フォルダ選択ダイアログって結構使い方に癖があって、使うのが面倒くさいですよね?
何でまたこんな仕様になってしまったのか不思議です。まあ、それが拡張性を持たせたってこと何でしょうけど。 使いにくいので、ラッパクラスを作ってみました。 使い方は、MFCの CFileDialog クラスを参考に、「見た感じダイアログっぽい」ように作ってあります。 ソースはここにありますので、ご自由にご利用ください。 ※ただし、このソースを使用したことによって発生したいかなる不都合・不利益等につきまして、作者は一切責任を負わないものとしてください。 クラス名:CBrowseDialog ファイル:browsedialog.h 環境:MFC/Win32 // // フォルダ選択ダイアログラップクラス // CBrowseDialog // // SHBrowseForFolder()をラップしたクラスです。 // // // 作者:あいそび // 日付:2004/02/19 // // 使用法: // // CBrowseDialog dlg("c:\\windows\\", "選択してね"); // if(dlg.DoModal() == IDOK) // { // CString strPath = dlg.GetPathName(); // 選択パスを取得 // } // // // v5.0 (Shell32.dll:Windows2000以降)について // v5.0の印が付いているものは、ビルド時に新しいPlatformSDKのヘッダファイルが必要です。 // フラグなどは、数値で代用することができますが、クライアント側に新しいバージョンの // Shell32.dll が入っている必要があります。 // 無い場合は期待道理に動作しません(多分)。 // // #pragma once const CString INVALID_CHARS_FOR_PATH = "*?\"<>|"; const CString INVALID_CHARS_FOR_FNAME = "\\/:" + INVALID_CHARS_FOR_PATH; #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize #endif // Caller needs to call OleInitialize() before using this API #ifndef BIF_USENEWUI #define BIF_USENEWUI (BIF_NEWDIALOGSTYLE | BIF_EDITBOX) #endif class CBrowseDialog { public: CBrowseDialog(const CString strDefPath = "" , const CString strMessage = "フォルダを選択してください" , CWnd* pWnd = AfxGetMainWnd()) { if(pWnd) { m_hWnd = pWnd->GetSafeHwnd(); } m_strDefPath = strDefPath; m_strMessage = strMessage; m_pIDL = NULL; m_uiFlags = BIF_RETURNONLYFSDIRS; m_bRequireExisting = TRUE; } virtual ~CBrowseDialog(){} // ツリーのルートとするITEMIDLISTをセット void SetRootIDL(ITEMIDLIST* pIDL){ m_pIDL = pIDL; } // フラグをセット (*1 と *2 は判別できなくなるので排他とします) // BIF_RETURNONLYFSDIRS - *1 フォルダのみ選択可能 // BIF_BROWSEINCLUDEFILES - *1 ファイルも表示 // BIF_BROWSEFORCOMPUTER - *2 コンピュータを選択 // BIF_BROWSEFORPRINTER - *2 プリンタを選択 // BIF_DONTGOBELOWDOMAIN - ネットワークドメイン以下を表示しない // BIF_USENEWUI - *1 新しいUIを使用(v5.0) =(0x0040 | 0x0010) void SetFlags(UINT uiFlags) { ASSERT(!(uiFlags & (BIF_RETURNONLYFSDIRS | BIF_BROWSEINCLUDEFILES | BIF_USENEWUI) && uiFlags & (BIF_BROWSEFORCOMPUTER | BIF_BROWSEFORPRINTER))); // *1 と *2 は排他とします(本当は排他ではないですが、ここではそうします)。 // コンピュータ名などを選んだのか、ディレクトリを選んだのか判別が難しいため。 // BIF_USENEWUI を指定すると、コンピュータ・プリンタだけの選択がうまくできない。 m_uiFlags = uiFlags; } // 存在しないファイル名を許可するかどうか設定 void SetRequireExisting(BOOL bRequire) { m_bRequireExisting = bRequire; } // 結果のパスを取得 const CString& GetPathName(){ return m_strPathName; } // ダイアログ表示 int DoModal() { BROWSEINFO bInfo; TCHAR* szDisplayName = m_strPathName.GetBuffer(MAX_PATH); // BROWSEINFO構造体に値を設定 bInfo.hwndOwner = m_hWnd; // ダイアログの親ウインドウのハンドル bInfo.pidlRoot = m_pIDL; // ルートフォルダを示す // ITEMIDLISTのポインタ // (NULLの場合デスクトップフォルダが使われます) bInfo.pszDisplayName = szDisplayName; // 選択されたフォルダ名を // 受け取るバッファのポインタ bInfo.lpszTitle = m_strMessage; // ツリービューの上部に表示される文字列 bInfo.ulFlags = m_uiFlags | BIF_VALIDATE; // 表示されるフォルダの種類を // 示すフラグ bInfo.lpfn = BrowseCallbackProc; // BrowseCallbackProc関数のポインタ bInfo.lParam = (LPARAM)this; // コールバック関数に渡す値 // フォルダ選択ダイアログを表示 HRESULT hr = ::CoInitialize(NULL); if(SUCCEEDED(hr)) { LPITEMIDLIST pIDList = ::SHBrowseForFolder(&bInfo); int nRet = IDOK; if(pIDList == NULL) { nRet = IDCANCEL; // キャンセルの場合は空の文字列を返します szDisplayName[0] = '\0'; } if(nRet == IDOK) { if(!(m_uiFlags & (BIF_BROWSEFORCOMPUTER | BIF_BROWSEFORPRINTER))) { // ItemIDListをパス名に変換します if(!::SHGetPathFromIDList(pIDList, szDisplayName)) { // エラー処理 nRet = IDCANCEL; szDisplayName[0] = '\0'; } } // コンピュータ・プリンタ名の場合は、変換の必要なし } m_strPathName.ReleaseBuffer(); // 最後にpIDListのポイントしているメモリを開放します ::CoTaskMemFree(pIDList); ::CoUninitialize(); return m_strPathName.IsEmpty() ? IDCANCEL : nRet; } else { AfxMessageBox("COMの初期化に失敗しました"); return IDCANCEL; } } protected: // コールバック関数 static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg , LPARAM lParam, LPARAM lpData) { return ((CBrowseDialog*)lpData)->BrowseCallbackImp(hWnd, uMsg, lParam); } // コールバック関数の実装 int BrowseCallbackImp(HWND hWnd, UINT uMsg, LPARAM lParam) { if(uMsg == BFFM_INITIALIZED) { if(!m_strDefPath.IsEmpty()) ::SendMessage(hWnd, BFFM_SETSELECTION, TRUE , (LPARAM)(LPCTSTR)m_strDefPath); } else if(uMsg == BFFM_SELCHANGED) { ; } else if(uMsg == BFFM_VALIDATEFAILED) { CString strName((char*)lParam); if(m_bRequireExisting) { AfxMessageBox("既存の項目を選択してください"); return TRUE; } if(strName.FindOneOf(INVALID_CHARS_FOR_FNAME) != -1) { AfxMessageBox("次の文字は名前として使用できません:\n\n" + INVALID_CHARS_FOR_FNAME); return TRUE; } } return 0; } // 非公開メンバ HWND m_hWnd; CString m_strMessage; CString m_strDefPath; ITEMIDLIST* m_pIDL; UINT m_uiFlags; CString m_strPathName; BOOL m_bRequireExisting; }; 使い方:こんな感じです。 // 初期表示フォルダ・メッセージ文字列を指定して構築 CBrowseDialog dlg("c:\\windows\\", "選択してね"); // フラグを設定 dlg.SetFlags(BIF_RETURNONLYFSDIRS // パスを取得 | BIF_BROWSEINCLUDEFILES // ファイルもツリーに含める | BIF_USENEWUI); // Win2K以降の新しいUIを使用 if(dlg.DoModal() == IDOK) { CString strPath = dlg.GetPathName(); // パス取得 AfxMessageBox(strPath); } フォルダパスだけでなく、ファイルのパスも取得できますよ。
by isoq
| 2004-02-19 23:05
| C/C++/Win32
|
PR
検索
最新の記事
カテゴリ
全体 開発日記 コンピュータ C/C++/Win32 Ubuntu / Linux Web データベース 3Dグラフィックス スクリプティング 書籍 - 技術系 フリーウェア モバイル 日記 子供のこと 旅行日記 観察日記 グルメ 写真館 天体観測 ショッピング アートワーク ヘルスケア 携帯からの投稿 誤変換検索 趣味 Windows 未分類 タグ
海外
Windows 7
旅行
C++
ドイツ
Windows
Aspire 1410
ボストン
MFC
OpenGL
出張
REGZA
天体望遠鏡
お買い得
CUDA
42Z9000
GPGPU
グルメ
XPモード
NaiNai
最新のトラックバック
以前の記事
2022年 03月 2020年 05月 2020年 04月 2020年 03月 2018年 05月 2016年 02月 2015年 04月 2015年 03月 2013年 10月 2012年 01月 2011年 12月 2011年 11月 2011年 10月 2011年 09月 2011年 08月 2011年 07月 2011年 06月 2011年 05月 2011年 03月 2011年 02月 2011年 01月 2010年 11月 2010年 10月 2010年 09月 2010年 08月 2010年 07月 2010年 06月 2010年 05月 2010年 04月 2010年 03月 2010年 02月 2010年 01月 2009年 12月 2009年 11月 2009年 10月 2009年 09月 2009年 08月 2009年 07月 2009年 06月 2009年 05月 2009年 04月 2009年 03月 2009年 02月 2009年 01月 2008年 12月 2008年 11月 2008年 10月 2008年 09月 2008年 08月 2008年 07月 2008年 06月 2008年 05月 2008年 04月 2008年 03月 2008年 02月 2008年 01月 2007年 12月 2007年 11月 2007年 10月 2007年 09月 2007年 08月 2007年 07月 2007年 06月 2007年 05月 2007年 04月 2007年 03月 2007年 02月 2007年 01月 2006年 12月 2006年 11月 2006年 10月 2006年 09月 2006年 08月 2006年 07月 2006年 06月 2006年 05月 2006年 04月 2006年 03月 2006年 02月 2006年 01月 2005年 12月 2005年 11月 2005年 10月 2005年 09月 2005年 08月 2005年 07月 2005年 06月 2005年 05月 2005年 04月 2005年 03月 2005年 02月 2005年 01月 2004年 12月 2004年 11月 2004年 10月 2004年 09月 2004年 08月 2004年 07月 2004年 06月 2004年 05月 2004年 04月 2004年 03月 2004年 02月 2001年 01月 その他のジャンル
記事ランキング
ブログジャンル
画像一覧
フォロー中のブログ
外部リンク
|
ファン申請 |
||