Revision: 9035 https://osdn.net/projects/ttssh2/scm/svn/commits/9035 Author: zmatsuo Date: 2020-11-22 00:12:27 +0900 (Sun, 22 Nov 2020) Log Message: ----------- 64bitビルド時にttxsshのホスト名エディットボックスで CTRL+k の動作がおかしかったので修正 - 関数名 SetEditboxSubclass() を SetEditboxEmacsKeybind() に変更した - C-b/C-f(カーソルを1文字前/後ろ)でサロゲートペアに対応 - エディットボックスかコンボボックスかを自動で判別するようにした - ttxssh のログイン履歴を Unicode 対応とした - teraterm.ini が Unicode で保存していあるとき有効 Modified Paths: -------------- trunk/teraterm/common/dlglib.c trunk/teraterm/common/dlglib.h trunk/teraterm/common/layer_for_unicode.cpp trunk/teraterm/teraterm/dnddlg.cpp trunk/teraterm/ttpdlg/ttdlg.c trunk/ttssh2/ttxssh/ttxssh.c -------------- next part -------------- Modified: trunk/teraterm/common/dlglib.c =================================================================== --- trunk/teraterm/common/dlglib.c 2020-11-21 14:59:32 UTC (rev 9034) +++ trunk/teraterm/common/dlglib.c 2020-11-21 15:12:27 UTC (rev 9035) @@ -40,6 +40,7 @@ #endif #include <stdlib.h> #include <crtdbg.h> +#include <wchar.h> #include "ttlib.h" // for get_lang_font() #include "layer_for_unicode.h" #include "codeconv.h" @@ -90,7 +91,7 @@ } HControl = GetDlgItem(HDlg, FirstId + R - 1); SendMessage(HControl, BM_SETCHECK, 1, 0); - Style = GetClassLongPtr(HControl, GCL_STYLE); + Style = (DWORD)GetClassLongPtr(HControl, GCL_STYLE); SetClassLongPtr(HControl, GCL_STYLE, Style | WS_TABSTOP); } @@ -232,24 +233,26 @@ typedef struct { WNDPROC OrigProc; // Original window procedure LONG_PTR OrigUser; // DWLP_USER - BOOL ComboBox; + BOOL IsComboBox; } EditSubclassData; -// C-n/C-p \x82̂\xBD\x82߂ɃT\x83u\x83N\x83\x89\x83X\x89\xBB (2007.9.4 maya) -// C-p/C-n/C-b/C-f/C-a/C-e \x82\xF0\x83T\x83|\x81[\x83g (2007.9.5 maya) -// C-d/C-k \x82\xF0\x83T\x83|\x81[\x83g (2007.10.3 yutaka) -// \x83h\x83\x8D\x83b\x83v\x83_\x83E\x83\x93\x82̒\x86\x82̃G\x83f\x83B\x83b\x83g\x83R\x83\x93\x83g\x83\x8D\x81[\x83\x8B\x82\xF0 -// \x83T\x83u\x83N\x83\x89\x83X\x89\xBB\x82\xB7\x82邽\x82߂̃E\x83C\x83\x93\x83h\x83E\x83v\x83\x8D\x83V\x81[\x83W\x83\x83 -// TODO \x83T\x83\x8D\x83Q\x81[\x83g\x83y\x83A\x95\xB6\x8E\x9A\x82̏ꍇ\x82̏\x88\x97\x9D +/** + * \x83T\x83|\x81[\x83g\x82\xB7\x82\xE9\x83L\x81[ + * C-n/C-p \x83R\x83\x93\x83{\x83{\x83b\x83N\x83X\x82̂Ƃ\xAB1\x82\xE3/\x89\xBA\x82\xF0\x91I\x91\xF0 + * C-b/C-f \x83J\x81[\x83\\x83\x8B\x82\xF01\x95\xB6\x8E\x9A\x91O/\x8C\xE3\x82\xEB + * C-a/C-e \x83J\x81[\x83\\x83\x8B\x82\xF0\x8Ds\x93\xAA/\x8Ds\x96\x96 + * C-d \x83J\x81[\x83\\x83\x8B\x94z\x89\xBA\x82\xCC1\x95\xB6\x8E\x9A\x8D폜 + * C-k \x83J\x81[\x83\\x83\x8B\x82\xA9\x82\xE7\x8Ds\x96\x96\x82܂ō폜 + * C-u \x83J\x81[\x83\\x83\x8B\x82\xE6\x82\xE8\x8Ds\x93\xAA\x82܂ō폜 + */ static LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { EditSubclassData *data = (EditSubclassData *)GetWindowLongPtr(dlg, GWLP_USERDATA); LRESULT Result; - LRESULT select; - LRESULT max; - int len; - char *str, *orgstr; + DWORD select; + DWORD max; + DWORD len; switch (msg) { // \x83L\x81[\x82\xAA\x89\x9F\x82\xB3\x82ꂽ\x82̂\xF0\x8C\x9F\x92m\x82\xB7\x82\xE9 @@ -257,64 +260,105 @@ if (GetKeyState(VK_CONTROL) < 0) { switch (wParam) { case 0x50: // Ctrl+p ... up - if (data->ComboBox) { + if (data->IsComboBox) { HWND parent = GetParent(dlg); - select = SendMessage(parent, CB_GETCURSEL, 0, 0); - if (select > 0) { - PostMessage(parent, CB_SETCURSEL, select - 1, 0); + select = (DWORD)_SendMessageW(parent, CB_GETCURSEL, 0, 0); + if (select == CB_ERR) { + max = (DWORD)_SendMessageW(parent, CB_GETCOUNT, 0, 0); + PostMessageW(parent, CB_SETCURSEL, max - 1, 0); } + else if (select > 0) { + PostMessageW(parent, CB_SETCURSEL, select - 1, 0); + } return 0; } break; case 0x4e: // Ctrl+n ... down - if (data->ComboBox) { + if (data->IsComboBox) { HWND parent = GetParent(dlg); - max = SendMessage(parent, CB_GETCOUNT, 0, 0); - select = SendMessage(parent, CB_GETCURSEL, 0, 0); - if (select < max - 1) { - PostMessage(parent, CB_SETCURSEL, select + 1, 0); + max = (DWORD)_SendMessageW(parent, CB_GETCOUNT, 0, 0); + select = (DWORD)_SendMessageW(parent, CB_GETCURSEL, 0, 0); + if (select == CB_ERR) { + PostMessageW(parent, CB_SETCURSEL, 0, 0); + } else if (select < max - 1) { + PostMessageW(parent, CB_SETCURSEL, select + 1, 0); } return 0; } break; - case 0x42: // Ctrl+b ... left - SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select); - PostMessage(dlg, EM_SETSEL, select-1, select-1); + case 0x42: { + // Ctrl+b ... left + _SendMessageW(dlg, EM_GETSEL, 0, (LPARAM)&select); + if (select > 0) { + wchar_t *str; + max = _GetWindowTextLengthW(dlg); + max++; // '\0' + str = (wchar_t *)malloc(sizeof(wchar_t) * max); + if (str == NULL) { + return 0; + } + _GetWindowTextW(dlg, str, (int)max); + select = select - 1; + if (IsLowSurrogate(str[select])) { + select = select - 1; + } + PostMessageW(dlg, EM_SETSEL, select, select); + free(str); + } return 0; - case 0x46: // Ctrl+f ... right - SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select); - max = GetWindowTextLength(dlg) ; - PostMessage(dlg, EM_SETSEL, select+1, select+1); + } + case 0x46: { + // Ctrl+f ... right + _SendMessageW(dlg, EM_GETSEL, 0, (LPARAM)&select); + max = _GetWindowTextLengthW(dlg); + if (select < max) { + wchar_t *str; + max++; // '\0' + str = (wchar_t *)malloc(sizeof(wchar_t) * max); + if (str == NULL) { + return 0; + } + _GetWindowTextW(dlg, str, (int)max); + select = select + 1; + if (IsLowSurrogate(str[select])) { + select = select + 1; + } + PostMessageW(dlg, EM_SETSEL, select, select); + free(str); + } return 0; + } case 0x41: // Ctrl+a ... home - PostMessage(dlg, EM_SETSEL, 0, 0); + PostMessageW(dlg, EM_SETSEL, 0, 0); return 0; case 0x45: // Ctrl+e ... end - max = GetWindowTextLength(dlg) ; - PostMessage(dlg, EM_SETSEL, max, max); + max = _GetWindowTextLengthW(dlg) ; + PostMessageW(dlg, EM_SETSEL, max, max); return 0; case 0x44: // Ctrl+d case 0x4b: // Ctrl+k - case 0x55: // Ctrl+u - SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select); - max = GetWindowTextLength(dlg); + case 0x55: { + // Ctrl+u + wchar_t *str, *orgstr; + _SendMessageW(dlg, EM_GETSEL, 0, (LPARAM)&select); + max = _GetWindowTextLengthW(dlg); max++; // '\0' - orgstr = str = (char *)malloc(max); + orgstr = str = (wchar_t *)malloc(sizeof(wchar_t) * max); if (str != NULL) { - len = GetWindowTextA(dlg, str, (int)max); - if (select >= 0 && select < len) { - if (wParam == 0x44) { // \x83J\x81[\x83\\x83\x8B\x94z\x89\xBA\x82̕\xB6\x8E\x9A\x82݂̂\xF0\x8D폜\x82\xB7\x82\xE9 - memmove(&str[select], &str[select + 1], len - select - 1); + len = _GetWindowTextW(dlg, str, (int)max); + if (select < len) { + if (wParam == 0x44) { // Ctrl+d \x83J\x81[\x83\\x83\x8B\x94z\x89\xBA\x82̕\xB6\x8E\x9A\x82݂̂\xF0\x8D폜\x82\xB7\x82\xE9 + wmemmove(&str[select], &str[select + 1], len - select - 1); str[len - 1] = '\0'; - } else if (wParam == 0x4b) { // \x83J\x81[\x83\\x83\x8B\x82\xA9\x82\xE7\x8Ds\x96\x96\x82܂ō폜\x82\xB7\x82\xE9 + } else if (wParam == 0x4b) { // Ctrl+k \x83J\x81[\x83\\x83\x8B\x82\xA9\x82\xE7\x8Ds\x96\x96\x82܂ō폜\x82\xB7\x82\xE9 str[select] = '\0'; } } - if (wParam == 0x55) { // \x83J\x81[\x83\\x83\x8B\x82\xE6\x82荶\x91\xA4\x82\xF0\x82\xB7\x82ׂď\xC1\x82\xB7 + if (wParam == 0x55) { // Ctrl+u\x83J\x81[\x83\\x83\x8B\x82\xE6\x82荶\x91\xA4\x82\xF0\x82\xB7\x82ׂď\xC1\x82\xB7 if (select >= len) { str[0] = '\0'; } else { @@ -323,12 +367,15 @@ select = 0; } - SetWindowTextA(dlg, str); - SendMessage(dlg, EM_SETSEL, select, select); + _SetWindowTextW(dlg, str); + _SendMessageW(dlg, EM_SETSEL, select, select); free(orgstr); return 0; } break; + } + default: + break; } } break; @@ -374,19 +421,22 @@ * C-n/C-p \x82̂\xBD\x82߂ɃT\x83u\x83N\x83\x89\x83X\x89\xBB * @praram hDlg \x83_\x83C\x83A\x83\x8D\x83O * @praram nID emacs\x95\x97\x82ɂ\xB7\x82\xE9\x83G\x83f\x83B\x83b\x83g\x83{\x83b\x83N\x83X \x82܂\xBD\x82\xCD \x83R\x83\x93\x83{\x83{\x83b\x83N\x83X - * @param comboBox TRUE = nID\x82\xAA\x83R\x83\x93\x83{\x83{\x83b\x83N\x83X */ -void SetEditboxSubclass(HWND hDlg, int nID, BOOL ComboBox) +void SetEditboxEmacsKeybind(HWND hDlg, int nID) { EditSubclassData *data; HWND hWndEdit = GetDlgItem(hDlg, nID); - if (ComboBox) { + BOOL IsCombobox = FALSE; + char ClassName[32]; + GetClassNameA(hWndEdit, ClassName, _countof(ClassName)); + if (strcmp(ClassName, "ComboBox") == 0) { hWndEdit = GetWindow(hWndEdit, GW_CHILD); + IsCombobox = TRUE; } data = (EditSubclassData *)malloc(sizeof(EditSubclassData)); data->OrigProc = (WNDPROC)GetWindowLongPtrW(hWndEdit, GWLP_WNDPROC); data->OrigUser = (LONG_PTR)GetWindowLongPtr(hWndEdit, GWLP_USERDATA); - data->ComboBox = ComboBox; + data->IsComboBox = IsCombobox; _SetWindowLongPtrW(hWndEdit, GWLP_WNDPROC, (LONG_PTR)HostnameEditProc); SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)data); } Modified: trunk/teraterm/common/dlglib.h =================================================================== --- trunk/teraterm/common/dlglib.h 2020-11-21 14:59:32 UTC (rev 9034) +++ trunk/teraterm/common/dlglib.h 2020-11-21 15:12:27 UTC (rev 9035) @@ -49,7 +49,7 @@ void SetDropDownListW(HWND HDlg, int Id_Item, const wchar_t *List[], int nsel); LONG GetCurSel(HWND HDlg, int Id_Item); void InitDlgProgress(HWND HDlg, int id_Progress, int *CurProgStat); -void SetEditboxSubclass(HWND hDlg, int nID, BOOL ComboBox); +void SetEditboxEmacsKeybind(HWND hDlg, int nID); #if defined(_UNICODE) #define SetDropDownListT(p1, p2, p3, p4) SetDropDownListW(p1, p2, p3, p4) Modified: trunk/teraterm/common/layer_for_unicode.cpp =================================================================== --- trunk/teraterm/common/layer_for_unicode.cpp 2020-11-21 14:59:32 UTC (rev 9034) +++ trunk/teraterm/common/layer_for_unicode.cpp 2020-11-21 15:12:27 UTC (rev 9035) @@ -538,7 +538,7 @@ if (pSetWindowLongPtrW != NULL) { return pSetWindowLongPtrW(hWnd, nIndex, dwNewLong); } - return SetWindowLongPtr(hWnd, nIndex, dwNewLong); + return SetWindowLongPtrA(hWnd, nIndex, dwNewLong); #else return _SetWindowLongW(hWnd, nIndex, dwNewLong); #endif Modified: trunk/teraterm/teraterm/dnddlg.cpp =================================================================== --- trunk/teraterm/teraterm/dnddlg.cpp 2020-11-21 14:59:32 UTC (rev 9034) +++ trunk/teraterm/teraterm/dnddlg.cpp 2020-11-21 15:12:27 UTC (rev 9035) @@ -1,5 +1,5 @@ /* - * (C) 2005-2019 TeraTerm Project + * (C) 2005-2020 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,7 +111,7 @@ EnableWindow(GetDlgItem(hDlgWnd, IDC_SCP_PATH), FALSE); EnableWindow(GetDlgItem(hDlgWnd, IDC_SCP_PATH_NOTE), FALSE); } - SetEditboxSubclass(hDlgWnd, IDC_SCP_PATH, FALSE); + SetEditboxEmacsKeybind(hDlgWnd, IDC_SCP_PATH); // Send File if (Param->DropType == DROP_TYPE_SEND_FILE_BINARY) { Modified: trunk/teraterm/ttpdlg/ttdlg.c =================================================================== --- trunk/teraterm/ttpdlg/ttdlg.c 2020-11-21 14:59:32 UTC (rev 9034) +++ trunk/teraterm/ttpdlg/ttdlg.c 2020-11-21 15:12:27 UTC (rev 9035) @@ -1902,7 +1902,7 @@ SendDlgItemMessage(Dialog, IDC_HOSTNAME, CB_SETCURSEL,0,0); - SetEditboxSubclass(Dialog, IDC_HOSTNAME, TRUE); + SetEditboxEmacsKeybind(Dialog, IDC_HOSTNAME); SetRB(Dialog,GetHNRec->Telnet,IDC_HOSTTELNET,IDC_HOSTTELNET); SendDlgItemMessage(Dialog, IDC_HOSTTCPPORT, EM_LIMITTEXT,5,0); Modified: trunk/ttssh2/ttxssh/ttxssh.c =================================================================== --- trunk/ttssh2/ttxssh/ttxssh.c 2020-11-21 14:59:32 UTC (rev 9034) +++ trunk/ttssh2/ttxssh/ttxssh.c 2020-11-21 15:12:27 UTC (rev 9035) @@ -1207,7 +1207,6 @@ static char *ProtocolFamilyList[] = { "AUTO", "IPv6", "IPv4", NULL }; PGetHNRec GetHNRec; char EntName[128]; - char TempHost[HostNameMaxLength + 1]; WORD i, j, w; WORD ComPortTable[MAXCOMPORT]; static char *ComPortDesc[MAXCOMPORT]; @@ -1235,26 +1234,30 @@ ) GetHNRec->PortType = IdTCPIP; - strncpy_s(EntName, sizeof(EntName), "Host", _TRUNCATE); + { + wchar_t *SetupFnW = ToWcharA(GetHNRec->SetupFN); + i = 1; + do { + wchar_t EntNameW[128]; + wchar_t TempHostW[HostNameMaxLength + 1]; + _snwprintf_s(EntNameW, _countof(EntNameW), _TRUNCATE, L"host%d", i); + GetPrivateProfileStringW(L"Hosts", EntNameW, L"", + TempHostW, _countof(TempHostW), + SetupFnW); + if (TempHostW[0] != 0) + SendDlgItemMessageW(dlg, IDC_HOSTNAME, CB_ADDSTRING, + 0, (LPARAM) TempHostW); + i++; + } while (i <= MAXHOSTLIST); + free(SetupFnW); + } - i = 1; - do { - _snprintf_s(&EntName[4], sizeof(EntName)-4, _TRUNCATE, "%d", i); - GetPrivateProfileString("Hosts", EntName, "", - TempHost, sizeof(TempHost), - GetHNRec->SetupFN); - if (strlen(TempHost) > 0) - SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING, - 0, (LPARAM) TempHost); - i++; - } while (i <= MAXHOSTLIST); - SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT, HostNameMaxLength - 1, 0); SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0); - SetEditboxSubclass(dlg, IDC_HOSTNAME, TRUE); + SetEditboxEmacsKeybind(dlg, IDC_HOSTNAME); CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER, pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->