// フォルダ選択ダイアログクラス // (C)2002,2003 Yutaka Wada, AirparkLab /* 使い方 CFolderDialog dlg; if( dlg.DoModal( this->GetSafeHwnd() ) == IDOK ){ CString path = dlg.GetPathName(); } などとしてフォルダを選択するダイアログを開き、パスを取得する。 パブリックメンバ関数は以下の通り。 CFolderDialog() メッセージを指定しない場合のコンストラクタ CFolderDialog( LPCTSTR szMessage, LPCTSTR szRoot = NULL, LPCTSTR szSelect = NULL ) メッセージ、ROOTフォルダおよび初期フォルダを 指定する場合のコンストラクタ int DoModal( HWND hWnd = NULL ) ダイアログを開く 引数は親ウインドウハンドル 戻値は IDOK か IDCANCEL CString GetPathName() 選択されたフォルダパスを取得する ~CFolderDialog() デストラクタ */ #ifndef __FOLDER_DIALOG_H__ #define __FOLDER_DIALOG_H__ #include #include #include // シェル関数によるフォルダダイアログ表示SHBrowseForFolder()用のコールバック関数 static int AFXAPI BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData ) { // 開始時にフォルダを選択 if( uMsg == BFFM_INITIALIZED ){ ::SendMessage( hwnd, BFFM_SETSELECTION, TRUE, lpData ); } // フォルダ選択時にフルパスを表示 else { char chText[MAX_PATH]; if( ::SHGetPathFromIDList( (LPITEMIDLIST)lParam, chText ) ){ ::SendMessage( hwnd, BFFM_SETSTATUSTEXT, TRUE, (LPARAM)chText ); } } return( 0 ); } // フォルダダイアログのラッパークラス class CFolderDialog { char m_szMessage[MAX_PATH]; // メッセージ char m_szRoot[MAX_PATH]; // ルートフォルダ char m_szSelect[MAX_PATH]; // 初期選択フォルダ char m_szPath[MAX_PATH]; // 選択フォルダ public: // コンストラクタ CFolderDialog() { strcpy( m_szMessage, "フォルダを選択してください" ); m_szRoot[0] = '\0'; m_szSelect[0] = '\0'; m_szPath[0] = '\0'; } CFolderDialog( LPCTSTR szMessage, LPCTSTR szRoot = NULL, LPCTSTR szSelect = NULL ) { strcpy( m_szMessage, szMessage ); if( szRoot != NULL ) strcpy( m_szRoot, szRoot ); else m_szRoot[0] = '\0'; int len = strlen( m_szRoot ); if( len > 3 && m_szRoot[len-1] == '\\' ) m_szRoot[len-1] = '\0'; if( szSelect != NULL ) strcpy( m_szSelect, szSelect ); else m_szSelect[0] = '\0'; len = strlen( m_szSelect ); if( len > 3 && m_szSelect[len-1] == '\\' ) m_szSelect[len-1] = '\0'; m_szPath[0] = '\0'; } // デストラクタ ~CFolderDialog() { } // ダイアログを開く int DoModal( HWND hWnd = NULL ) { int ret; LPITEMIDLIST pidl_root = GetItemIDList( m_szRoot ); LPMALLOC pMalloc; if( SHGetMalloc( &pMalloc ) == NOERROR ){ BROWSEINFO bi; ZeroMemory( &bi, sizeof(BROWSEINFO) ); bi.hwndOwner = hWnd; bi.pidlRoot = pidl_root; bi.pszDisplayName = m_szPath; bi.lpszTitle = m_szMessage; bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)m_szSelect; ITEMIDLIST *pidl; pidl = SHBrowseForFolder( &bi ); SHGetPathFromIDList( pidl, m_szPath ); if( pidl ) ret = IDOK; else ret = IDCANCEL; if( pidl ) pMalloc->Free( pidl ); if( pidl_root ) pMalloc->Free( pidl_root ); pMalloc->Release(); } else ret = IDABORT; return( ret ); } // パスの取得 CString GetPathName() { CString ret = m_szPath; return( ret ); } // ITEMIDLIST の取得 LPITEMIDLIST GetItemIDList( LPCTSTR szPath ) { if( szPath == NULL ) return( NULL ); else if( szPath[0] == '\0' ) return( NULL ); else { LPSHELLFOLDER pDesktopFolder; if( ::SHGetDesktopFolder( &pDesktopFolder ) != NOERROR ) return( NULL ); unsigned short ochPath[MAX_PATH]; ::MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, m_szRoot, -1, ochPath, MAX_PATH ); ULONG chEaten; ULONG dwAttributes; LPITEMIDLIST pidl; HRESULT hRes = pDesktopFolder->ParseDisplayName( NULL, NULL, ochPath, &chEaten, &pidl, &dwAttributes ); if( hRes != NOERROR ) pidl = NULL; pDesktopFolder->Release(); return( pidl ); } } }; #endif