Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

フォルダ選択ダイアログを SHBrowseForFolder() でなく IFileDialog を使用するように変更 #1609

Merged
merged 9 commits into from
Apr 10, 2021
Merged
2 changes: 1 addition & 1 deletion sakura_core/dlg/CDlgExec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,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() ) ){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

戻り値BOOLをやめた場合、ここはこんな感じになります。

if( auto selectedDir = SelectDir( GetHwnd(), LS(STR_DLGEXEC_SELECT_CURDIR), &m_szCurDir[0] ); selectedDir.length() > 0 ){
  m_szCurDir = selectedDir.c_str();

m_szCurDir の宣言型がおかしいのが原因で、ロジックが書きづらくなっています。
対応はしなくてもいいんじゃないかなぁ、と思います。

::DlgItem_SetText( GetHwnd(), IDC_COMBO_CUR_DIR, &m_szCurDir[0] );
}
}
Expand Down
115 changes: 66 additions & 49 deletions sakura_core/util/shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,63 +40,80 @@
#include "extmodule/CHtmlHelp.h"
#include "config/app_constants.h"
#include "String_define.h"
#include <wrl.h>

int CALLBACK MYBrowseCallbackProc(
HWND hwnd,
UINT uMsg,
LPARAM lParam,
LPARAM lpData
)
{
switch( uMsg ){
case BFFM_INITIALIZED:
::SendMessage( hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpData );
break;
case BFFM_SELCHANGED:
break;
}
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];
if ( nullptr == strFolderName ) {
return FALSE;
}

wcscpy( szInitFolder, pszInitFolder );
/* フォルダの最後が半角かつ'\\'の場合は、取り除く "c:\\"等のルートは取り除かない*/
CutLastYenFromDirectoryPath( szInitFolder );
using namespace Microsoft::WRL;
ComPtr<IFileDialog> pDialog;
HRESULT hres;

// 2010.08.28 フォルダを開くとフックも含めて色々DLLが読み込まれるので移動
CCurrentDirectoryBackupPoint dirBack;
ChangeCurrentDirectoryToExeDir();
// インスタンスを作成
hres = CoCreateInstance( CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDialog) );
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;
}
// デフォルト設定を取得
DWORD dwOptions = 0;
hres = pDialog->GetOptions( &dwOptions );
if ( FAILED(hres) ) {
return FALSE;
}

// オプションをフォルダを選択可能に変更
hres = pDialog->SetOptions( dwOptions | FOS_PICKFOLDERS | FOS_NOCHANGEDIR | FOS_FORCEFILESYSTEM );
if ( FAILED(hres) ) {
return FALSE;
}
return FALSE;

// 初期フォルダを設定
ComPtr<IShellItem> psiFolder;
hres = SHCreateItemFromParsingName( pszInitFolder, nullptr, IID_PPV_ARGS(&psiFolder) );
if ( SUCCEEDED(hres) ) {
pDialog->SetFolder( psiFolder.Get() );
}

// タイトル文字列を設定
hres = pDialog->SetTitle( pszTitle );
if ( FAILED(hres) ) {
return FALSE;
}

// フォルダ選択ダイアログを表示
hres = pDialog->Show( hWnd );
if ( FAILED(hres) ) {
return FALSE;
}

// 選択結果を取得
ComPtr<IShellItem> psiResult;
hres = pDialog->GetResult( &psiResult );
if ( FAILED(hres) ) {
return FALSE;
}

PWSTR pszResult;
berryzplus marked this conversation as resolved.
Show resolved Hide resolved
hres = psiResult->GetDisplayName( SIGDN_FILESYSPATH, &pszResult );
if ( FAILED(hres) ) {
return FALSE;
}

BOOL bRet = TRUE;
if ( 0 != wcsncpy_s( strFolderName, nMaxCount, pszResult, _TRUNCATE ) ) {
wcsncpy_s( strFolderName, nMaxCount, L"", _TRUNCATE );
bRet = FALSE;
}

CoTaskMemFree( pszResult );

return bRet;
}

/*! 特殊フォルダのパスを取得する
Expand Down
9 changes: 8 additions & 1 deletion sakura_core/util/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@
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 ); /* フォルダ選択ダイアログ */

template <size_t nMaxCount>
BOOL SelectDir(HWND hWnd, const WCHAR* pszTitle, const WCHAR* pszInitFolder, WCHAR(&strFolderName)[nMaxCount])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここ、SonarCloudの警告がでました。
対応は必須でないと思いますが、あるべき姿で考えると「戻り値BOOL」がマズいのかもです。

std::wstring SelectDir(
  HWND hWnd,
  std::wstring_view title,
  std::wstring_view initFolder);

{
return SelectDir( hWnd, pszTitle, pszInitFolder, strFolderName, nMaxCount );
}

BOOL ResolveShortcutLink(HWND hwnd, LPCWSTR lpszLinkFile, LPWSTR lpszPath);/* ショートカット(.lnk)の解決 */

HWND OpenHtmlHelp( HWND hWnd, LPCWSTR szFile, UINT uCmd, DWORD_PTR data,bool msgflag = true);
Expand Down