フォルダ選択ダイアログを表示する

test35.gif
フォルダ選択ダイアログを表示するにはSHBrowseForFolderを利用する。これはダイアログを開いたときの初期選択フォルダ設定をコールバックで指定する必要があるなど少し使い方に癖のあるAPIだ。

#include "atlstr.h"
#include "shlobj.h"



//	初期フォルダ設定用のコールバック関数
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(HWND hWndParent,CAtlString* lpstrFolder,LPCTSTR pszIniFolder,bool bAvailNewFolder)
{
	bool			ret;
	TCHAR			lpszPath[MAX_PATH];
	LPMALLOC		lpMalloc;
	BROWSEINFO		sInfo;
	LPITEMIDLIST	lpidlRoot;
	LPITEMIDLIST	lpidlBrowse;
	CAtlString		strIniFolder;

	if(lpstrFolder == NULL)
		return	false;
	strIniFolder = pszIniFolder;

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

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

	lpidlRoot = NULL;
	::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);
	sInfo.hwndOwner		= hWndParent;

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

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

		ret = true;
	}

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

	lpMalloc->Release();

	return	ret;
}



void	Test(void)
{
	bool		ret;
	CAtlString	strMessage;

	ret = SelectFolderDlg(NULL,&strMessage,_T("c:\\"),false);

	if(ret)
		::MessageBox(NULL,strMessage,_T(""),MB_OK);
	else
		::MessageBox(NULL,_T("取得に失敗しました"),_T(""),MB_OK);
}

プロジェクトファイルをダウンロード


カテゴリー「ファイル・フォルダ」 のエントリー