• R/O
  • SSH
  • HTTPS

ttssh2: コミット


コミットメタ情報

リビジョン9420 (tree)
日時2021-09-14 00:20:06
作者zmatsuo

ログメッセージ

文字長 MAX_PATH 以上の文字列を返せるよう doSelectFolderW() の仕様を変更

- 従来の doSelectFolder() を使用している個所をなくした
- doSelectFolder() は doSelectFolderW() のラッパとした
- doSelectFolderW() を common/ttlib_static_cpp.cpp へ移動
- 現在 doSelectFolderW() 内部には MAX_PATH の上限がある

- 内部で使用している SHGetPathFromIDListW() の仕様
- SHGetPathFromIDListEx() への切り替えで上限はなくなる?

変更サマリ

差分

--- trunk/teraterm/common/ttlib.c (revision 9419)
+++ trunk/teraterm/common/ttlib.c (revision 9420)
@@ -910,59 +910,19 @@
910910 return TRUE;
911911 }
912912
913-//
914-// cf. http://homepage2.nifty.com/DSS/VCPP/API/SHBrowseForFolder.htm
915-//
916-static int CALLBACK setDefaultFolder(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
917-{
918- if(uMsg == BFFM_INITIALIZED) {
919- SendMessage(hwnd, BFFM_SETSELECTION, (WPARAM)TRUE, lpData);
920- }
921- return 0;
922-}
923-
924913 BOOL doSelectFolder(HWND hWnd, char *path, int pathlen, const char *def, const char *msg)
925914 {
926- BROWSEINFOA bi;
927- LPITEMIDLIST pidlRoot; // ブラウズのルートPIDL
928- LPITEMIDLIST pidlBrowse; // ユーザーが選択したPIDL
929- char buf[MAX_PATH];
930- BOOL ret = FALSE;
931-
932- // ダイアログ表示時のルートフォルダのPIDLを取得
933- // ※以下はデスクトップをルートとしている。デスクトップをルートとする
934- // 場合は、単に bi.pidlRoot に0を設定するだけでもよい。その他の特
935- // 殊フォルダをルートとする事もできる。詳細はSHGetSpecialFolderLoca
936- // tionのヘルプを参照の事。
937- if (!SUCCEEDED(SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlRoot))) {
938- return FALSE;
915+ wchar_t *defW = ToWcharA(def);
916+ wchar_t *msgW = ToWcharA(msg);
917+ wchar_t *pathW;
918+ BOOL r = doSelectFolderW(hWnd, defW, msgW, &pathW);
919+ if (r == TRUE) {
920+ WideCharToACP_t(pathW, path, pathlen);
921+ free(pathW);
939922 }
940-
941- // BROWSEINFO構造体の初期値設定
942- // ※BROWSEINFO構造体の各メンバの詳細説明もヘルプを参照
943- bi.hwndOwner = hWnd;
944- bi.pidlRoot = pidlRoot;
945- bi.pszDisplayName = buf;
946- bi.lpszTitle = msg;
947- bi.ulFlags = 0;
948- bi.lpfn = setDefaultFolder;
949- bi.lParam = (LPARAM)def;
950- // フォルダ選択ダイアログの表示
951- pidlBrowse = SHBrowseForFolderA(&bi);
952- if (pidlBrowse != NULL) {
953- // PIDL形式の戻り値のファイルシステムのパスに変換
954- if (SHGetPathFromIDListA(pidlBrowse, buf)) {
955- // 取得成功
956- strncpy_s(path, pathlen, buf, _TRUNCATE);
957- ret = TRUE;
958- }
959- // SHBrowseForFolderの戻り値PIDLを解放
960- CoTaskMemFree(pidlBrowse);
961- }
962- // クリーンアップ処理
963- CoTaskMemFree(pidlRoot);
964-
965- return ret;
923+ free(msgW);
924+ free(defW);
925+ return r;
966926 }
967927
968928 void OutputDebugPrintf(const char *fmt, ...)
--- trunk/teraterm/common/ttlib.h (revision 9419)
+++ trunk/teraterm/common/ttlib.h (revision 9420)
@@ -94,7 +94,7 @@
9494 void get_lang_msgW(const char *key, wchar_t *buf, int buf_len, const wchar_t *def, const char *iniFile);
9595 int get_lang_font(const char *key, HWND dlg, PLOGFONT logfont, HFONT *font, const char *iniFile);
9696 DllExport BOOL doSelectFolder(HWND hWnd, char *path, int pathlen, const char *def, const char *msg);
97-BOOL doSelectFolderW(HWND hWnd, wchar_t *path, int pathlen, const wchar_t *def, const wchar_t *msg);
97+BOOL doSelectFolderW(HWND hWnd, const wchar_t *def, const wchar_t *msg, wchar_t **folder);
9898 DllExport void OutputDebugPrintf(const char *fmt, ...);
9999 void OutputDebugPrintfW(const wchar_t *fmt, ...);
100100 void OutputDebugHexDump(const void *data, size_t len);
--- trunk/teraterm/common/ttlib_static.c (revision 9419)
+++ trunk/teraterm/common/ttlib_static.c (revision 9420)
@@ -352,61 +352,4 @@
352352 OutputDebugStringW(tmp);
353353 }
354354
355-static int CALLBACK setDefaultFolder(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
356-{
357- if(uMsg == BFFM_INITIALIZED) {
358- if (IsWindowsNTKernel()) {
359- SendMessageW(hwnd, BFFM_SETSELECTIONW, (WPARAM)TRUE, lpData);
360- } else {
361- // NT系ではないとき、Layer for unicode が使用されていると思われる
362- SendMessageA(hwnd, BFFM_SETSELECTIONA, (WPARAM)TRUE, lpData);
363- }
364- }
365- return 0;
366-}
367-
368-BOOL doSelectFolderW(HWND hWnd, wchar_t *path, int pathlen, const wchar_t *def, const wchar_t *msg)
369-{
370- BROWSEINFOW bi;
371- LPITEMIDLIST pidlRoot; // ブラウズのルートPIDL
372- LPITEMIDLIST pidlBrowse; // ユーザーが選択したPIDL
373- wchar_t buf[MAX_PATH];
374- BOOL ret = FALSE;
375-
376- // ダイアログ表示時のルートフォルダのPIDLを取得
377- // ※以下はデスクトップをルートとしている。デスクトップをルートとする
378- // 場合は、単に bi.pidlRoot に0を設定するだけでもよい。その他の特
379- // 殊フォルダをルートとする事もできる。詳細はSHGetSpecialFolderLoca
380- // tionのヘルプを参照の事。
381- if (!SUCCEEDED(SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlRoot))) {
382- return FALSE;
383- }
384-
385- // BROWSEINFO構造体の初期値設定
386- // ※BROWSEINFO構造体の各メンバの詳細説明もヘルプを参照
387- bi.hwndOwner = hWnd;
388- bi.pidlRoot = pidlRoot;
389- bi.pszDisplayName = buf;
390- bi.lpszTitle = msg;
391- bi.ulFlags = 0;
392- bi.lpfn = setDefaultFolder;
393- bi.lParam = (LPARAM)def;
394- // フォルダ選択ダイアログの表示
395- pidlBrowse = SHBrowseForFolderW(&bi);
396- if (pidlBrowse != NULL) {
397- // PIDL形式の戻り値のファイルシステムのパスに変換
398- if (SHGetPathFromIDListW(pidlBrowse, buf)) {
399- // 取得成功
400- wcsncpy_s(path, pathlen, buf, _TRUNCATE);
401- ret = TRUE;
402- }
403- // SHBrowseForFolderの戻り値PIDLを解放
404- CoTaskMemFree(pidlBrowse);
405- }
406- // クリーンアップ処理
407- CoTaskMemFree(pidlRoot);
408-
409- return ret;
410-}
411-
412355 /* vim: set ts=4 sw=4 ff=dos : */
--- trunk/teraterm/common/ttlib_static_cpp.cpp (revision 9419)
+++ trunk/teraterm/common/ttlib_static_cpp.cpp (revision 9420)
@@ -1069,3 +1069,62 @@
10691069 _SHGetKnownFolderPath(FOLDERID_Downloads, 0, NULL, &download);
10701070 return download;
10711071 }
1072+
1073+static int CALLBACK BrowseCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
1074+{
1075+ switch(uMsg) {
1076+ case BFFM_INITIALIZED: {
1077+ // 初期化時
1078+
1079+ const wchar_t *folder = (wchar_t *)lpData;
1080+ if (folder == NULL || folder[0] == 0) {
1081+ // 選択フォルダが指定されていない
1082+ break;
1083+ }
1084+ // フォルダを選択状態にする
1085+ SendMessageW(hwnd, BFFM_SETSELECTIONW, (WPARAM)TRUE, (LPARAM)folder);
1086+ break;
1087+ }
1088+ default:
1089+ break;
1090+ }
1091+ return 0;
1092+}
1093+
1094+/**
1095+ * フォルダを選択する
1096+ * SHBrowseForFolderW() をコールする
1097+ *
1098+ * @param[in] def 選択フォルダの初期値(特に指定しないときは NULL or "")
1099+ * @param[out] **folder 選択したフォルダのフルパス(キャンセル時はセットされない)
1100+ * 不要になったら free() すること(キャンセル時はfree()不要)
1101+ * @retval TRUE 選択した
1102+ * @retval FALSE キャンセルした
1103+ *
1104+ */
1105+BOOL doSelectFolderW(HWND hWnd, const wchar_t *def, const wchar_t *msg, wchar_t **folder)
1106+{
1107+ wchar_t buf[MAX_PATH];
1108+ BROWSEINFOW bi = {};
1109+ bi.hwndOwner = hWnd;
1110+ bi.pidlRoot = 0; // 0 = from desktop
1111+ bi.pszDisplayName = buf;
1112+ bi.lpszTitle = msg;
1113+ bi.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE;
1114+ bi.lpfn = BrowseCallback;
1115+ bi.lParam = (LPARAM)def;
1116+ LPITEMIDLIST pidlBrowse = SHBrowseForFolderW(&bi);
1117+ if (pidlBrowse == NULL) {
1118+ *folder = NULL;
1119+ return FALSE;
1120+ }
1121+
1122+ // PIDL形式の戻り値のファイルシステムのパスに変換
1123+ // TODO SHGetPathFromIDListEx() へ切り替え?
1124+ if (!SHGetPathFromIDListW(pidlBrowse, buf)) {
1125+ return FALSE;
1126+ }
1127+ *folder = _wcsdup(buf);
1128+ CoTaskMemFree(pidlBrowse);
1129+ return TRUE;
1130+}
--- trunk/teraterm/layer_for_unicode/layer_for_unicode.cpp (revision 9419)
+++ trunk/teraterm/layer_for_unicode/layer_for_unicode.cpp (revision 9420)
@@ -171,7 +171,7 @@
171171 return (int)lenW;
172172 }
173173
174-static LRESULT SendMessageAFromW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
174+LRESULT WINAPI _SendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
175175 {
176176 LRESULT retval;
177177 switch(Msg) {
@@ -215,6 +215,17 @@
215215 free(strW);
216216 return dest_len - 1 < lenW ? dest_len - 1 : lenW;
217217 }
218+ case BFFM_SETSELECTIONW: {
219+ if (wParam == TRUE) {
220+ // フォルダを選択状態にする
221+ char *folderA = ToCharW((wchar_t *)lParam);
222+ retval = SendMessageA(hWnd, BFFM_SETSELECTIONA, wParam, (LPARAM)folderA);
223+ free(folderA);
224+ }
225+ else {
226+ retval = SendMessageA(hWnd, Msg, wParam, lParam);
227+ }
228+ }
218229 default:
219230 retval = SendMessageA(hWnd, Msg, wParam, lParam);
220231 break;
@@ -222,15 +233,10 @@
222233 return retval;
223234 }
224235
225-LRESULT WINAPI _SendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
226-{
227- return SendMessageAFromW(hWnd, Msg, wParam, lParam);
228-}
229-
230236 LRESULT WINAPI _SendDlgItemMessageW(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)
231237 {
232238 HWND hWnd = GetDlgItem(hDlg, nIDDlgItem);
233- return SendMessageAFromW(hWnd, Msg, wParam, lParam);
239+ return _SendMessageW(hWnd, Msg, wParam, lParam);
234240 }
235241
236242 HWND WINAPI _CreateWindowExW(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X,
@@ -477,7 +483,7 @@
477483 LPITEMIDLIST WINAPI _SHBrowseForFolderW(LPBROWSEINFOW lpbi)
478484 {
479485 char display_name[MAX_PATH];
480- BROWSEINFOA biA;
486+ BROWSEINFOA biA = {};
481487 biA.hwndOwner = lpbi->hwndOwner;
482488 biA.pidlRoot = lpbi->pidlRoot;
483489 biA.pszDisplayName = display_name;
--- trunk/teraterm/teraterm/addsetting.cpp (revision 9419)
+++ trunk/teraterm/teraterm/addsetting.cpp (revision 9420)
@@ -54,6 +54,7 @@
5454 #include "coding_pp.h"
5555 #include "font_pp.h"
5656 #include "asprintf.h"
57+#include "win32helper.h"
5758
5859 const mouse_cursor_t MouseCursor[] = {
5960 {"ARROW", IDC_ARROW},
@@ -1424,12 +1425,14 @@
14241425 // ログディレクトリの選択ダイアログ
14251426 {
14261427 wchar_t *title = TTGetLangStrW("Tera Term", "FILEDLG_SELECT_LOGDIR_TITLE", L"Select log folder", ts.UILanguageFile);
1427- wchar_t buf[MAX_PATH];
1428- wchar_t buf2[MAX_PATH];
1429- GetDlgItemTextW(IDC_DEFAULTPATH_EDITOR, buf, _countof(buf));
1430- if (doSelectFolderW(GetSafeHwnd(), buf2, _countof(buf2), buf, title)) {
1428+ wchar_t *buf;
1429+ hGetDlgItemTextW(m_hWnd, IDC_DEFAULTPATH_EDITOR, &buf);
1430+ wchar_t *buf2;
1431+ if (doSelectFolderW(GetSafeHwnd(), buf, title, &buf2)) {
14311432 SetDlgItemTextW(IDC_DEFAULTPATH_EDITOR, buf2);
1433+ free(buf2);
14321434 }
1435+ free(buf);
14331436 free(title);
14341437 }
14351438
@@ -1662,16 +1665,18 @@
16621665
16631666 BOOL CCygwinPropPageDlg::OnCommand(WPARAM wParam, LPARAM lParam)
16641667 {
1665- wchar_t buf[MAX_PATH], buf2[MAX_PATH];
1666-
16671668 switch (wParam) {
16681669 case IDC_SELECT_FILE | (BN_CLICKED << 16):
16691670 // Cygwin install ディレクトリの選択ダイアログ
16701671 wchar_t *title = TTGetLangStrW("Tera Term", "DIRDLG_CYGTERM_DIR_TITLE", L"Select Cygwin directory", ts.UILanguageFile);
1671- GetDlgItemTextW(IDC_CYGWIN_PATH, buf, _countof(buf));
1672- if (doSelectFolderW(GetSafeHwnd(), buf2, _countof(buf2), buf, title)) {
1673- SetDlgItemTextW(IDC_CYGWIN_PATH, buf2);
1672+ wchar_t *buf;
1673+ hGetDlgItemTextW(m_hWnd, IDC_CYGWIN_PATH, &buf);
1674+ wchar_t *path;
1675+ if (doSelectFolderW(GetSafeHwnd(), buf, title, &path)) {
1676+ SetDlgItemTextW(IDC_CYGWIN_PATH, path);
1677+ free(path);
16741678 }
1679+ free(buf);
16751680 free(title);
16761681 return TRUE;
16771682 }
--- trunk/teraterm/ttpdlg/ttdlg.c (revision 9419)
+++ trunk/teraterm/ttpdlg/ttdlg.c (revision 9420)
@@ -53,6 +53,7 @@
5353 #include "codeconv.h"
5454 #include "helpid.h"
5555 #include "asprintf.h"
56+#include "win32helper.h"
5657
5758 // Oniguruma: Regular expression library
5859 #define ONIG_EXTERN extern
@@ -2081,7 +2082,6 @@
20812082 POINT D, B, S;
20822083 int WX, WY, WW, WH, CW, DW, DH, BW, BH, SW, SH;
20832084 char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG];
2084- char buf[MAX_PATH], buf2[MAX_PATH];
20852085
20862086 switch (Message) {
20872087 case WM_INITDIALOG:
@@ -2197,18 +2197,23 @@
21972197 EndDialog(Dialog, 0);
21982198 return TRUE;
21992199
2200- case IDC_SELECT_DIR:
2201- get_lang_msg("DLG_SELECT_DIR_TITLE", uimsg, sizeof(uimsg),
2202- "Select new directory", UILanguageFile);
2200+ case IDC_SELECT_DIR: {
2201+ wchar_t uimsgW[MAX_UIMSG];
2202+ wchar_t *buf, *buf2;
2203+ get_lang_msgW("DLG_SELECT_DIR_TITLE", uimsgW, _countof(uimsgW),
2204+ L"Select new directory", UILanguageFile);
22032205 {
2204- char FileDirExpanded[MAX_PATH];
2205- GetDlgItemText(Dialog, IDC_DIRNEW, buf, sizeof(buf));
2206- ExpandEnvironmentStrings(buf, FileDirExpanded, sizeof(FileDirExpanded));
2207- if (doSelectFolder(Dialog, buf2, sizeof(buf2), FileDirExpanded, uimsg)) {
2208- SetDlgItemText(Dialog, IDC_DIRNEW, buf2);
2206+ wchar_t FileDirExpanded[MAX_PATH];
2207+ hGetDlgItemTextW(Dialog, IDC_DIRNEW, &buf);
2208+ ExpandEnvironmentStringsW(buf, FileDirExpanded, _countof(FileDirExpanded));
2209+ if (doSelectFolderW(Dialog, FileDirExpanded, uimsgW, &buf2)) {
2210+ SetDlgItemTextW(Dialog, IDC_DIRNEW, buf2);
2211+ free(buf2);
22092212 }
2213+ free(buf);
22102214 }
22112215 return TRUE;
2216+ }
22122217
22132218 case IDC_DIRHELP:
22142219 PostMessage(GetParent(Dialog),WM_USER_DLGHELP2,HlpFileChangeDir,0);
--- trunk/teraterm/ttpmacro/ttl_gui.cpp (revision 9419)
+++ trunk/teraterm/ttpmacro/ttl_gui.cpp (revision 9420)
@@ -317,11 +317,12 @@
317317 if (CheckVar("inputstr", &ValType, &VarId) &&
318318 (ValType == TypString)) {
319319 BringupWindow(GetHWND());
320- wchar_t buf[MAX_PATH];
321- if (doSelectFolderW(GetHWND(), buf, _countof(buf), wc::fromUtf8(InitDir), wc::fromUtf8(Title))) {
320+ wchar_t *buf;
321+ if (doSelectFolderW(GetHWND(), wc::fromUtf8(InitDir), wc::fromUtf8(Title), &buf)) {
322322 const char *bufU8 = ToU8W(buf);
323323 SetInputStr((PCHAR)bufU8);
324324 free((void *)bufU8);
325+ free(buf);
325326 ret = 1;
326327 }
327328 else {
--- trunk/ttssh2/ttxssh/ttxssh.c (revision 9419)
+++ trunk/ttssh2/ttxssh/ttxssh.c (revision 9420)
@@ -3306,13 +3306,14 @@
33063306 return TRUE;
33073307 case IDC_RECVDIR_SELECT | (BN_CLICKED << 16):
33083308 {
3309- char buf[MAX_PATH], buf2[MAX_PATH];
3310- hWnd = GetDlgItem(dlg, IDC_RECVFILE_TO);
3311- SendMessage(hWnd, WM_GETTEXT , sizeof(buf), (LPARAM)buf);
3312- if (doSelectFolder(dlg, buf2, sizeof(buf2), buf, "Choose destination directory")) {
3313- strncpy_s(recvdir, sizeof(recvdir), buf2, _TRUNCATE);
3314- SendMessage(GetDlgItem(dlg, IDC_RECVFILE_TO), WM_SETTEXT, 0, (LPARAM)recvdir);
3309+ wchar_t *buf, *buf2;
3310+ hGetDlgItemTextW(dlg, IDC_RECVFILE_TO, &buf);
3311+ if (doSelectFolderW(dlg, buf, L"Choose destination directory", &buf2)) {
3312+ WideCharToACP_t(buf2, recvdir, sizeof(recvdir));
3313+ SetDlgItemTextA(dlg, IDC_RECVFILE_TO, recvdir);
3314+ free(buf2);
33153315 }
3316+ free(buf);
33163317 }
33173318 return TRUE;
33183319 }
旧リポジトリブラウザで表示