「フォルダの参照ダイアログ」とは以下に示すようなダイアログで、ユーザーにフォルダ名などを選択してもらいたいときに使います。

まず次のようにシェルのアロケータを取得します。これは後でPIDLを開放するために用意します。
// IMallocインタフェースの取得
SHGetMalloc(&g_pMalloc);
次に、SHBrowseForFolder(shlobj.h)関数でフォルダ参照ダイアログを表示します。
BROWSEINFO bi;
ITEMIDLIST *idl;
bi.hwndOwner =hwndDlg; //ダイアログボックスのオーナーウインドウのハンドル
bi.pidlRoot =NULL; //フォルダ検索開始点(nullならdesktop)
bi.pszDisplayName =szTmp; //選択フォルダの表示名を受け取るバッファのアドレス(サイズはMAX_PATH)
bi.lpszTitle ="保存先フォルダを選択してください";//ツリービューの上に表示する文字列
bi.ulFlags =BIF_RETURNONLYFSDIRS;//ツリービューに対するオプション
/*ulFlagsメンバの詳細
BIF_BROWSEFORCOMPUTER
コンピュータのみを返す。それ以外を選択すると、OKボタンが灰色表示される。
BIF_BROWSEFORPRINTER
プリンタのみを返す。以外を選択すると、OKボタンが灰色表示される。
BIF_DONTGOBELOWDOMAIN
ツリービューコントロールのドメインレベルの下にネットワークフォルダを加えない。
BIF_RETURNFSANCESTORS
ファイルシステムの祖先のみを返す。それ以外を選択すると、OKボタンが灰色表示される。
BIF_RETURNONLYFSDIRS
ファイルシステムのディレクトリのみを返す。それ以外を選択すると、OKボタンが灰色表示される。
BIF_STATUSTEXT
ダイアログボックスにステータス領域を含める。コールバック関数がダイアログボックスにメッセージを送ることによって、ステータステキストを設定できる。
*/
bi.lpfn =NULL; //イベントの発生時にダイアログボックスが呼び出す
//アプリケーション定義関数のアドレス。
bi.lParam =0; //ダイアログボックスがコールバック関数に渡す
//アプリケーション定義の値。
bi.iImage =0; //選択されたフォルダに関連するイメージを受け取る変数。
idl=SHBrowseForFolder(&bi);
SHGetPathFromIDList関数でPIDLをファイルシステムパスに変換します。
if(idl != NULL)
{
SHGetPathFromIDList(idl,szTmp);
PIDLは最後にシェルのアロケーターを使って開放します。
//PIDLを解放する
g_pMalloc->lpVtbl->Free(g_pMalloc,idl);
}
以下は使用例です。
/******************************************************************************
title : tips5 - フォルダ参照ダイアログを表示 for win95/NT4.0
compiler : VC++ 5.0
******************************************************************************/
#include<windows.h>
#include<shlobj.h>
int WINAPI WinMain(HINSTANCE hInstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
{
BROWSEINFO bi;
ITEMIDLIST *idl;
LPMALLOC g_pMalloc;
char szTmp[MAX_PATH];
// IMallocインタフェースの取得
SHGetMalloc(&g_pMalloc);
bi.hwndOwner =NULL;
bi.pidlRoot =NULL; //検索開始点(nullならdesktop)
bi.pszDisplayName =szTmp;
bi.lpszTitle ="フォルダを選択してください";
bi.ulFlags =BIF_RETURNONLYFSDIRS;
bi.lpfn =NULL;
bi.lParam =0;
bi.iImage =0;
//フォルダの参照ダイアログを表示
idl=SHBrowseForFolder(&bi);
if(idl != NULL)
{
if(SHGetPathFromIDList(idl,szTmp) != FALSE)
{
MessageBox(NULL,szTmp,"tips5",MB_OK);
}
//PIDLを解放する
g_pMalloc->lpVtbl->Free(g_pMalloc,idl);
}
return 0;
}