diff --git a/sakura_core/dlg/CDlgExec.cpp b/sakura_core/dlg/CDlgExec.cpp index ecf8be4016..b17c1c491c 100644 --- a/sakura_core/dlg/CDlgExec.cpp +++ b/sakura_core/dlg/CDlgExec.cpp @@ -259,7 +259,7 @@ BOOL CDlgExec::OnBnClicked( int wID ) case IDC_BUTTON_REFERENCE2: { - if( SelectDir( GetHwnd(), LS(STR_DLGEXEC_SELECT_CURDIR), &m_szCurDir[0], &m_szCurDir[0] ) ){ + if( SelectDir( GetHwnd(), LS(STR_DLGEXEC_SELECT_CURDIR), &m_szCurDir[0], &m_szCurDir[0], m_szCurDir.GetBufferCount() ) ){ ::DlgItem_SetText( GetHwnd(), IDC_COMBO_CUR_DIR, &m_szCurDir[0] ); } } diff --git a/sakura_core/dlg/CDlgGrep.cpp b/sakura_core/dlg/CDlgGrep.cpp index f79c088dd6..dddf5f5478 100644 --- a/sakura_core/dlg/CDlgGrep.cpp +++ b/sakura_core/dlg/CDlgGrep.cpp @@ -509,7 +509,7 @@ BOOL CDlgGrep::OnBnClicked( int wID ) if( szFolder[0] == L'\0' ){ ::GetCurrentDirectory( nMaxPath, szFolder ); } - if( SelectDir( GetHwnd(), LS(STR_DLGGREP1), szFolder, szFolder ) ){ + if( SelectDir( GetHwnd(), LS(STR_DLGGREP1), szFolder, szFolder, _countof(szFolder) ) ){ SetGrepFolder( GetItemHwnd(IDC_COMBO_FOLDER), szFolder ); } } diff --git a/sakura_core/dlg/CDlgPluginOption.cpp b/sakura_core/dlg/CDlgPluginOption.cpp index 11e2c79219..42418c4f04 100644 --- a/sakura_core/dlg/CDlgPluginOption.cpp +++ b/sakura_core/dlg/CDlgPluginOption.cpp @@ -730,7 +730,7 @@ void CDlgPluginOption::SelectDirectory( int iLine ) WCHAR sTitle[MAX_LENGTH_VALUE+10]; auto_sprintf( sTitle, LS(STR_DLGPLUGINOPT_SELECT), buf); - if (SelectDir( GetHwnd(), (const WCHAR*)sTitle /*L"ディレクトリの選択"*/, szDir, szDir )) { + if (SelectDir( GetHwnd(), (const WCHAR*)sTitle /*L"ディレクトリの選択"*/, szDir, szDir, _countof(szDir) )) { // 末尾に\マークを追加する. AddLastChar( szDir, _countof(szDir), L'\\' ); ::DlgItem_SetText( GetHwnd(), IDC_EDIT_PLUGIN_OPTION_DIR, szDir ); diff --git a/sakura_core/dlg/CDlgTagsMake.cpp b/sakura_core/dlg/CDlgTagsMake.cpp index 06a7e62d81..40fe075b1e 100644 --- a/sakura_core/dlg/CDlgTagsMake.cpp +++ b/sakura_core/dlg/CDlgTagsMake.cpp @@ -125,7 +125,7 @@ void CDlgTagsMake::SelectFolder( HWND hwndDlg ) /* フォルダ */ ::DlgItem_GetText( hwndDlg, IDC_EDIT_TAG_MAKE_FOLDER, szPath, _MAX_PATH ); - if( SelectDir( hwndDlg, LS(STR_DLGTAGMAK_SELECTDIR), szPath, szPath ) ) + if( SelectDir( hwndDlg, LS(STR_DLGTAGMAK_SELECTDIR), szPath, szPath, _countof(szPath) ) ) { //末尾に\\マークを追加する. ::PathAddBackslashW( szPath ); diff --git a/sakura_core/macro/CMacro.cpp b/sakura_core/macro/CMacro.cpp index 3e822a1f35..bb47eaf95d 100644 --- a/sakura_core/macro/CMacro.cpp +++ b/sakura_core/macro/CMacro.cpp @@ -1939,7 +1939,7 @@ bool CMacro::HandleFunction(CEditView *View, EFunctionCode ID, const VARIANT *Ar } WCHAR szPath[ _MAX_PATH ]; - int nRet = SelectDir( View->GetHwnd(), sMessage.c_str(), sDefault.c_str(), szPath ); + int nRet = SelectDir( View->GetHwnd(), sMessage.c_str(), sDefault.c_str(), szPath, _countof(szPath) ); if( nRet == IDOK ){ SysString S( szPath, wcslen(szPath) ); Wrap( &Result )->Receive( S ); diff --git a/sakura_core/outline/CDlgFileTree.cpp b/sakura_core/outline/CDlgFileTree.cpp index a72a138492..7b0a18c5eb 100644 --- a/sakura_core/outline/CDlgFileTree.cpp +++ b/sakura_core/outline/CDlgFileTree.cpp @@ -537,7 +537,7 @@ BOOL CDlgFileTree::OnBnClicked( int wID ) // RADIO_GREP == folder WCHAR szDir[MAX_PATH]; DlgItem_GetText(GetHwnd(), IDC_EDIT_PATH, szDir, _countof(szDir) ); - if( SelectDir(hwndDlg, LS(STR_DLGGREP1), szDir, szDir) ){ + if( SelectDir(hwndDlg, LS(STR_DLGGREP1), szDir, szDir, _countof(szDir) ) ){ DlgItem_SetText(GetHwnd(), IDC_EDIT_PATH, szDir ); } }else{ diff --git a/sakura_core/prop/CPropComBackup.cpp b/sakura_core/prop/CPropComBackup.cpp index b2a33d2d5d..09529c121c 100644 --- a/sakura_core/prop/CPropComBackup.cpp +++ b/sakura_core/prop/CPropComBackup.cpp @@ -174,7 +174,7 @@ INT_PTR CPropBackup::DispatchEvent( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR WCHAR szFolder[_MAX_PATH]; ::DlgItem_GetText( hwndDlg, IDC_EDIT_BACKUPFOLDER, szFolder, _countof( szFolder )); - if( SelectDir( hwndDlg, LS(STR_PROPCOMBK_SEL_FOLDER), szFolder, szFolder ) ){ + if( SelectDir( hwndDlg, LS(STR_PROPCOMBK_SEL_FOLDER), szFolder, szFolder, _countof( szFolder ) ) ){ wcscpy( m_Common.m_sBackup.m_szBackUpFolder, szFolder ); ::DlgItem_SetText( hwndDlg, IDC_EDIT_BACKUPFOLDER, m_Common.m_sBackup.m_szBackUpFolder ); } diff --git a/sakura_core/prop/CPropComEdit.cpp b/sakura_core/prop/CPropComEdit.cpp index c70bea0df4..4693714f55 100644 --- a/sakura_core/prop/CPropComEdit.cpp +++ b/sakura_core/prop/CPropComEdit.cpp @@ -118,7 +118,7 @@ INT_PTR CPropEdit::DispatchEvent( WCHAR szPath[_MAX_PATH]; ::DlgItem_GetText( hwndDlg, IDC_EDIT_FILEOPENDIR, szMetaPath, _countof(szMetaPath) ); CFileNameManager::ExpandMetaToFolder( szMetaPath, szPath, _countof(szPath) ); - if( SelectDir( hwndDlg, LS(STR_PROPEDIT_SELECT_DIR), szPath, szPath ) ){ + if( SelectDir( hwndDlg, LS(STR_PROPEDIT_SELECT_DIR), szPath, szPath, _countof(szPath) ) ){ CNativeW cmem(szPath); cmem.Replace(L"%", L"%%"); ::DlgItem_SetText( hwndDlg, IDC_EDIT_FILEOPENDIR, cmem.GetStringPtr() ); diff --git a/sakura_core/prop/CPropComHelper.cpp b/sakura_core/prop/CPropComHelper.cpp index 9eed90c925..4795daeb79 100644 --- a/sakura_core/prop/CPropComHelper.cpp +++ b/sakura_core/prop/CPropComHelper.cpp @@ -168,7 +168,7 @@ INT_PTR CPropHelper::DispatchEvent( }else{ wcscpy( szPath, m_Common.m_sHelper.m_szMigemoDict ); } - if( SelectDir( hwndDlg, LS(STR_PROPCOMHELP_MIGEMODIR), szPath, szPath ) ){ + if( SelectDir( hwndDlg, LS(STR_PROPCOMHELP_MIGEMODIR), szPath, szPath, _countof(szPath) ) ){ wcscpy( m_Common.m_sHelper.m_szMigemoDict, GetRelPath(szPath) ); // 2015.03.03 可能なら相対パスにする ::DlgItem_SetText( hwndDlg, IDC_EDIT_MIGEMO_DICT, m_Common.m_sHelper.m_szMigemoDict ); } diff --git a/sakura_core/prop/CPropComMacro.cpp b/sakura_core/prop/CPropComMacro.cpp index ecb1828c49..13a3136cb7 100644 --- a/sakura_core/prop/CPropComMacro.cpp +++ b/sakura_core/prop/CPropComMacro.cpp @@ -581,7 +581,7 @@ void CPropMacro::SelectBaseDir_Macro( HWND hwndDlg ) GetInidirOrExedir( szDir, folder ); } - if( SelectDir( hwndDlg, LS(STR_PROPCOMMACR_SEL_DIR), szDir, szDir ) ){ + if( SelectDir( hwndDlg, LS(STR_PROPCOMMACR_SEL_DIR), szDir, szDir, _countof(szDir) ) ){ // 末尾に\\マークを追加する. AddLastChar( szDir, _countof(szDir), L'\\' ); ::DlgItem_SetText( hwndDlg, IDC_MACRODIR, GetRelPath(szDir) ); // 2015.03.03 可能なら相対パスにする diff --git a/sakura_core/util/shell.cpp b/sakura_core/util/shell.cpp index e6f1468148..c4d0d7007a 100644 --- a/sakura_core/util/shell.cpp +++ b/sakura_core/util/shell.cpp @@ -38,63 +38,90 @@ #include "env/CShareData.h" #include "env/DLLSHAREDATA.h" #include "extmodule/CHtmlHelp.h" +#include -int CALLBACK MYBrowseCallbackProc( - HWND hwnd, - UINT uMsg, - LPARAM lParam, - LPARAM lpData -) + +/*! + @brief IFileDialog の初期フォルダを設定する + + @param [in] pDialog 設定対象のダイアログ + @param [in] pszInitFolder 初期フォルダに設定したいパス +*/ +static void SetInitialDir( Microsoft::WRL::ComPtr pDialog, const WCHAR* pszInitFolder ) { - switch( uMsg ){ - case BFFM_INITIALIZED: - ::SendMessage( hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpData ); - break; - case BFFM_SELCHANGED: - break; + + WCHAR szInitFolder[MAX_PATH]; + wcscpy_s( szInitFolder, _countof(szInitFolder), pszInitFolder ); + + // フォルダの最後が半角かつ'\\'の場合は、取り除く "c:\\"等のルートは取り除かない + CutLastYenFromDirectoryPath( szInitFolder ); + + // 初期フォルダを設定 + Microsoft::WRL::ComPtr psiFolder; + HRESULT hres = SHCreateItemFromParsingName( szInitFolder, nullptr, IID_PPV_ARGS(&psiFolder) ); + if ( SUCCEEDED(hres) ) { + pDialog->SetFolder( psiFolder.Get() ); } - return 0; } /* フォルダ選択ダイアログ */ -BOOL SelectDir( HWND hWnd, const WCHAR* pszTitle, const WCHAR* pszInitFolder, WCHAR* strFolderName ) +BOOL SelectDir( HWND hWnd, const WCHAR* pszTitle, const WCHAR* pszInitFolder, WCHAR* strFolderName, size_t nMaxCount ) { - BOOL bRes; - WCHAR szInitFolder[MAX_PATH]; + using namespace Microsoft::WRL; + ComPtr pDialog; + HRESULT hres; - wcscpy( szInitFolder, pszInitFolder ); - /* フォルダの最後が半角かつ'\\'の場合は、取り除く "c:\\"等のルートは取り除かない*/ - CutLastYenFromDirectoryPath( szInitFolder ); + // インスタンスを作成 + hres = CoCreateInstance( CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDialog) ); + if ( FAILED(hres) ) { + return FALSE; + } - // 2010.08.28 フォルダを開くとフックも含めて色々DLLが読み込まれるので移動 - CCurrentDirectoryBackupPoint dirBack; - ChangeCurrentDirectoryToExeDir(); + // デフォルト設定を取得 + DWORD dwOptions = 0; + hres = pDialog->GetOptions( &dwOptions ); + if ( FAILED(hres) ) { + return FALSE; + } - // SHBrowseForFolder()関数に渡す構造体 - BROWSEINFO bi; - bi.hwndOwner = hWnd; - bi.pidlRoot = NULL; - bi.pszDisplayName = strFolderName; - bi.lpszTitle = pszTitle; - bi.ulFlags = BIF_RETURNONLYFSDIRS/* | BIF_EDITBOX*//* | BIF_STATUSTEXT*/; - bi.lpfn = MYBrowseCallbackProc; - bi.lParam = (LPARAM)szInitFolder; - bi.iImage = 0; - // アイテムIDリストを返す - // ITEMIDLISTはアイテムの一意を表す構造体 - LPITEMIDLIST pList = ::SHBrowseForFolder(&bi); - if( NULL != pList ){ - // SHGetPathFromIDList()関数はアイテムIDリストの物理パスを探してくれる - bRes = ::SHGetPathFromIDList( pList, strFolderName ); - // :SHBrowseForFolder()で取得したアイテムIDリストを削除 - ::CoTaskMemFree( pList ); - if( bRes ){ - return TRUE; - }else{ - return FALSE; - } + // オプションをフォルダを選択可能に変更 + hres = pDialog->SetOptions( dwOptions | FOS_PICKFOLDERS | FOS_NOCHANGEDIR | FOS_FORCEFILESYSTEM ); + if ( FAILED(hres) ) { + return FALSE; + } + + // 初期フォルダを設定 + SetInitialDir( pDialog, pszInitFolder ); + + // タイトル文字列を設定 + hres = pDialog->SetTitle( pszTitle ); + if ( FAILED(hres) ) { + return FALSE; + } + + // フォルダ選択ダイアログを表示 + hres = pDialog->Show( hWnd ); + if ( FAILED(hres) ) { + return FALSE; + } + + // 選択結果を取得 + ComPtr psiResult; + hres = pDialog->GetResult( &psiResult ); + if ( FAILED(hres) ) { + return FALSE; + } + + PWSTR pszResult; + hres = psiResult->GetDisplayName( SIGDN_FILESYSPATH, &pszResult ); + if ( FAILED(hres) ) { + return FALSE; } - return FALSE; + + wcscpy_s( strFolderName, nMaxCount, pszResult ); + CoTaskMemFree( pszResult ); + + return TRUE; } /*! 特殊フォルダのパスを取得する diff --git a/sakura_core/util/shell.h b/sakura_core/util/shell.h index 1a496e6b59..9a407d5a3c 100644 --- a/sakura_core/util/shell.h +++ b/sakura_core/util/shell.h @@ -32,7 +32,7 @@ BOOL MyWinHelp(HWND hwndCaller, UINT uCommand, DWORD_PTR dwData); /* WinHelp のかわりに HtmlHelp を呼び出す */ // 2006.07.22 ryoji /* Shell Interface系(?) */ -BOOL SelectDir(HWND hWnd, const WCHAR* pszTitle, const WCHAR* pszInitFolder, WCHAR* strFolderName ); /* フォルダ選択ダイアログ */ +BOOL SelectDir(HWND hWnd, const WCHAR* pszTitle, const WCHAR* pszInitFolder, WCHAR* strFolderName, size_t nMaxCount ); /* フォルダ選択ダイアログ */ BOOL ResolveShortcutLink(HWND hwnd, LPCWSTR lpszLinkFile, LPWSTR lpszPath);/* ショートカット(.lnk)の解決 */ HWND OpenHtmlHelp( HWND hWnd, LPCWSTR szFile, UINT uCmd, DWORD_PTR data,bool msgflag = true);