フォルダ選択ダイアログの表示

解説

   フォルダ選択ダイアログを使用する。
   新しいフォルダの作成や初期状態で選択されるフォルダの指定も可能。


使用例

bool	SelectFolderDlg(CString* lpstrFolder,CString strIniFolder,bool bAvailNewFolder);

void	Test(void)
{
	CString	strFolder;

	SelectFolderDlg(&strFolder,"c:\\windows",false);

	AfxMessageBox(strFolder);
}


#ifndef	BIF_NEWDIALOGSTYLE
	#define		BIF_NEWDIALOGSTYLE		0x0040
#endif

#ifndef	BIF_USENEWUI
	#define		BIF_USENEWUI			0x0050
#endif

//	初期フォルダ設定用のコールバック関数
int		CALLBACK	_SHBrowseForFolderCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
	if(uMsg == BFFM_INITIALIZED)
		::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);

	return	0;
}


//
//	フォルダー選択ダイアログの表示
//
//		結果は"c:\windows\"のように末尾に必ず"\"が付加する
//
bool	SelectFolderDlg(CString* lpstrFolder,CString strIniFolder,bool bAvailNewFolder)
{
	bool			ret;
	char			lpszPath[MAX_PATH];
	LPMALLOC		lpMalloc;
	BROWSEINFO		sInfo;
	LPITEMIDLIST	lpidlRoot;
	LPITEMIDLIST	lpidlBrowse;

	if(lpstrFolder == NULL)
		return	false;

	if(::SHGetMalloc(&lpMalloc) != NOERROR)
		return	false;

	ret = false;
	*lpstrFolder = "";
	if(strIniFolder != "")
	{
		if(strIniFolder.Right(1) == "\\")
			strIniFolder = strIniFolder.Left(strIniFolder.GetLength() - 1);			//末尾の\\を除去
	}

	::SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &lpidlRoot);	//選択可能フォルダ名取得

	::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
	sInfo.pidlRoot		= lpidlRoot;
	sInfo.pszDisplayName = lpszPath;
	sInfo.lpszTitle		= _T("フォルダの選択");
	sInfo.ulFlags		= BIF_RETURNONLYFSDIRS;
	if(bAvailNewFolder == true)
		sInfo.ulFlags	|= BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_USENEWUI;
	sInfo.lpfn			= _SHBrowseForFolderCallbackProc;
	sInfo.lParam		= (LPARAM)strIniFolder.GetBuffer(0);

	lpidlBrowse = ::SHBrowseForFolder(&sInfo);			//フォルダ選択ダイアログ表示
	if(lpidlBrowse != NULL)
	{
		::SHGetPathFromIDList(lpidlBrowse,lpszPath);	//フォルダ名の取得
		*lpstrFolder = lpszPath;

		if(*lpstrFolder != "")
		{
			if(lpstrFolder->Right(1) != "\\")
				*lpstrFolder += "\\";			//末尾に\\が付加することを保証
		}

		ret = true;
	}

	if(lpidlBrowse != NULL)
		::CoTaskMemFree(lpidlBrowse);
	if(lpidlRoot != NULL)
		::CoTaskMemFree(lpidlRoot);

	lpMalloc->Release();

	return	ret;
}

カテゴリー「VC++ TIPS」 のエントリー