1

------------------------- 업데이트 5th ---------- ---------------------가상 폴더는 Windows 7의 CFileDialog에서 보이지 않습니다.

  if (fIsFolder) 
      { 
       dwAttribs |= SFGAO_FOLDER; 
      } 
      else 
      { 
       dwAttribs |= SFGAO_SYSTEM; 

       dwAttribs |= SFGAO_FILESYSTEM; 
      } 

      if (nLevel < g_nMaxLevel) 
      { 
       dwAttribs |= SFGAO_HASSUBFOLDER; 

       dwAttribs |= SFGAO_FILESYSANCESTOR; 
      } 

지금이 하나의 응용 프로그램 A, 유래 이미지 업로드 파일 대화 상자에서 정기적 폴더 탐색기에서 정상적으로 작동합니다.

---------------------------------------------- ------- 업데이트 4th ----------------------------------------- ------------------ dwAttribs |= SFGAO_SYSTEM;을 추가 한 후 적어도 응용 프로그램 A의 경우 파일 대화 상자에서 예상대로 작동합니다. 그러나 폴더는 여전히 일반 폴더 대화 상자 또는 CWFileDialog에 대해 클릭 할 수 없습니다.

  if (fIsFolder) 
      { 
       dwAttribs |= SFGAO_FOLDER; 

       dwAttribs |= SFGAO_FILESYSTEM; 

       dwAttribs |= SFGAO_FILESYSANCESTOR; 
      } 
      else 
      { 
       dwAttribs |= SFGAO_SYSTEM;// this line of code works better 

       dwAttribs |= SFGAO_FILESYSTEM; 
      } 

----------------------------------- 업데이트 셋째 ------ ----------------------------------- 이것은 가상 폴더의 ISHellFolder에있는 코드입니다.

dwAttribs |= SFGAO_FILESYSTEM;을 추가하기 위해 다음 코드를 편집 한 후에 폴더보기에서 폴더를 두 번 클릭하면 해당 폴더를 탐색 할 수 없습니다. 트리보기에서 왼쪽 버튼을 클릭하면 열 수 있습니다.

HRESULT CFolderViewImplFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, ULONG *rgfInOut) 
{ 
// If SFGAO_FILESYSTEM is returned, GetDisplayNameOf(SHGDN_FORPARSING) on that item MUST 
// return a filesystem path. 
HRESULT hr = E_INVALIDARG; 

DWORD dwAttribs = 0; 

dwAttribs |= SFGAO_FILESYSTEM; 

if (1 == cidl) 
{ 
    int nLevel = 0; 
    hr = _GetLevel(apidl[0], &nLevel); 
    if (SUCCEEDED(hr)) 
    { 
     BOOL fIsFolder = FALSE; 
     hr = _GetFolderness(apidl[0], &fIsFolder); 
     if (SUCCEEDED(hr)) 
     { 

      if (fIsFolder) 
      { 
       dwAttribs |= SFGAO_FOLDER; 
      } 
      if (nLevel < g_nMaxLevel) 
      { 
       dwAttribs |= SFGAO_HASSUBFOLDER; 
      } 

     } 
    } 
} 

*rgfInOut &= dwAttribs; 

return hr; 
}` 

또는

DWORD dwAttribs = 0; 

if (1 == cidl) 
{ 
    int nLevel = 0; 
    hr = _GetLevel(apidl[0], &nLevel); 
    if (SUCCEEDED(hr)) 
    { 
     BOOL fIsFolder = FALSE; 
     hr = _GetFolderness(apidl[0], &fIsFolder); 
     if (SUCCEEDED(hr)) 
     { 

      if (fIsFolder) 
      { 
       dwAttribs |= SFGAO_FOLDER; 

       dwAttribs |= SFGAO_FILESYSTEM; 

       dwAttribs |= SFGAO_FILESYSANCESTOR; 
      } 
      else 
      { 
       dwAttribs |= SFGAO_SYSTEM; 
      } 

      if (nLevel < g_nMaxLevel) 
      { 
       dwAttribs |= SFGAO_HASSUBFOLDER; 
      } 
     } 
    } 
} 

*rgfInOut &= dwAttribs; 

다른 코드

update 2nd과 동일합니다. 이 코드를 편집 한 후에 이상한 일들은 일반적으로 CFileDialog (포장하지 않고 m_bPickNonFileSysFoldersMode을 설정하지 않음)을 사용하는 응용 프로그램 A가 예상대로 모든 가상 폴더를 정상적으로 표시 할 수 있습니다. 그러나 하나를 포함하여 다른 모든 응용 프로그램 (true로 m_bPickNonFileSysFoldersMode 가상 폴더를 볼 수 없습니다 아직 설정 CWFileDilao 사용합니다.

--------------------- ------------------ 업데이트 2 -------------------------

I 좋아

class CWFileDlg : public CFileDialog 
{ 
public: 
CWFileDlg(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs 
    LPCTSTR lpszDefExt = NULL, 
    LPCTSTR lpszFileName = NULL, 
    DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
    LPCTSTR lpszFilter = NULL, 
    CWnd* pParentWnd = NULL, 
    DWORD dwSize = 0, 
    BOOL bVistaStyle = TRUE); 

~CWFileDlg(); 
}; 

CWFileDlg::CWFileDlg(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs 
        LPCTSTR lpszDefExt, 
        LPCTSTR lpszFileName, 
        DWORD dwFlags, 
        LPCTSTR lpszFilter, 
        CWnd* pParentWnd, 
        DWORD dwSize, 
        BOOL bVistaStyle) : CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle) 
{ 
    m_bPickNonFileSysFoldersMode = TRUE; 
} 

CWFileDlg::~CWFileDlg() 
{ 

} 

그럼 내가 전화 :

CWFileDlg dlg(TRUE, NULL, 0, OFN_SHAREAWARE | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, L"all(*.*)|*.*||", this); 

BOOL IsPickNonFileSysFoldersMode = dlg.IsPickNonFileSysFoldersMode(); 
//the value it gets is 1, which is TRUE 

INT_PTR result = dlg.DoModal(); 
CFileDialog에에서 파생되는 간단한 클래스를 코딩하지만 팝업 대화 상자에서 가상 폴더가 보이지 않습니다. 그것에 대한 트리보기도 보이지 않습니다. ------------------------------------------ 업데이트 ------ ----------------------

protected: 

BOOL m_bVistaStyle; 
BOOL m_bPickFoldersMode; 
BOOL m_bPickNonFileSysFoldersMode; 
DWORD m_dwCookie; 
void* m_pIFileDialog; 
void* m_pIFileDialogCustomize; 

m_bPickNonFileSysFoldersMode은 공개되지 않습니다. 어떻게하면 TRUE로 설정할 수 있습니까? 마이크로 소프트 윈도우 샘플 코드를 사용하여


Error 1 error C2248: 'CFileDialog::m_bPickNonFileSysFoldersMode' : cannot access protected member declared in class 'CFileDialog' c:\users\liyuan.liu\documents\dp-dll\testvirtualfolder\browser2\browser2\browser2dlg.cpp 166 1 browser2 

, 나는 쉘 네임 스페이스 확장을 사용하여 윈도우 7의 가상 폴더를 설치했습니다. 다음 스크린 샷을 열려면 일반 폴더 브라우저를 사용하고 있습니다 : enter image description here

다음

내가 파일 대화 상자를 만들 수 있습니다 프로젝트를 썼다가 :

CFileDialog dlg(TRUE, NULL, 0, OFN_SHAREAWARE | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, L"all(*.*)|*.*||", this); 
INT_PTR result = dlg.DoModal(); 

그러나 파일 브라우저에서, 가상 폴더가 보이지 않는 :

enter image description here

그러나! 스크린 샷을 StackOverflow (크롬을 사용하는 웹 브라우저)에 업로드하려고 할 때 파일을 선택하는 데 사용되는 파일 대화 상자에서 가상 폴더의 트리보기 (트리보기 만)를 표시 할 수 있습니다.

Google 검색에서 CFileDialog는 실제로 시스템에 없기 때문에 가상 폴더를 표시 할 수 없습니다. 그 해결책은 무엇입니까? 나는 또한

bi.pidlRoot = pidlVirtual; 
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_BROWSEINCLUDEFILES | BIF_BROWSEFILEJUNCTIONS; 
LPITEMIDLIST pidl = SHBrowseForFolder(&bi); 

으로 시도 또한 작동하지 않습니다.

+0

32 비트 및 64 비트 NSE를 모두 만들고 등록 했습니까? –

+0

'CFileDialog'는 Visual Studio 2008 이상에서 기본적으로 IFileDialog를 래핑합니다. 'IFileDialog'는 가상 폴더와 SNE를 확실히 지원합니다 (이것은 이전의'Get (Open | Save) FileName()'API에 비해 큰 발전입니다). 사용중인 Visual Studio의 버전은 무엇입니까? 어쩌면 버전의 'CFileDialog'가 이전 파일 시스템 전용 API를 사용하고있을 수도 있습니다. IFileDialog를 직접 사용해 보셨나요? –

답변

1

파일 대화 상자에 표시되는 내용은 파일을 여는 앱의 기능입니다. Vista에서 시작하여 사용되는 IFileDialog 인터페이스이며, IFileDialog::SetOptions method을 통해 일련의 옵션을 정의합니다.

FOS_FORCEFILESYSTEM 플래그는 반환 된 항목이 파일 시스템 항목 (SFGAO_FILESYSTEM)이고 확장명을 작성한 방법에 따라 달라지는 것을 보장합니다. SFGAO_FILESYSTEM은 종을 울려 야합니다. IShellFolder::GetAttributesOf method이 반환 할 수있는 플래그 중 하나입니다. 당신이하는 일이 실제로 가상 일 경우 (즉,이 플래그를 반환하지 않으면) IFileDialog가 이와 같이 구성 될 때 표시되지 않습니다.

다른 앱 (메모장, 단어, 엑셀, 브라우저 등)을 사용하여 확장 프로그램을 테스트하면 가끔씩 보게되는 경우가 있습니다. MFC의 코드 (dlgfile.cpp)으로로 spelunking

, 당신은이를 발견 할 것이다 :

// We only expect and handle file system paths (for compatibility with GetOpenFileName functionality), so set the 
    // "force file system" flag which enables GetOpenFileName-like download behavior for non file system paths, unless 
    // the m_bPickNonFileSysFoldersMode is set to allow picking non-file system folders (like libraries in Windows 7). 
    dwFlags |= FOS_FORCEFILESYSTEM; 
    if (m_bPickNonFileSysFoldersMode) 
    { 
     dwFlags &= ~FOS_FORCEFILESYSTEM; 
    } 

그래서, 당신은 CFileDialog에 내선을 보여 true로 m_bPickNonFileSysFoldersMode를 설정해야합니다.

그러나이 플래그를 사용하지 않는 다른 응용 프로그램은 수정하지 않습니다 ...

+0

CFileDialog에 대해 어떻게 m_bPickNonFileSysFoldersMode를 TRUE로 설정할 수 있습니까? 이 변수는 CFileDialog 밖으로 액세스 할 수없는 것 같습니다. CFileDialog의 정의를 확인할 때 CFileDialog 클래스입니다. public CCommonDialog – beasone

+0

멤버가 보호되어 있으므로 CFileDialog에서 파생되고 생성자에서 값을 TRUE로 설정해야합니다. –

+0

그것을 감싸고 플래그를 TRUE로 설정했지만 여전히 보이지 않습니다. 내 업데이 트를 참조하십시오. – beasone