フォルダ選択ダイアログの使用方法

普通のファイルを開くダイアログではなくフォルダ選択専用のダイアログの 使い方です。
本当に便利なものが用意されているものです。

今回の主役のAPIは、
  • SHGetMalloc : Shellのアロケータを取得
  • SHBrowseForFolder : フォルダの参照ダイアログ
  • SHGetPathFromIDList : LPITEMIDLIST型からパスへ変換する
です。
さっそくサンプルです。
#include <stdio.h>
#include <windows.h>

void SearchFolder();
int CALLBACK SearchFolderCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData);

int main(int argc,char *argv[])
{
SearchFolder();
return 0;
}

int CALLBACK SearchFolderCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData)
{
switch (uMsg){
case BFFM_INITIALIZED:
//選択済みフォルダを指定する
SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,pData);
break;
default:
break;
}

return 0;
}

void SearchFolder()
{
BROWSEINFO bi;
TCHAR path[MAX_PATH+1];
TCHAR dir[MAX_PATH+1];
LPITEMIDLIST pidl;
LPMALLOC pMalloc;

//Shellの標準のアロケータを取得
if(SUCCEEDED(SHGetMalloc(&pMalloc))){
ZeroMemory(&bi,sizeof(bi));
//オーナーウィンドウハンドルを設定
bi.hwndOwner = NULL;//Handle;
//デスクトップをルートにする
bi.pidlRoot = 0;
//選択したフォルダ名が格納される配列の指定
bi.pszDisplayName = dir;
//ダイアログのタイトル
bi.lpszTitle = "フォルダを選んでください";
//各種フラグ
bi.ulFlags = BIF_RETURNONLYFSDIRS;
//コールバック関数の指定
bi.lpfn = SearchFolderCallbackProc;
//ダイアログを開いた時に選択済みにするフォルダ(NULLの指定OK)
bi.lParam = (LPARAM)"C:\\Documents and Settings\\Administrator\\デスクトップ";

//フォルダの参照ダイアログボックスの表示
pidl = SHBrowseForFolder(&bi);
if(pidl){
//PIDLをファイルシステムのパスに変換
if(SHGetPathFromIDList(pidl,path)){
//ここにフォルダが選択された時の処理を記述してください。
printf("選択パス:%s\n",path);
printf("選択フォルダ名:%s\n",dir);
}
pMalloc->Free(pidl);
}
pMalloc->Release();
}

return;
}

今回は、コンソールアプリなので、bi.hwndOwner=NULLとしています。
また、結果を標準出力へ出力しています。