Revision: 7509 http://sourceforge.jp/projects/ttssh2/scm/svn/commits/7509 Author: zmatsuo Date: 2019-03-25 22:47:32 +0900 (Mon, 25 Mar 2019) Log Message: ----------- クリップボード内容表示ダイアログをHiDPI化 dlglib.c,h ANSI/UNICODE対応,IsExistFont(),SetDialogFont()(ダイアログフォントの初期化) 追加 dlglib_cpp.cpp 追加、ダイアログAPIラッパ dlg_tmpl.cpp 追加、ダイアログテンプレート操作 i18n.c,h ANSI/UNICODE対応,SetI18DlgStrs(),SetI18MenuStrs()追加 ttlib.c,h ANSI/UNICODE対応 Modified Paths: -------------- trunk/TTProxy/CMakeLists.txt trunk/teraterm/common/dlglib.c trunk/teraterm/common/dlglib.h trunk/teraterm/common/dllutil.cpp trunk/teraterm/common/i18n.c trunk/teraterm/common/i18n.h trunk/teraterm/common/teraterm.h trunk/teraterm/common/ttlib.c trunk/teraterm/common/ttlib.h trunk/teraterm/teraterm/CMakeLists.txt trunk/teraterm/teraterm/clipboar.c trunk/teraterm/teraterm/protodlg.cpp trunk/teraterm/teraterm/teraterm.cpp trunk/teraterm/ttpcmn/CMakeLists.txt trunk/teraterm/ttpcmn/language.c trunk/teraterm/ttpcmn/ttpcmn.def trunk/teraterm/ttpdlg/CMakeLists.txt trunk/teraterm/ttpfile/CMakeLists.txt trunk/teraterm/ttptek/CMakeLists.txt trunk/teraterm/ttptek/tekesc.c trunk/teraterm/ttptek/tekesc.h trunk/teraterm/ttptek/tttek.c trunk/ttpmenu/CMakeLists.txt trunk/ttpmenu/ttpmenu.cpp Added Paths: ----------- trunk/teraterm/common/dlglib_cpp.cpp trunk/teraterm/common/dlglib_tmpl.cpp trunk/teraterm/ttptek/tttek.h -------------- next part -------------- Modified: trunk/TTProxy/CMakeLists.txt =================================================================== --- trunk/TTProxy/CMakeLists.txt 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/TTProxy/CMakeLists.txt 2019-03-25 13:47:32 UTC (rev 7509) @@ -19,6 +19,8 @@ ../teraterm/common/codeconv.cpp ../teraterm/common/dlglib.h ../teraterm/common/dlglib.c + ../teraterm/common/dlglib_cpp.cpp + ../teraterm/common/dlglib_tmpl.cpp ../teraterm/teraterm/ttdialog.h ../teraterm/teraterm/ttfileio.h ../teraterm/teraterm/ttsetup.h Modified: trunk/teraterm/common/dlglib.c =================================================================== --- trunk/teraterm/common/dlglib.c 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/dlglib.c 2019-03-25 13:47:32 UTC (rev 7509) @@ -28,11 +28,15 @@ */ /* Routines for dialog boxes */ +#include "dlglib.h" + +#include "i18n.h" #include <windows.h> -#include "dlglib.h" -#include "i18n.h" // for MAX_UIMSG +#include <assert.h> #include <stdio.h> #include <commctrl.h> +#include <tchar.h> +#include "ttlib.h" // for get_lang_font() void EnableDlgItem(HWND HDlg, int FirstId, int LastId) { @@ -80,8 +84,8 @@ } HControl = GetDlgItem(HDlg, FirstId + R - 1); SendMessage(HControl, BM_SETCHECK, 1, 0); - Style = GetClassLong(HControl, GCL_STYLE); - SetClassLong(HControl, GCL_STYLE, Style | WS_TABSTOP); + Style = GetClassLongPtr(HControl, GCL_STYLE); + SetClassLongPtr(HControl, GCL_STYLE, Style | WS_TABSTOP); } void GetRB(HWND HDlg, LPWORD R, int FirstId, int LastId) @@ -91,7 +95,7 @@ *R = 0; for (i = FirstId ; i <= LastId ; i++) { if (SendDlgItemMessage(HDlg, i, BM_GETCHECK, 0, 0) != 0) { - *R = i - FirstId + 1; + *R = (WORD)(i - FirstId + 1); return; } } @@ -99,10 +103,10 @@ void SetDlgNum(HWND HDlg, int id_Item, LONG Num) { - char Temp[16]; + TCHAR Temp[16]; /* In Win16, SetDlgItemInt can not be used to display long integer. */ - _snprintf_s(Temp,sizeof(Temp),_TRUNCATE,"%d",Num); + _sntprintf_s(Temp, _countof(Temp), _TRUNCATE, _T("%d"), Num); SetDlgItemText(HDlg,id_Item,Temp); } @@ -125,17 +129,17 @@ // 20MB\x88ȏ\xE3\x82̃t\x83@\x83C\x83\x8B\x82\xF0\x83A\x83b\x83v\x83\x8D\x81[\x83h\x82\xB5\x82悤\x82Ƃ\xB7\x82\xE9\x82ƁAbuffer overflow\x82\xC5 // \x97\x8E\x82\xBF\x82\xE9\x96\xE2\x91\xE8\x82ւ̑Ώ\x88\x81B(2005.3.18 yutaka) // cf. http://sourceforge.jp/tracker/index.php?func=detail&aid=5713&group_id=1412&atid=5333 - double Num; - char NumStr[10]; + double Num; + TCHAR NumStr[10]; if (b==0) { - Num = 100.0; + Num = 100.0; } else { - Num = 100.0 * (double)a / (double)b; + Num = 100.0 * (double)a / (double)b; } - _snprintf_s(NumStr,sizeof(NumStr),_TRUNCATE,"%3.1f%%",Num); - SetDlgItemText(HDlg, id_Item, NumStr); + _sntprintf_s(NumStr, _countof(NumStr),_TRUNCATE,_T("%3.1f%%"),Num); + SetDlgItemText(HDlg, id_Item, NumStr); if (id_Progress != 0 && p != NULL && *p >= 0 && (double)*p < Num) { *p = (int)Num; @@ -147,13 +151,13 @@ { static int prev_elapsed; int elapsed, rate; - char buff[64]; + TCHAR buff[64]; elapsed = (GetTickCount() - stime) / 1000; if (elapsed == 0) { prev_elapsed = 0; - SetDlgItemText(HDlg, id_Item, "0:00"); + SetDlgItemText(HDlg, id_Item, _T("0:00")); return; } @@ -164,34 +168,49 @@ rate = bytes / elapsed; if (rate < 1200) { - _snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d:%02d (%dBytes/s)", elapsed / 60, elapsed % 60, rate); + _sntprintf_s(buff, _countof(buff), _TRUNCATE, _T("%d:%02d (%dBytes/s)"), elapsed / 60, elapsed % 60, rate); } else if (rate < 1200000) { - _snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d:%02d (%d.%02dKB/s)", elapsed / 60, elapsed % 60, rate / 1000, rate / 10 % 100); + _sntprintf_s(buff, _countof(buff), _TRUNCATE, _T("%d:%02d (%d.%02dKB/s)"), elapsed / 60, elapsed % 60, rate / 1000, rate / 10 % 100); } else { - _snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d:%02d (%d.%02dMB/s)", elapsed / 60, elapsed % 60, rate / (1000 * 1000), rate / 10000 % 100); + _sntprintf_s(buff, _countof(buff), _TRUNCATE, _T("%d:%02d (%d.%02dMB/s)"), elapsed / 60, elapsed % 60, rate / (1000 * 1000), rate / 10000 % 100); } SetDlgItemText(HDlg, id_Item, buff); } -void SetDropDownList(HWND HDlg, int Id_Item, const TCHAR **List, int nsel) +void SetDropDownList(HWND HDlg, int Id_Item, const char *List[], int nsel) { int i; i = 0; while (List[i] != NULL) { - SendDlgItemMessage(HDlg, Id_Item, CB_ADDSTRING, - 0, (LPARAM)List[i]); + SendDlgItemMessageA(HDlg, Id_Item, CB_ADDSTRING, + 0, (LPARAM)List[i]); i++; } SendDlgItemMessage(HDlg, Id_Item, CB_SETCURSEL,nsel-1,0); } +#if defined(UNICODE) +void SetDropDownListW(HWND HDlg, int Id_Item, const wchar_t *List[], int nsel) +{ + int i; + + i = 0; + while (List[i] != NULL) { + SendDlgItemMessageW(HDlg, Id_Item, CB_ADDSTRING, + 0, (LPARAM)List[i]); + i++; + } + SendDlgItemMessage(HDlg, Id_Item, CB_SETCURSEL,nsel-1,0); +} +#endif + LONG GetCurSel(HWND HDlg, int Id_Item) { - LONG n; + LRESULT n; n = SendDlgItemMessage(HDlg, Id_Item, CB_GETCURSEL, 0, 0); if (n==CB_ERR) { @@ -201,7 +220,7 @@ n++; } - return n; + return (LONG)n; } typedef struct { @@ -218,9 +237,11 @@ static LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { - EditSubclassData *data = (EditSubclassData *)GetWindowLong(dlg, GWLP_USERDATA); + EditSubclassData *data = (EditSubclassData *)GetWindowLongPtr(dlg, GWLP_USERDATA); LRESULT Result; - int max, select, len; + LRESULT select; + LRESULT max; + int len; char *str, *orgstr; switch (msg) { @@ -274,7 +295,7 @@ max++; // '\0' orgstr = str = (char *)malloc(max); if (str != NULL) { - len = GetWindowText(dlg, str, max); + 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); @@ -295,7 +316,7 @@ select = 0; } - SetWindowText(dlg, str); + SetWindowTextA(dlg, str); SendMessage(dlg, EM_SETSEL, select, select); free(orgstr); return 0; @@ -350,29 +371,154 @@ hWndEdit = GetWindow(hWndEdit, GW_CHILD); } data = (EditSubclassData *)malloc(sizeof(EditSubclassData)); - data->OrigProc = (WNDPROC)GetWindowLong(hWndEdit, GWLP_WNDPROC); - data->OrigUser = (LONG_PTR)GetWindowLong(hWndEdit, GWLP_USERDATA); + data->OrigProc = (WNDPROC)GetWindowLongPtr(hWndEdit, GWLP_WNDPROC); + data->OrigUser = (LONG_PTR)GetWindowLongPtr(hWndEdit, GWLP_USERDATA); data->ComboBox = ComboBox; - SetWindowLongPtr(hWndEdit, GWL_WNDPROC, (LONG_PTR)HostnameEditProc); + SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)HostnameEditProc); SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)data); } -void SetDlgTexts(HWND hDlgWnd, const DlgTextInfo *infos, int infoCount, const char *UILanguageFile) +typedef struct { + BOOL found; + const char *face; + BYTE charset; +} IsExistFontInfoA; + +int CALLBACK IsExistFontSubA( + ENUMLOGFONTA* lpelf, NEWTEXTMETRICA* lpntm, + int nFontType, LPARAM lParam) { - int i; - for (i = 0 ; i < infoCount; i++) { - char *key = infos[i].key; - char uimsg[MAX_UIMSG]; - get_lang_msg(key, uimsg, sizeof(uimsg), "", UILanguageFile); - if (uimsg[0] != '\0') { - const int nIDDlgItem = infos[i].nIDDlgItem; - if (nIDDlgItem == 0) { - SetWindowText(hDlgWnd, uimsg); - } else { - SetDlgItemText(hDlgWnd, nIDDlgItem, uimsg); + IsExistFontInfoA *info = (IsExistFontInfoA *)lParam; + (void)lpntm; + if (nFontType != DEVICE_FONTTYPE && + _stricmp(lpelf->elfLogFont.lfFaceName, info->face) == 0 && + lpelf->elfLogFont.lfCharSet == info->charset) + { + info->found = TRUE; + return 0; + } + return 1; +} + +/** + * IsExistFont + * \x83t\x83H\x83\x93\x83g\x82\xAA\x91\xB6\x8D݂\xB5\x82Ă\xA2\x82邩\x83`\x83F\x83b\x83N\x82\xB7\x82\xE9 + * + * @param[in] face \x83t\x83H\x83\x93\x83g\x96\xBC(\x83t\x83@\x83C\x83\x8B\x96\xBC\x82ł͂Ȃ\xA2) + * @param[in] charset SHIFTJIS_CHARSET\x82Ȃ\xC7 + * @param[in] strict TRUE \x83t\x83H\x83\x93\x83g\x83\x8A\x83\x93\x83N\x82͌\x9F\x8D\xF5\x82Ɋ܂߂Ȃ\xA2 + * FALSE \x83t\x83H\x83\x93\x83g\x83\x8A\x83\x93\x83N\x82\xE0\x8C\x9F\x8D\xF5\x82Ɋ܂߂\xE9 + * @retval FALSE \x83t\x83H\x83\x93\x83g\x82͂\xB5\x82Ȃ\xA2 + * @retval TRUE \x83t\x83H\x83\x93\x83g\x82͑\xB6\x8D݂\xB7\x82\xE9 + * + * strict = FALSE\x8E\x9E\x81A\x91\xB6\x8D݂\xB5\x82Ȃ\xA2\x83t\x83H\x83\x93\x83g\x82ł\xE0\x95\\x8E\xA6\x82ł\xAB\x82\xE9\x82Ȃ\xE7TRUE\x82\xAA\x95Ԃ\xE9 + */ +BOOL IsExistFontA(const char *face, BYTE charset, BOOL strict) +{ + HDC hDC = GetDC(NULL); + LOGFONTA lf; + IsExistFontInfoA info; + memset(&lf, 0, sizeof(lf)); + lf.lfCharSet = !strict ? DEFAULT_CHARSET : charset; + // \x81\xAADEFAULT_CHARSET\x82Ƃ\xB7\x82\xE9\x82ƃt\x83H\x83\x93\x83g\x83\x8A\x83\x93\x83N\x82\xE0\x97L\x8C\xF8\x82ɂȂ\xE9\x82悤\x82\xBE + lf.lfPitchAndFamily = 0; + info.found = FALSE; + info.face = face; + info.charset = charset; + EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)IsExistFontSubA, (LPARAM)&info, 0); + ReleaseDC(NULL, hDC); + return info.found; +} + +/** + * \x83_\x83C\x83A\x83\x8D\x83O\x83t\x83H\x83\x93\x83g\x82\xF0\x8E擾\x82\xB7\x82\xE9 + * \x83G\x83\x89\x81[\x82͔\xAD\x90\xB6\x82\xB5\x82Ȃ\xA2 + */ +void GetMessageboxFont(LOGFONT *logfont) +{ + NONCLIENTMETRICS nci; + const int st_size = CCSIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont); + BOOL r; + + memset(&nci, 0, sizeof(nci)); + nci.cbSize = st_size; + r = SystemParametersInfo(SPI_GETNONCLIENTMETRICS, st_size, &nci, 0); + assert(r == TRUE); + *logfont = nci.lfStatusFont; +} + +/** + * \x8Eg\x97p\x82\xB7\x82\xE9\x83_\x83C\x83A\x83\x8D\x83O\x83t\x83H\x83\x93\x83g\x82\xF0\x8C\x88\x92肷\x82\xE9 + */ +void SetDialogFont(const char *SetupFName, + const char *UILanguageFile, const char *Section) +{ + // teraterm.ini\x82̎w\x92\xE8 + if (SetupFName != NULL) { + LOGFONTA logfont; + BOOL result; + result = GetI18nLogfont("Tera Term", "DlgFont", &logfont, 0, SetupFName); + if (result == TRUE) { + result = IsExistFontA(logfont.lfFaceName, logfont.lfCharSet, TRUE); + if (result == TRUE) { + TTSetDlgFontA(logfont.lfFaceName, logfont.lfHeight, logfont.lfCharSet); + return; } } } + + // .lng\x82̎w\x92\xE8 + if (UILanguageFile != NULL) { + static const char *dlg_font_keys[] = { + "DLG_FONT", + "DLG_TAHOMA_FONT", + "DLG_SYSTEM_FONT", + }; + BOOL result = FALSE; + LOGFONTA logfont; + size_t i; + if (Section != NULL) { + for (i = 0; i < _countof(dlg_font_keys); i++) { + result = GetI18nLogfont(Section, dlg_font_keys[i], &logfont, 0, UILanguageFile); + if (result == FALSE) { + continue; + } + if (logfont.lfFaceName[0] == '\0') { + break; + } + if (IsExistFontA(logfont.lfFaceName, logfont.lfCharSet, TRUE)) { + break; + } + } + } + if (result == FALSE) { + for (i = 0; i < _countof(dlg_font_keys); i++) { + result = GetI18nLogfont("Tera Term", dlg_font_keys[i], &logfont, 0, UILanguageFile); + if (result == FALSE) { + continue; + } + if (logfont.lfFaceName[0] == '\0') { + break; + } + if (IsExistFontA(logfont.lfFaceName, logfont.lfCharSet, TRUE)) { + break; + } + } + } + if (result == TRUE) { + TTSetDlgFontA(logfont.lfFaceName, logfont.lfHeight, logfont.lfCharSet); + return; + } + } + + // ini,lng\x82Ŏw\x92肳\x82ꂽ\x83t\x83H\x83\x93\x83g\x82\xAA\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xA9\x82\xC1\x82\xBD\x82Ƃ\xAB\x81A + // \x95\xB6\x8E\x9A\x89\xBB\x82\xAF\x82Ő\xB3\x82\xB5\x82\xAD\x95\\x8E\xA6\x82\xB3\x82\xEA\x82Ȃ\xA2\x8E\x96\x91ԂƂȂ\xE9 + // messagebox()\x82̃t\x83H\x83\x93\x83g\x82\xF0\x82Ƃ肠\x82\xA6\x82\xB8\x91I\x91\xF0\x82\xB5\x82Ă\xA8\x82\xAD + { + LOGFONT logfont; + GetMessageboxFont(&logfont); + TTSetDlgFont(logfont.lfFaceName, logfont.lfHeight, logfont.lfCharSet); + } } HFONT SetDlgFonts(HWND hDlg, const int nIDDlgItems[], int nIDDlgItemCount, Modified: trunk/teraterm/common/dlglib.h =================================================================== --- trunk/teraterm/common/dlglib.h 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/dlglib.h 2019-03-25 13:47:32 UTC (rev 7509) @@ -27,7 +27,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* Routines for dialog boxes */ +#pragma once + +#include <windows.h> +#include "i18n.h" + + /* Routines for dialog boxes */ #ifdef __cplusplus extern "C" { #endif @@ -40,18 +45,59 @@ void SetDlgNum(HWND HDlg, int id_Item, LONG Num); void SetDlgPercent(HWND HDlg, int id_Item, int id_Progress, LONG a, LONG b, int *prog); void SetDlgTime(HWND HDlg, int id_Item, DWORD elapsed, int bytes); -void SetDropDownList(HWND HDlg, int Id_Item, const TCHAR **List, int nsel); +void SetDropDownList(HWND HDlg, int Id_Item, const char *List[], int nsel); +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); -typedef struct { - int nIDDlgItem; - char *key; -} DlgTextInfo; -void SetDlgTexts(HWND hDlgWnd, const DlgTextInfo *infos, int infoCount, const char *UILanguageFile); + +#if defined(_UNICODE) +#define SetDropDownListT(p1, p2, p3, p4) SetDropDownListW(p1, p2, p3, p4) +#else +#define SetDropDownListT(p1, p2, p3, p4) SetDropDownList(p1, p2, p3, p4) +#endif + +void TTSetDlgFontA(const char *face, int height, int charset); +void TTSetDlgFontW(const wchar_t *face, int height, int charset); +const wchar_t *TTGetClassName(const DLGTEMPLATE *DlgTempl); +DLGTEMPLATE *TTGetDlgTemplate(HINSTANCE hInst, LPCTSTR lpTemplateName); +DLGTEMPLATE *TTGetNewDlgTemplate( + HINSTANCE hInst, const DLGTEMPLATE *src, + size_t *PrevTemplSize, size_t *NewTemplSize); +BOOL TTEndDialog(HWND hDlgWnd, INT_PTR nResult); +HWND TTCreateDialogIndirectParam( + HINSTANCE hInstance, + LPCDLGTEMPLATE lpTemplate, + HWND hWndParent, + DLGPROC lpDialogFunc, + LPARAM lParamInit); +HWND TTCreateDialog( + HINSTANCE hInstance, + LPCTSTR lpTemplateName, + HWND hWndParent, + DLGPROC lpDialogFunc); +INT_PTR TTDialogBoxParam( + HINSTANCE hInstance, + LPCTSTR lpTemplateName, + HWND hWndParent, + DLGPROC lpDialogFunc, + LPARAM lParamInit); +INT_PTR TTDialogBox( + HINSTANCE hInstance, + LPCTSTR lpTemplateName, + HWND hWndParent, + DLGPROC lpDialogFunc); +void SetDialogFont(const char *SetupFName, const char *UILanguageFile, const char *Section); HFONT SetDlgFonts(HWND hDlg, const int nIDDlgItems[], int nIDDlgItemCount, const char *UILanguageFile, PCHAR key); +BOOL IsExistFontA(const char *face, BYTE charset, BOOL strict); +#if defined(_UNICODE) +#define TTSetDlgFont(p1,p2,p3) TTSetDlgFontW(p1,p2,p3) +#else +#define TTSetDlgFont(p1,p2,p3) TTSetDlgFontA(p1,p2,p3) +#endif + #ifdef __cplusplus } #endif Added: trunk/teraterm/common/dlglib_cpp.cpp =================================================================== --- trunk/teraterm/common/dlglib_cpp.cpp (rev 0) +++ trunk/teraterm/common/dlglib_cpp.cpp 2019-03-25 13:47:32 UTC (rev 7509) @@ -0,0 +1,242 @@ +/* + * (C) 2005-2018 TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Routines for dialog boxes */ + +#include <windows.h> +#include "dlglib.h" + +// \x83_\x83C\x83A\x83\x8D\x83O\x83\x82\x81[\x83_\x83\x8B\x8F\xF3\x91Ԃ̎\x9E\x81AOnIdle()\x82\xF0\x8E\xC0\x8Ds\x82\xB7\x82\xE9 +//#define ENABLE_CALL_IDLE_MODAL 1 + +extern BOOL CallOnIdle(LONG lCount); + +typedef struct { + DLGPROC OrigProc; // Dialog proc + LONG_PTR OrigUser; // DWLP_USER + LPARAM ParamInit; + int DlgResult; + bool EndDialogFlag; +} TTDialogData; + +static TTDialogData *TTDialogTmpData; + +#if ENABLE_CALL_IDLE_MODAL +static int TTDoModal(HWND hDlgWnd) +{ + LONG lIdleCount = 0; + MSG Msg; + TTDialogData *data = (TTDialogData *)GetWindowLongPtr(hDlgWnd, DWLP_USER); + + for (;;) + { + if (!IsWindow(hDlgWnd)) { + // \x83E\x83C\x83\x93\x83h\x83E\x82\xAA\x95\xB6\x82\xE7\x82ꂽ + return IDCANCEL; + } +#if defined(_DEBUG) + if (!IsWindowVisible(hDlgWnd)) { + // \x8C\xEB\x82\xC1\x82\xC4EndDialog()\x82\xAA\x8Eg\x82\xED\x82ꂽ? -> TTEndDialog()\x82\xF0\x8Eg\x82\xA4\x82\xB1\x82\xC6 + ::ShowWindow(hDlgWnd, SW_SHOWNORMAL); + } +#endif + if (data->EndDialogFlag) { + // TTEndDialog()\x82\xAA\x8CĂꂽ + return data->DlgResult; + } + + if(!::PeekMessage(&Msg, NULL, NULL, NULL, PM_NOREMOVE)) + { + // \x83\x81\x83b\x83Z\x81[\x83W\x82\xAA\x82Ȃ\xA2 + // OnIdel() \x82\xF0\x8F\x88\x97\x9D\x82\xB7\x82\xE9 + if (!CallOnIdle(lIdleCount++)) { + // Idle\x8F\x88\x97\x9D\x82\xAA\x82Ȃ\xAD\x82Ȃ\xC1\x82\xBD + lIdleCount = 0; + Sleep(10); + } + continue; + } + else + { + // \x83\x81\x83b\x83Z\x81[\x83W\x82\xAA\x82\xA0\x82\xE9 + + // pump message + BOOL quit = !::GetMessage(&Msg, NULL, NULL, NULL); + if (quit) { + // QM_QUIT + PostQuitMessage(0); + return IDCANCEL; + } + + if (!::IsDialogMessage(hDlgWnd, &Msg)) { + // \x83_\x83C\x83A\x83\x8D\x83O\x88ȊO\x82̏\x88\x97\x9D + ::TranslateMessage(&Msg); + ::DispatchMessage(&Msg); + } + } + } + + // \x82\xB1\x82\xB1\x82ɂ͗\x88\x82Ȃ\xA2 + return IDOK; +} +#endif + +static INT_PTR CALLBACK TTDialogProc( + HWND hDlgWnd, UINT msg, + WPARAM wParam, LPARAM lParam) +{ + TTDialogData *data = (TTDialogData *)GetWindowLongPtr(hDlgWnd, DWLP_USER); + if (msg == WM_INITDIALOG) { + data = (TTDialogData *)lParam; + SetWindowLongPtr(hDlgWnd, DWLP_USER, (LONG_PTR)lParam); + lParam = data->ParamInit; + } + + if (data == NULL) { + // WM_INITDIALOG\x82\xE6\x82\xE8\x82\xE0\x91O\x82͐ݒ肳\x82\xEA\x82Ă\xA2\x82Ȃ\xA2 + data = TTDialogTmpData; + } else { + // TTEndDialog()\x82\xAA\x8CĂꂽ\x82Ƃ\xAB\x81ADWLP_USER \x82\xAA\x8EQ\x8FƂł\xAB\x82Ȃ\xA2 + TTDialogTmpData = data; + } + + SetWindowLongPtr(hDlgWnd, DWLP_DLGPROC, (LONG_PTR)data->OrigProc); + SetWindowLongPtr(hDlgWnd, DWLP_USER, (LONG_PTR)data->OrigUser); + LRESULT Result = data->OrigProc(hDlgWnd, msg, wParam, lParam); + data->OrigProc = (DLGPROC)GetWindowLongPtr(hDlgWnd, DWLP_DLGPROC); + data->OrigUser = GetWindowLongPtr(hDlgWnd, DWLP_USER); + SetWindowLongPtr(hDlgWnd, DWLP_DLGPROC, (LONG_PTR)TTDialogProc); + SetWindowLongPtr(hDlgWnd, DWLP_USER, (LONG_PTR)data); + + if (msg == WM_NCDESTROY) { + SetWindowLongPtr(hDlgWnd, DWLP_USER, 0); + free(data); + } + + return Result; +} + +/** + * EndDialog() \x8C݊\xB7\x8A\x94 + */ +BOOL TTEndDialog(HWND hDlgWnd, INT_PTR nResult) +{ +#if ENABLE_CALL_IDLE_MODAL + TTDialogData *data = TTDialogTmpData; + data->DlgResult = nResult; + data->EndDialogFlag = true; + return TRUE; +#else + return EndDialog(hDlgWnd, nResult); +#endif +} + +/** + * CreateDialogIndirectParam() \x8C݊\xB7\x8A\x94 + */ +HWND TTCreateDialogIndirectParam( + HINSTANCE hInstance, + LPCTSTR lpTemplateName, + HWND hWndParent, // \x83I\x81[\x83i\x81[\x83E\x83B\x83\x93\x83h\x83E\x82̃n\x83\x93\x83h\x83\x8B + DLGPROC lpDialogFunc, // \x83_\x83C\x83A\x83\x8D\x83O\x83{\x83b\x83N\x83X\x83v\x83\x8D\x83V\x81[\x83W\x83\x83\x82ւ̃|\x83C\x83\x93\x83^ + LPARAM lParamInit) // \x8F\x89\x8A\xFA\x89\xBB\x92l +{ + TTDialogData *data = (TTDialogData *)malloc(sizeof(TTDialogData)); + data->OrigProc = lpDialogFunc; + data->OrigUser = 0; + data->ParamInit = lParamInit; + data->EndDialogFlag = false; + data->DlgResult = 0; + DLGTEMPLATE *lpTemplate = TTGetDlgTemplate(hInstance, lpTemplateName); + TTDialogTmpData = data; + HWND hDlgWnd = CreateDialogIndirectParam( + hInstance, lpTemplate, hWndParent, TTDialogProc, (LPARAM)data); + TTDialogTmpData = NULL; + ShowWindow(hDlgWnd, SW_SHOW); + UpdateWindow(hDlgWnd); + free(lpTemplate); + return hDlgWnd; +} + +/** + * CreateDialog() \x8C݊\xB7\x8A\x94 + */ +HWND TTCreateDialog( + HINSTANCE hInstance, + LPCTSTR lpTemplateName, + HWND hWndParent, + DLGPROC lpDialogFunc) +{ + return TTCreateDialogIndirectParam(hInstance, lpTemplateName, + hWndParent, lpDialogFunc, NULL); +} + +/** + * DialogBoxParam() \x8C݊\xB7\x8A\x94 + * EndDialog()\x82ł͂Ȃ\xAD\x81ATTEndDialog()\x82\xF0\x8Eg\x97p\x82\xB7\x82邱\x82\xC6 + */ +INT_PTR TTDialogBoxParam( + HINSTANCE hInstance, + LPCTSTR lpTemplateName, + HWND hWndParent, // \x83I\x81[\x83i\x81[\x83E\x83B\x83\x93\x83h\x83E\x82̃n\x83\x93\x83h\x83\x8B + DLGPROC lpDialogFunc, // \x83_\x83C\x83A\x83\x8D\x83O\x83{\x83b\x83N\x83X\x83v\x83\x8D\x83V\x81[\x83W\x83\x83\x82ւ̃|\x83C\x83\x93\x83^ + LPARAM lParamInit) // \x8F\x89\x8A\xFA\x89\xBB\x92l +{ +#if ENABLE_CALL_IDLE_MODAL + HWND hDlgWnd = TTCreateDialogIndirectParam( + hInstance, lpTemplateName, + hWndParent, lpDialogFunc, lParamInit); + EnableWindow(hWndParent, FALSE); + int DlgResult = TTDoModal(hDlgWnd); + ::DestroyWindow(hDlgWnd); + EnableWindow(hWndParent, TRUE); + return DlgResult; +#else + DLGTEMPLATE *lpTemplate = TTGetDlgTemplate(hInstance, lpTemplateName); + INT_PTR DlgResult = DialogBoxIndirectParam( + hInstance, lpTemplate, hWndParent, + lpDialogFunc, lParamInit); + free(lpTemplate); + return DlgResult; +#endif +} + +/** + * DialogBoxParam() \x8C݊\xB7\x8A\x94 + * EndDialog()\x82ł͂Ȃ\xAD\x81ATTEndDialog()\x82\xF0\x8Eg\x97p\x82\xB7\x82邱\x82\xC6 + */ +INT_PTR TTDialogBox( + HINSTANCE hInstance, + LPCTSTR lpTemplateName, + HWND hWndParent, + DLGPROC lpDialogFunc) +{ + return TTDialogBoxParam( + hInstance, lpTemplateName, + hWndParent, lpDialogFunc, (LPARAM)NULL); +} Added: trunk/teraterm/common/dlglib_tmpl.cpp =================================================================== --- trunk/teraterm/common/dlglib_tmpl.cpp (rev 0) +++ trunk/teraterm/common/dlglib_tmpl.cpp 2019-03-25 13:47:32 UTC (rev 7509) @@ -0,0 +1,510 @@ +/* + * (C) 2005-2018 TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Routines for dialog boxes */ + +#include "dlglib.h" + +#include <wchar.h> +#include <assert.h> +#include <crtdbg.h> + +#ifdef _DEBUG +#define malloc(l) _malloc_dbg((l), _NORMAL_BLOCK, __FILE__, __LINE__) +#define free(p) _free_dbg((p), _NORMAL_BLOCK, __FILE__, __LINE__) +#endif + +//#define _countof(ary) (sizeof(ary)/sizeof(ary[0])) + +// https://docs.microsoft.com/ja-jp/windows/desktop/dlgbox/dlgtemplateex +// https://www.pg-fl.jp/program/tips/dlgmem.htm +#pragma pack(push, 1) +typedef struct +{ + WORD dlgVer; + WORD signature; + DWORD helpID; + DWORD exStyle; + DWORD style; + WORD cDlgItems; + short x; + short y; + short cx; + short cy; + + // sz_Or_Ord menu; // name or ordinal of a menu resource + // sz_Or_Ord windowClass; // name or ordinal of a window class + // WCHAR title[N]; + // WORD pointsize; // only if DS_SETFONT is set + // WORD weight; // only if DS_SETFONT is set + // BYTE italic; // only if DS_SETFONT is set + // BYTE charset; // only if DS_SETFONT is set + // WCHAR typeface[stringLen]; // only if DS_SETFONT is set + + // PAD + + // DLGITEMTEMPLATEEX controls[cDlgItems]; +} DLGTEMPLATEEX; + +typedef struct +{ + DWORD helpID; + DWORD exStyle; + DWORD style; + short x; + short y; + short cx; + short cy; + DWORD id; + + // sz_Or_Ord windowClass; // name or ordinal of a window class + // sz_Or_Ord title; // title string or ordinal of a resource + // WORD extraCount; // bytes following creation data +} DLGITEMTEMPLATEEX; +#pragma pack(pop) + +#if 0 // !defined(_MSC_VER) +static inline errno_t wcscpy_s( + wchar_t *dest, + size_t dest_size, + const wchar_t *src) +{ + wcscpy(dest, src); + return 0; +} +#endif + +static size_t CopySz(const WORD *src, WORD *dest) +{ + size_t size = 0; + do { + if (dest != NULL) { + *dest++ = *src; + } + size++; + } while (*src++ != 0); + return size; +} + +static size_t CopySzOrOrd(const WORD *src, WORD *dest) +{ + size_t size; + if (*src == 0x0000) { + // 0x0000 \x82̂Ƃ\xAB\x81A\x82Ȃɂ\xE0\x82Ȃ\xA2 + if (dest != NULL) { + *dest = *src; + } + size = 1; + } else if (*src == 0xffff) { + // 0xffff \x82̂Ƃ\xAB\x81A1WORD\x82̃f\x81[\x83^ + if (dest != NULL) { + *dest++ = *src++; + *dest++ = *src++; + } + size = 2; + } else { + // \x88ȊO\x82\xCDwchar_t\x82̕\xB6\x8E\x9A\x97\xF1 + return CopySz(src, dest); + } + return size; +} + +static size_t CopyDlgItem(const WORD *src, WORD *dest) +{ + size_t size = sizeof(DLGITEMTEMPLATE) / sizeof(WORD); + if (dest != NULL) { + *(DLGITEMTEMPLATE *)dest = *(DLGITEMTEMPLATE *)src; + dest += size; + } + src += size; + + size_t t; + t = CopySzOrOrd(src, dest); // windowClass + size += t; + src += t; if (dest != NULL) dest += t; + t = CopySzOrOrd(src, dest); // title + size += t; + src += t; if (dest != NULL) dest += t; + const WORD extraCount = *src++; + size++; + if (dest != NULL) { + *dest++ = extraCount; + } + if (extraCount != 0) { + size += extraCount; + if (dest != NULL) { + memcpy(dest, src, extraCount * sizeof(WORD)); + dest += extraCount; + } + src += extraCount; + } + + size = (size + 1) & ~1; + return size; +} + +/** + * drc \x83_\x83C\x83A\x83\x8D\x83O\x83\x8A\x83\\x81[\x83X\x82ւ̃|\x83C\x83\x93\x83^ + * dest \x83R\x83s\x81[\x90\xE6(NULL\x82̂Ƃ\xAB\x83R\x83s\x81[\x82\xB5\x82Ȃ\xA2) + * logfont \x90ݒ肷\x82\xE9\x83t\x83H\x83\x93\x83g\x8F\xEE\x95\xF1(\x82\xBD\x82\xBE\x82\xB5\x81Adest_v\x82\xAANULL\x82̎\x9E\x82͎擾) + * NULL\x82̂Ƃ\xAB\x90ݒ\xE8,\x8E擾\x82\xB5\x82Ȃ\xA2 + */ +static size_t CopyDlgTemplate( + const WORD *src_v, + WORD *dest_v, + LOGFONTW *logfont) +{ + const WORD *src = (const WORD *)src_v; + WORD *dest = (WORD *)dest_v; + size_t size = sizeof(DLGTEMPLATE) / sizeof(WORD); + const DLGTEMPLATE *dlg = (DLGTEMPLATE *)src; + if (dest != NULL) { + *(DLGTEMPLATE *)dest = *dlg; + dest += size; + } + src += size; + + size_t t; + t = CopySzOrOrd(src, dest); // menu + size += t; + src += t; if (dest != NULL) dest += t; + t = CopySzOrOrd(src, dest); // windowClass + size += t; + src += t; if (dest != NULL) dest += t; + t = CopySz(src, dest); // title + size += t; + src += t; if (dest != NULL) dest += t; + size_t dsize = 0; + if (dlg->style & DS_SETFONT) { + if (dest == NULL) { + // \x8E擾 + if (logfont != NULL) { + memset(logfont, 0, sizeof(*logfont)); + logfont->lfHeight = *src++; + t = CopySz(src, (WORD *)(&logfont->lfFaceName[0])); + } else { + src++; + t = CopySz(src, NULL); + } + size += t + 1; + } else { + // \x83Z\x83b\x83g + if (logfont != NULL) { + *dest++ = (WORD)logfont->lfHeight; + src += 1; + t = CopySz((WORD *)(&logfont->lfFaceName[0]), dest); + dest += t; + dsize = size + t + 1; + t = CopySz(src, NULL); + size += t + 1; + } else { + *dest++ = *src++; + t = CopySz(src, dest); + size += t + 1; + dsize = size; + } + } + } + + size = (size + 1) & ~1; + src = ((const WORD *)src_v) + size; + if (dest != NULL) { + dsize = (dsize + 1) & ~1; + dest = ((WORD *)dest_v) + dsize; + size = dsize; + } + for (int i = 0; i < dlg->cdit; i++) { + t = CopyDlgItem(src, dest); + src += t; if (dest != NULL) dest += t; + size += t; + } + + return size * sizeof(WORD); +} + +static size_t CopyDlgItemEx(const WORD *src, WORD *dest) +{ + size_t size = sizeof(DLGITEMTEMPLATEEX) / sizeof(WORD); + if (dest != NULL) { + *(DLGITEMTEMPLATEEX *)dest = *(DLGITEMTEMPLATEEX *)src; + dest += size; + } + src += size; + + size_t t; + t = CopySzOrOrd(src, dest); // windowClass + size += t; + src += t; if (dest != NULL) dest += t; + t = CopySzOrOrd(src, dest); // title + size += t; + src += t; if (dest != NULL) dest += t; + const WORD extraCount = *src++; + size++; + if (dest != NULL) { + *dest++ = extraCount; + } + if (extraCount != 0) { + size += extraCount; + if (dest != NULL) { + memcpy(dest, src, extraCount * sizeof(WORD)); + dest += extraCount; + } + src += extraCount; + } + + size = (size + 1) & ~1; + return size; +} + +/** + * drc_v \x83_\x83C\x83A\x83\x8D\x83O\x83\x8A\x83\\x81[\x83X\x82ւ̃|\x83C\x83\x93\x83^ + * dest_v \x83R\x83s\x81[\x90\xE6(NULL\x82̂Ƃ\xAB\x83R\x83s\x81[\x82\xB5\x82Ȃ\xA2) + * logfont \x90ݒ肷\x82\xE9\x83t\x83H\x83\x93\x83g\x8F\xEE\x95\xF1(\x82\xBD\x82\xBE\x82\xB5\x81Adest_v\x82\xAANULL\x82̎\x9E\x82͎擾) + * NULL\x82̂Ƃ\xAB\x90ݒ\xE8,\x8E擾\x82\xB5\x82Ȃ\xA2 + */ +static size_t CopyDlgTemplateEx( + const DLGTEMPLATE *src_v, + DLGTEMPLATE *dest_v, + LOGFONTW *logfont) +{ + const WORD *src = (const WORD *)src_v; + WORD *dest = (WORD *)dest_v; + if (*src != 1) { + return CopyDlgTemplate(src, dest, logfont); + } + // version 1 + size_t size = sizeof(DLGTEMPLATEEX) / sizeof(WORD); + const DLGTEMPLATEEX *dlg = (DLGTEMPLATEEX *)src; + if (dest != NULL) { + *(DLGTEMPLATEEX *)dest = *dlg; + dest += size; + } + src += size; + + size_t t; + t = CopySzOrOrd(src, dest); // menu + size += t; + src += t; if (dest != NULL) dest += t; + t = CopySzOrOrd(src, dest); // windowClass + size += t; + src += t; if (dest != NULL) dest += t; + t = CopySz(src, dest); // title + size += t; + src += t; if (dest != NULL) dest += t; + size_t dsize = 0; + if (dlg->style & DS_SETFONT) { + if (dest == NULL) { + // \x8E擾 + if (logfont != NULL) { + memset(logfont, 0, sizeof(*logfont)); + logfont->lfHeight = *src++; + logfont->lfWeight = *src++; + logfont->lfItalic = *((BYTE *)src); + logfont->lfCharSet = *(((BYTE *)src)+1); + src++; + t = CopySz(src, (WORD *)(&logfont->lfFaceName[0])); + } else { + src++; + src++; + src++; + t = CopySz(src, NULL); + } + size += t + 3; + } else { + // \x83Z\x83b\x83g + if (logfont != NULL) { + *dest++ = (WORD)logfont->lfHeight; + *dest++ = (WORD)logfont->lfWeight; + *((BYTE *)dest) = logfont->lfItalic; + *(((BYTE *)dest)+1) = logfont->lfCharSet; + dest++; + src += 3; + t = CopySz((WORD *)(&logfont->lfFaceName[0]), dest); + dest += t; + dsize = size + t + 3; + t = CopySz(src, NULL); + size += t + 3; + } else { + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + t = CopySz(src, dest); + size += t + 3; + dsize = size; + } + } + } + + size = (size + 1) & ~1; + src = ((const WORD *)src_v) + size; + if (dest != NULL) { + dsize = (dsize + 1) & ~1; + dest = ((WORD *)dest_v) + dsize; + size = dsize; + } + for (int i = 0; i < dlg->cDlgItems; i++) { + t = CopyDlgItemEx(src, dest); + src += t; if (dest != NULL) dest += t; + size += t; + } + + return size * sizeof(WORD); +} + +static DLGTEMPLATE *GetDlgTemplate( + const DLGTEMPLATE *src, + const WCHAR *FontFaceName, LONG FontHeight, BYTE FontCharSet, + size_t *PrevTemplSize, size_t *NewTemplSize) +{ + LOGFONTW logfont; + const size_t prev_size = CopyDlgTemplateEx(src, NULL, &logfont); + DLGTEMPLATE *dest; + size_t new_size = 0; + if (FontFaceName == NULL || FontFaceName[0] == '\0') { + // simple copy + dest = (DLGTEMPLATE *)malloc(prev_size); + CopyDlgTemplateEx(src, dest, NULL); + new_size = prev_size; + } else { + // copy with replacing font + int size_namediff = + wcslen(FontFaceName) - wcslen(logfont.lfFaceName); + size_namediff *= sizeof(WCHAR); + size_namediff += 3; // \x83e\x83L\x83X\x83g\x81A\x83t\x83H\x83\x93\x83g\x96\xBC\x92\xB7\x82\xC5align\x82\xAA\x95ω\xBB\x82\xB7\x82\xE9 + size_t new_size_forcast = prev_size + size_namediff; + new_size_forcast = (new_size_forcast + 3) & ~3; + dest = (DLGTEMPLATE *)malloc(new_size_forcast); + logfont.lfCharSet = FontCharSet; + logfont.lfHeight = FontHeight; + wcscpy_s(logfont.lfFaceName, _countof(logfont.lfFaceName), + FontFaceName); + new_size = CopyDlgTemplateEx(src, dest, &logfont); + assert(new_size <= new_size_forcast); + } + + if (PrevTemplSize != NULL) { + *PrevTemplSize = prev_size; + } + if (NewTemplSize != NULL) { + *NewTemplSize = new_size; + } + return dest; +} + +static DLGTEMPLATE *GetDlgTemplate( + HINSTANCE hInst, LPCTSTR lpTemplateName, + const WCHAR *FontFaceName, LONG FontHeight, BYTE FontCharSet, + size_t *PrevTemplSize, size_t *NewTemplSize) +{ + HRSRC hResource = ::FindResource(hInst, lpTemplateName, RT_DIALOG); + assert(hResource != NULL); + HANDLE hDlgTemplate = ::LoadResource(hInst, hResource); + const DLGTEMPLATE *src = (DLGTEMPLATE *)::LockResource(hDlgTemplate); + + DLGTEMPLATE *dest = GetDlgTemplate( + src, + FontFaceName, FontHeight, FontCharSet, + PrevTemplSize, NewTemplSize); + + ::FreeResource(hDlgTemplate); + + return dest; +} + +static wchar_t FontFaceName[LF_FACESIZE]; +static LONG FontHeight; +static BYTE FontCharSet; + +void TTSetDlgFontW(const wchar_t *face, int height, int charset) +{ + if (face != NULL) { + wcscpy_s(FontFaceName, face); + } else { + FontFaceName[0] = L'\0'; + } + FontHeight = height; + FontCharSet = (BYTE)charset; +} + +void TTSetDlgFontA(const char *face, int height, int charset) +{ + if (face != NULL) { + MultiByteToWideChar(CP_ACP, 0, face, -1, FontFaceName, LF_FACESIZE); + } else { + FontFaceName[0] = L'\0'; + } + FontHeight = height; + FontCharSet = (BYTE)charset; +} + +DLGTEMPLATE *TTGetNewDlgTemplate( + HINSTANCE hInst, const DLGTEMPLATE *src, + size_t *PrevTemplSize, size_t *NewTemplSize) +{ + (void)hInst; + DLGTEMPLATE *DlgTemplate = + GetDlgTemplate(src, + FontFaceName, FontHeight, FontCharSet, + PrevTemplSize, NewTemplSize); + + return DlgTemplate; +} + +DLGTEMPLATE *TTGetDlgTemplate(HINSTANCE hInst, LPCTSTR lpTemplateName) +{ + DLGTEMPLATE *DlgTemplate = + GetDlgTemplate(hInst, lpTemplateName, + FontFaceName, FontHeight, FontCharSet, + NULL, NULL); + return DlgTemplate; +} + +/* + * \x83_\x83C\x83A\x83\x8D\x83O\x83e\x83\x93\x83v\x83\x8C\x81[\x83g\x82̃N\x83\x89\x83X\x96\xBC\x8E擾 + * @retval \x83N\x83\x89\x83X\x95\xB6\x8E\x9A\x97\xF1 + * @retval NULL \x83N\x83\x89\x83X\x82Ȃ\xB5 + */ +const wchar_t *TTGetClassName(const DLGTEMPLATE *DlgTempl) +{ + const WORD *src = (const WORD *)DlgTempl; + if (*src != 1) { + // DLGTEMPLATE + src += sizeof(DLGTEMPLATE) / sizeof(WORD); + } else { + // DLGTEMPLATEEX + src += sizeof(DLGTEMPLATEEX) / sizeof(WORD); + } + size_t t = CopySzOrOrd(src, NULL); // menu + src += t; + + if (*src == L'\0') { + // no class name + return NULL; + } + return (wchar_t *)src; +} Modified: trunk/teraterm/common/dllutil.cpp =================================================================== --- trunk/teraterm/common/dllutil.cpp 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/dllutil.cpp 2019-03-25 13:47:32 UTC (rev 7509) @@ -162,7 +162,7 @@ *pFunc = NULL; return ERROR_FILE_NOT_FOUND; } else { - *pFunc = GetProcAddress(hDll, ApiName); + *pFunc = (void *)GetProcAddress(hDll, ApiName); if (*pFunc == NULL) { return ERROR_PROC_NOT_FOUND; } Modified: trunk/teraterm/common/i18n.c =================================================================== --- trunk/teraterm/common/i18n.c 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/i18n.c 2019-03-25 13:47:32 UTC (rev 7509) @@ -27,31 +27,129 @@ */ #include "i18n.h" +#include "ttlib.h" +#include "codeconv.h" -void WINAPI GetI18nStr(PCHAR section, PCHAR key, PCHAR buf, int buf_len, PCHAR def, const char *iniFile) +#include <assert.h> +#include <tchar.h> + +#if defined(UNICODE) +DllExport void GetI18nStrW(const char *section, const char *key, wchar_t *buf, int buf_len, const wchar_t *def, const char *iniFile) { - GetPrivateProfileString(section, key, def, buf, buf_len, iniFile); + wchar_t sectionW[64]; + wchar_t keyW[128]; + wchar_t iniFileW[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, section, -1, sectionW, _countof(sectionW)); + MultiByteToWideChar(CP_ACP, 0, key, -1, keyW, _countof(keyW)); + MultiByteToWideChar(CP_ACP, 0, iniFile, -1, iniFileW, _countof(iniFileW)); + GetPrivateProfileStringW(sectionW, keyW, def, buf, buf_len, iniFileW); + RestoreNewLineW(buf); +} +#endif + +void GetI18nStr(const char *section, const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile) +{ + GetPrivateProfileStringA(section, key, def, buf, buf_len, iniFile); RestoreNewLine(buf); } -int WINAPI GetI18nLogfont(PCHAR section, PCHAR key, PLOGFONT logfont, int ppi, const char *iniFile) +// TODO: \x83o\x83b\x83t\x83@\x95s\x91\xAB\x8E\x9E\x82̓\xAE\x8D\xEC +void GetI18nStrU8(const char *section, const char *key, char *buf, int buf_len, const char *def, const char *iniFile) { - static char tmp[MAX_UIMSG]; - static char font[LF_FACESIZE]; - int hight, charset; - GetPrivateProfileString(section, key, "-", tmp, MAX_UIMSG, iniFile); - if (strcmp(tmp, "-") == 0) { + size_t r; +#if defined(UNICODE) + wchar_t tmp[MAX_UIMSG]; + wchar_t defW[MAX_UIMSG]; + r = UTF8ToWideChar(def, -1, defW, _countof(defW)); + assert(r != 0); + GetI18nStrW(section, key, tmp, _countof(tmp), defW, iniFile); + r = buf_len; + WideCharToUTF8(tmp, NULL, buf, &r); + assert(r != 0); +#else + // ANSI -> Wide -> utf8 + char strA[MAX_UIMSG]; + wchar_t strW[MAX_UIMSG]; + GetI18nStr(section, key, strA, _countof(strA), def, iniFile); + r = MultiByteToWideChar(CP_ACP, 0, strA, -1, strW, _countof(strW)); + assert(r != 0); + r = buf_len; + WideCharToUTF8(strW, NULL, buf, &r); + assert(r != 0); +#endif +} + +int GetI18nLogfont(const char *section, const char *key, PLOGFONTA logfont, int ppi, const char *iniFile) +{ + char tmp[MAX_UIMSG]; + char font[LF_FACESIZE]; + int height, charset; + assert(iniFile[0] != '\0'); + memset(logfont, 0, sizeof(*logfont)); + + GetPrivateProfileStringA(section, key, "", tmp, MAX_UIMSG, iniFile); + if (tmp[0] == '\0') { return FALSE; } GetNthString(tmp, 1, LF_FACESIZE-1, font); - GetNthNum(tmp, 2, &hight); + GetNthNum(tmp, 2, &height); GetNthNum(tmp, 3, &charset); - strncpy_s(logfont->lfFaceName, sizeof(logfont->lfFaceName), font, _TRUNCATE); - logfont->lfCharSet = charset; - logfont->lfHeight = MulDiv(hight, -ppi, 72); + if (font[0] != '\0') { + strncpy_s(logfont->lfFaceName, sizeof(logfont->lfFaceName), font, _TRUNCATE); + } + logfont->lfCharSet = (BYTE)charset; + if (ppi != 0) { + logfont->lfHeight = MulDiv(height, -ppi, 72); + } else { + logfont->lfHeight = height; + } logfont->lfWidth = 0; return TRUE; } + +void SetI18DlgStrs(const char *section, HWND hDlgWnd, + const DlgTextInfo *infos, size_t infoCount, const char *UILanguageFile) +{ + size_t i; + assert(hDlgWnd != NULL); + assert(infoCount > 0); + for (i = 0 ; i < infoCount; i++) { + const char *key = infos[i].key; + TCHAR uimsg[MAX_UIMSG]; + GetI18nStrT(section, key, uimsg, sizeof(uimsg), _T(""), UILanguageFile); + if (uimsg[0] != _T('\0')) { + const int nIDDlgItem = infos[i].nIDDlgItem; + BOOL r; + if (nIDDlgItem == 0) { + r = SetWindowText(hDlgWnd, uimsg); + assert(r != 0); + } else { + r = SetDlgItemText(hDlgWnd, nIDDlgItem, uimsg); + assert(r != 0); + } + (void)r; + } + } +} + +void SetI18MenuStrs(const char *section, HMENU hMenu, + const DlgTextInfo *infos, size_t infoCount, const char *UILanguageFile) +{ + size_t i; + for (i = 0; i < infoCount; i++) { + const int nIDDlgItem = infos[i].nIDDlgItem; + const char *key = infos[i].key; + TCHAR uimsg[MAX_UIMSG]; + GetI18nStrT(section, key, uimsg, sizeof(uimsg), _T(""), UILanguageFile); + if (uimsg[0] != '\0') { + if (nIDDlgItem < 1000) { + ModifyMenu(hMenu, nIDDlgItem, MF_BYPOSITION, nIDDlgItem, uimsg); + } else { + ModifyMenu(hMenu, nIDDlgItem, MF_BYCOMMAND, nIDDlgItem, uimsg); + } + } + } +} Modified: trunk/teraterm/common/i18n.h =================================================================== --- trunk/teraterm/common/i18n.h 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/i18n.h 2019-03-25 13:47:32 UTC (rev 7509) @@ -30,7 +30,6 @@ #define __I18N_H #include <windows.h> -#include "ttlib.h" #define MAX_UIMSG 1024 @@ -38,9 +37,27 @@ extern "C" { #endif -void WINAPI GetI18nStr(PCHAR section, PCHAR key, PCHAR buf, int buf_len, PCHAR def, const char *iniFile); -int WINAPI GetI18nLogfont(PCHAR section, PCHAR key, PLOGFONT logfont, int ppi, const char *iniFile); +typedef struct { + int nIDDlgItem; + const char *key; +} DlgTextInfo; +#if defined(UNICODE) +void GetI18nStrW(const char *section, const char *key, wchar_t *buf, int buf_len, const wchar_t *def, const char *iniFile); +#endif +void GetI18nStr(const char *section, const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile); +int GetI18nLogfont(const char *section, const char *key, PLOGFONTA logfont, int ppi, const char *iniFile); +void SetI18DlgStrs(const char *section, HWND hDlgWnd, + const DlgTextInfo *infos, size_t infoCount, const char *UILanguageFile); +void SetI18MenuStrs(const char *section, HMENU hMenu, + const DlgTextInfo *infos, size_t infoCount, const char *UILanguageFile); + +#if defined(_UNICODE) +#define GetI18nStrT(p1, p2, p3, p4, p5, p6) GetI18nStrW(p1, p2, p3, p4, p5, p6) +#else +#define GetI18nStrT(p1, p2, p3, p4, p5, p6) GetI18nStr(p1, p2, p3, p4, p5, p6) +#endif + #ifdef __cplusplus } #endif Modified: trunk/teraterm/common/teraterm.h =================================================================== --- trunk/teraterm/common/teraterm.h 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/teraterm.h 2019-03-25 13:47:32 UTC (rev 7509) @@ -70,6 +70,7 @@ #define USE_NORMAL_BGCOLOR #include "i18n.h" +#include "ttlib.h" #define MAXPATHLEN 256 /* version 2.3 */ Modified: trunk/teraterm/common/ttlib.c =================================================================== --- trunk/teraterm/common/ttlib.c 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/ttlib.c 2019-03-25 13:47:32 UTC (rev 7509) @@ -275,7 +275,7 @@ /* fit a filename to the windows-filename format */ /* FileName must contain filename part only. */ -void FitFileName(PCHAR FileName, int destlen, PCHAR DefExt) +void FitFileName(PCHAR FileName, int destlen, const char *DefExt) { int i, j, NumOfDots; char Temp[MAX_PATH]; @@ -880,7 +880,7 @@ } } -void WINAPI GetDefaultFName(char *home, char *file, char *dest, int destlen) +void GetDefaultFName(const char *home, const char *file, char *dest, int destlen) { // My Documents \x82\xC9 file \x82\xAA\x82\xA0\x82\xE9\x8Fꍇ\x81A // \x82\xBB\x82\xEA\x82\xF0\x93ǂݍ\x9E\x82ނ悤\x82ɂ\xB5\x82\xBD\x81B(2007.2.18 maya) @@ -971,7 +971,7 @@ strncpy_s(buf, buflen, Temp, _TRUNCATE); } -void get_lang_msg(PCHAR key, PCHAR buf, int buf_len, PCHAR def, const char *iniFile) +void get_lang_msg(const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile) { GetI18nStr("Tera Term", key, buf, buf_len, def, iniFile); } @@ -1002,9 +1002,9 @@ return 0; } -BOOL doSelectFolder(HWND hWnd, char *path, int pathlen, char *def, char *msg) +BOOL doSelectFolder(HWND hWnd, char *path, int pathlen, const char *def, const char *msg) { - BROWSEINFO bi; + BROWSEINFOA bi; LPITEMIDLIST pidlRoot; // \x83u\x83\x89\x83E\x83Y\x82̃\x8B\x81[\x83gPIDL LPITEMIDLIST pidlBrowse; // \x83\x86\x81[\x83U\x81[\x82\xAA\x91I\x91\xF0\x82\xB5\x82\xBDPIDL char buf[MAX_PATH]; @@ -1046,14 +1046,26 @@ return ret; } -void OutputDebugPrintf(char *fmt, ...) { +void OutputDebugPrintf(const char *fmt, ...) +{ char tmp[1024]; va_list arg; va_start(arg, fmt); _vsnprintf(tmp, sizeof(tmp), fmt, arg); - OutputDebugString(tmp); + va_end(arg); + OutputDebugStringA(tmp); } +void OutputDebugPrintfW(const wchar_t *fmt, ...) +{ + wchar_t tmp[1024]; + va_list arg; + va_start(arg, fmt); + _vsnwprintf(tmp, _countof(tmp), fmt, arg); + va_end(arg); + OutputDebugStringW(tmp); +} + #if (_MSC_VER < 1800) BOOL vercmp( DWORD cond_val, @@ -1783,3 +1795,13 @@ return TRUE; } + +void SetDlgTexts(HWND hDlgWnd, const DlgTextInfo *infos, int infoCount, const char *UILanguageFile) +{ + SetI18DlgStrs("Tera Term", hDlgWnd, infos, infoCount, UILanguageFile); +} + +void SetDlgMenuTexts(HMENU hMenu, const DlgTextInfo *infos, int infoCount, const char *UILanguageFile) +{ + SetI18MenuStrs("Tera Term", hMenu, infos, infoCount, UILanguageFile); +} Modified: trunk/teraterm/common/ttlib.h =================================================================== --- trunk/teraterm/common/ttlib.h 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/common/ttlib.h 2019-03-25 13:47:32 UTC (rev 7509) @@ -29,6 +29,10 @@ /* useful routines */ +#pragma once + +#include "i18n.h" + #ifdef __cplusplus extern "C" { #endif @@ -36,7 +40,7 @@ BOOL GetFileNamePos(PCHAR PathName, int far *DirLen, int far *FNPos); BOOL ExtractFileName(PCHAR PathName, PCHAR FileName, int destlen); BOOL ExtractDirName(PCHAR PathName, PCHAR DirName); -void FitFileName(PCHAR FileName, int destlen, PCHAR DefExt); +void FitFileName(PCHAR FileName, int destlen, const char *DefExt); void AppendSlash(PCHAR Path, int destlen); void DeleteSlash(PCHAR Path); void Str2Hex(PCHAR Str, PCHAR Hex, int Len, int MaxHexLen, BOOL ConvSP); @@ -63,18 +67,18 @@ void GetNthNum(PCHAR Source, int Nth, int far *Num); int GetNthNum2(PCHAR Source, int Nth, int defval); void GetDownloadFolder(char *dest, int destlen); -void WINAPI GetDefaultFName(char *home, char *file, char *dest, int destlen); +void GetDefaultFName(const char *home, const char *file, char *dest, int destlen); void GetDefaultSetupFName(char *home, char *dest, int destlen); void GetUILanguageFile(char *buf, int buflen); void GetOnOffEntryInifile(char *entry, char *buf, int buflen); -void get_lang_msg(PCHAR key, PCHAR buf, int buf_len, PCHAR def, const char *iniFile); +void get_lang_msg(const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile); #if defined(UNICODE) void get_lang_msgW(const char *key, wchar_t *buf, int buf_len, const wchar_t *def, const char *iniFile); #endif int get_lang_font(PCHAR key, HWND dlg, PLOGFONT logfont, HFONT *font, const char *iniFile); -BOOL doSelectFolder(HWND hWnd, char *path, int pathlen, char *def, char *msg); -void OutputDebugPrintf(char *fmt, ...); -DWORD get_OPENFILENAME_SIZE(); +BOOL doSelectFolder(HWND hWnd, char *path, int pathlen, const char *def, const char *msg); +void OutputDebugPrintf(const char *fmt, ...); +DWORD get_OPENFILENAME_SIZEA(); BOOL IsWindows95(); BOOL IsWindowsMe(); BOOL IsWindowsNT4(); @@ -107,10 +111,13 @@ #define CheckFlag(var, flag) (((var) & (flag)) != 0) +void SetDlgTexts(HWND hDlgWnd, const DlgTextInfo *infos, int infoCount, const char *UILanguageFile); #if defined(_UNICODE) #define get_lang_msgT(p1, p2, p3, p4, p5) get_lang_msgW(p1, p2, p3, p4, p5) +#define get_OPENFILENAME_SIZE() get_OPENFILENAME_SIZEW() #else #define get_lang_msgT(p1, p2, p3, p4, p5) get_lang_msg(p1, p2, p3, p4, p5) +#define get_OPENFILENAME_SIZE() get_OPENFILENAME_SIZEA() #endif #ifdef __cplusplus } Modified: trunk/teraterm/teraterm/CMakeLists.txt =================================================================== --- trunk/teraterm/teraterm/CMakeLists.txt 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/teraterm/CMakeLists.txt 2019-03-25 13:47:32 UTC (rev 7509) @@ -20,8 +20,10 @@ ../common/teraterm.h ../common/ttlib.c ../common/ttlib.h + ../common/dlglib.h ../common/dlglib.c - ../common/dlglib.h + ../common/dlglib_cpp.cpp + ../common/dlglib_tmpl.cpp ../common/win16api.h ../common/win16api.c ../common/codemap.h @@ -179,3 +181,59 @@ ttpset ttptek ) + +# copy .lng files +if(${CMAKE_GENERATOR} MATCHES "Visual Studio 15 2017") + add_custom_target( + copy_lang ALL + DEPENDS + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Default.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/English.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/French.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/German.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Japanese.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Korean.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Russian.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Simplified Chinese.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Traditional Chinese.lng" + ) + add_custom_command( + OUTPUT + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Default.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/English.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/French.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/German.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Japanese.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Korean.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Russian.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Simplified Chinese.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Traditional Chinese.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/Default.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Default.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/English.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/English.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/French.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/French.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/German.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/German.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/Japanese.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Japanese.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/Korean.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Korean.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/Russian.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Russian.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/Simplified Chinese.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Simplified Chinese.lng" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_SOURCE_DIR}/installer/release/lang/Traditional Chinese.lng" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$(Configuration)/lang/Traditional Chinese.lng" + ) +endif() Modified: trunk/teraterm/teraterm/clipboar.c =================================================================== --- trunk/teraterm/teraterm/clipboar.c 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/teraterm/clipboar.c 2019-03-25 13:47:32 UTC (rev 7509) @@ -40,6 +40,7 @@ #include "ttwinman.h" #include "ttcommon.h" #include "ttlib.h" +#include "dlglib.h" #include "clipboar.h" #include "tt_res.h" @@ -61,8 +62,6 @@ static BOOL CBEchoOnly; static BOOL CBInsertDelay = FALSE; -static HFONT DlgClipboardFont; - static LRESULT CALLBACK OnClipboardDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp); PCHAR CBOpen(LONG MemSize) @@ -358,8 +357,8 @@ } if (confirm) { - ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_CLIPBOARD_DIALOG), - HWin, (DLGPROC)OnClipboardDlgProc); + ret = TTDialogBox(hInst, MAKEINTRESOURCE(IDD_CLIPBOARD_DIALOG), + HWin, (DLGPROC)OnClipboardDlgProc); /* * \x88ȑO\x82̓_\x83C\x83A\x83\x8D\x83O\x82̓\xE0\x97e\x82\xF0\x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82ɏ\x91\x82\xAB\x96߂\xB5\x82Ă\xA2\x82\xBD\x82\xAF\x82\xEA\x82ǁA\x95K\x97v? */ @@ -814,7 +813,7 @@ char *buf; int wide_len; HGLOBAL wide_hMem; - LPWSTR wide_buf; + LPWSTR wide_buf = 0; if (OpenClipboard(owner) == 0) return FALSE; @@ -861,9 +860,11 @@ static LRESULT CALLBACK OnClipboardDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp) { - LOGFONT logfont; - HFONT font; - char uimsg[MAX_UIMSG]; + static const DlgTextInfo TextInfos[] = { + { 0, "DLG_CLIPBOARD_TITLE" }, + { IDCANCEL, "BTN_CANCEL" }, + { IDOK, "BTN_OK" }, + }; POINT p; RECT rc_dsk, rc_dlg; int dlg_height, dlg_width; @@ -871,33 +872,14 @@ RECT rc_edit, rc_ok, rc_cancel; // for status bar static HWND hStatus = NULL; - static init_width, init_height; + static int init_width, init_height; switch (msg) { case WM_INITDIALOG: - font = (HFONT)SendMessage(hDlgWnd, WM_GETFONT, 0, 0); - GetObject(font, sizeof(LOGFONT), &logfont); - if (get_lang_font("DLG_TAHOMA_FONT", hDlgWnd, &logfont, &DlgClipboardFont, ts.UILanguageFile)) { - SendDlgItemMessage(hDlgWnd, IDC_EDIT, WM_SETFONT, (WPARAM)DlgClipboardFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(hDlgWnd, IDOK, WM_SETFONT, (WPARAM)DlgClipboardFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(hDlgWnd, IDCANCEL, WM_SETFONT, (WPARAM)DlgClipboardFont, MAKELPARAM(TRUE,0)); - } - else { - DlgClipboardFont = NULL; - } + SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile); - GetWindowText(hDlgWnd, uimsg, sizeof(uimsg)); - get_lang_msg("DLG_CLIPBOARD_TITLE", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile); - SetWindowText(hDlgWnd, ts.UIMsg); - GetDlgItemText(hDlgWnd, IDCANCEL, uimsg, sizeof(uimsg)); - get_lang_msg("BTN_CANCEL", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile); - SetDlgItemText(hDlgWnd, IDCANCEL, ts.UIMsg); - GetDlgItemText(hDlgWnd, IDOK, uimsg, sizeof(uimsg)); - get_lang_msg("BTN_OK", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile); - SetDlgItemText(hDlgWnd, IDOK, ts.UIMsg); + SetDlgItemTextA(hDlgWnd, IDC_EDIT, CBMemPtr); - SendMessage(GetDlgItem(hDlgWnd, IDC_EDIT), WM_SETTEXT, 0, (LPARAM)CBMemPtr); - if (ActiveWin == IdVT) { // VT Window /* * Caret off \x8E\x9E\x82\xC9 GetCaretPos() \x82Ő\xB3\x8Am\x82ȏꏊ\x82\xAA\x8E\xE6\x82\xEA\x82Ȃ\xA2\x82̂ŁA @@ -995,7 +977,7 @@ switch (LOWORD(wp)) { case IDOK: { - unsigned len = SendMessage(GetDlgItem(hDlgWnd, IDC_EDIT), WM_GETTEXTLENGTH, 0, 0); + unsigned len = SendMessageA(GetDlgItem(hDlgWnd, IDC_EDIT), WM_GETTEXTLENGTH, 0, 0); HGLOBAL hMem; INT_PTR result = IDCANCEL; @@ -1033,26 +1015,18 @@ if (CBMemPtr == NULL) { CBMemPtr = GlobalLock(CBMemHandle); } - SendMessage(GetDlgItem(hDlgWnd, IDC_EDIT), WM_GETTEXT, GlobalSize(CBMemHandle), (LPARAM)CBMemPtr); + GetDlgItemTextA(hDlgWnd, IDC_EDIT, CBMemPtr, GlobalSize(CBMemHandle)); result = IDOK; } - if (DlgClipboardFont != NULL) { - DeleteObject(DlgClipboardFont); - } - DestroyWindow(hStatus); - EndDialog(hDlgWnd, result); + TTEndDialog(hDlgWnd, result); } break; case IDCANCEL: - if (DlgClipboardFont != NULL) { - DeleteObject(DlgClipboardFont); - } - DestroyWindow(hStatus); - EndDialog(hDlgWnd, IDCANCEL); + TTEndDialog(hDlgWnd, IDCANCEL); break; default: Modified: trunk/teraterm/teraterm/protodlg.cpp =================================================================== --- trunk/teraterm/teraterm/protodlg.cpp 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/teraterm/protodlg.cpp 2019-03-25 13:47:32 UTC (rev 7509) @@ -34,6 +34,7 @@ #include "tttypes.h" #include "ttftypes.h" #include "ttlib.h" +#include "dlglib.h" #include "protodlg.h" #ifdef _DEBUG Modified: trunk/teraterm/teraterm/teraterm.cpp =================================================================== --- trunk/teraterm/teraterm/teraterm.cpp 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/teraterm/teraterm.cpp 2019-03-25 13:47:32 UTC (rev 7509) @@ -51,6 +51,7 @@ #include "teraapp.h" #include "compat_w95.h" +#include "dlglib.h" #if 0 //#ifdef _DEBUG @@ -65,50 +66,12 @@ //}}AFX_MSG_MAP END_MESSAGE_MAP() -typedef struct { - const TCHAR *FaceName; - bool found; -} EnumFontInfo; - -static int CALLBACK EnumFontExProc( - ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm, - int nFontType, LPARAM lParam) -{ - EnumFontInfo *info = (EnumFontInfo *)lParam; - if (nFontType == DEVICE_FONTTYPE) { - // \x90ڑ\xB1\x82\xB3\x82ꂽ\x83f\x83o\x83C\x83X(\x83v\x83\x8A\x83\x93\x83^\x82Ȃ\xC7)\x93\xE0\x82̃t\x83H\x83\x93\x83g - return 1; - } - const TCHAR *FaceName = lpelf->elfLogFont.lfFaceName; - if (_tcscmp(info->FaceName, FaceName) == 0) { - info->found = true; - return 0; - } - return 1; -} - -BOOL isExistFont(const TCHAR *FaceName) -{ - HDC hDC = GetDC(NULL); - LOGFONT lf; - memset(&lf, 0, sizeof(lf)); - lf.lfCharSet = DEFAULT_CHARSET;// SHIFTJIS_CHARSET; - lf.lfPitchAndFamily = 0; - - EnumFontInfo info; - info.FaceName = FaceName; - info.found = false; - EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)EnumFontExProc, (LPARAM)&info, 0); - ReleaseDC(NULL, hDC); - return info.found; -} - static BOOL AddFontFlag; static TCHAR TSpecialFont[MAX_PATH]; static void LoadSpecialFont() { - if (!isExistFont(_T("Tera Special"))) { + if (!IsExistFontA("Tera Special", SYMBOL_CHARSET, TRUE)) { int r; if (GetModuleFileName(NULL, TSpecialFont,_countof(TSpecialFont)) == 0) { @@ -144,16 +107,26 @@ } } -CTeraApp::CTeraApp() +static void init() { #ifdef _DEBUG ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif - DLLInit(); WinCompatInit(); +#if 1 + if (pSetThreadDpiAwarenessContext) { + pSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + } +#endif + LoadSpecialFont(); } +CTeraApp::CTeraApp() +{ + init(); +} + // CTeraApp instance CTeraApp theApp; @@ -164,10 +137,12 @@ // CTeraApp initialization BOOL CTeraApp::InitInstance() { - LoadSpecialFont(); hInst = m_hInstance; m_pMainWnd = new CVTWindow(); pVTWin = m_pMainWnd; + // [Tera Term]\x83Z\x83N\x83V\x83\x87\x83\x93\x82\xCCDlgFont=\x82\xAA\x82Ȃ\xA2\x8Fꍇ\x82\xCD + // [TTSH]\x83Z\x83N\x83V\x83\x87\x83\x93\x82̃t\x83H\x83\x93\x83g\x90ݒ\xE8\x82\xF0\x8Eg\x97p\x82\xB7\x82\xE9 + SetDialogFont(ts.SetupFName, ts.UILanguageFile, "TTSSH"); return TRUE; } Modified: trunk/teraterm/ttpcmn/CMakeLists.txt =================================================================== --- trunk/teraterm/ttpcmn/CMakeLists.txt 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttpcmn/CMakeLists.txt 2019-03-25 13:47:32 UTC (rev 7509) @@ -57,6 +57,10 @@ ${SRC} ) +target_compile_definitions( + ttpcmn + PRIVATE -DTTPCMN_DLL + ) if(MINGW) set_target_properties( ttpcmn Modified: trunk/teraterm/ttpcmn/language.c =================================================================== --- trunk/teraterm/ttpcmn/language.c 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttpcmn/language.c 2019-03-25 13:47:32 UTC (rev 7509) @@ -33,6 +33,7 @@ #include "tttypes.h" #include <mbstring.h> #include <locale.h> +#include "codemap.h" #include "language.h" Modified: trunk/teraterm/ttpcmn/ttpcmn.def =================================================================== --- trunk/teraterm/ttpcmn/ttpcmn.def 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttpcmn/ttpcmn.def 2019-03-25 13:47:32 UTC (rev 7509) @@ -90,4 +90,7 @@ parse_port @90 parse_port_from_buf @91 service_name @92 - get_OPENFILENAME_SIZE @93 \ No newline at end of file + get_OPENFILENAME_SIZEA @93 + + SetI18DlgStrs + SetI18MenuStrs Modified: trunk/teraterm/ttpdlg/CMakeLists.txt =================================================================== --- trunk/teraterm/ttpdlg/CMakeLists.txt 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttpdlg/CMakeLists.txt 2019-03-25 13:47:32 UTC (rev 7509) @@ -13,6 +13,7 @@ set(COMMON_SRC ../common/dlglib.c ../common/dlglib.h + ../common/dlglib_tmpl.cpp ../common/ttlib.c ../common/ttlib.h ../common/teraterm.ico Modified: trunk/teraterm/ttpfile/CMakeLists.txt =================================================================== --- trunk/teraterm/ttpfile/CMakeLists.txt 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttpfile/CMakeLists.txt 2019-03-25 13:47:32 UTC (rev 7509) @@ -5,6 +5,8 @@ set(COMMON_SRC ../common/dlglib.c ../common/dlglib.h + ../common/dlglib_cpp.cpp + ../common/dlglib_tmpl.cpp ../common/ttlib.c ../common/ttlib.h ../common/win16api.h Modified: trunk/teraterm/ttptek/CMakeLists.txt =================================================================== --- trunk/teraterm/ttptek/CMakeLists.txt 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttptek/CMakeLists.txt 2019-03-25 13:47:32 UTC (rev 7509) @@ -11,7 +11,10 @@ ../common/i18n.h ../common/ttlib.c ../common/ttlib.h + ../common/codeconv.h + ../common/codeconv.cpp ) + source_group( "common" FILES @@ -25,7 +28,7 @@ ttptek.def ttptek.rc ttptek-version.rc -# tttek.h + tttek.h tttek.c ${COMMON_SRC} ) @@ -56,8 +59,8 @@ target_link_libraries( ttptek ttpcmn - debug sfmtd.lib - optimized sfmt.lib + debug sfmtd + optimized sfmt # iphlpapi gdi32 Modified: trunk/teraterm/ttptek/tekesc.c =================================================================== --- trunk/teraterm/ttptek/tekesc.c 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttptek/tekesc.c 2019-03-25 13:47:32 UTC (rev 7509) @@ -35,7 +35,11 @@ #include <math.h> #include <string.h> +#undef DllExport +#define DllExport __declspec(dllexport) + #include "tekesc.h" +#include "tttek.h" void Log1Byte(PComVar cv, BYTE b) { Modified: trunk/teraterm/ttptek/tekesc.h =================================================================== --- trunk/teraterm/ttptek/tekesc.h 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttptek/tekesc.h 2019-03-25 13:47:32 UTC (rev 7509) @@ -29,7 +29,6 @@ /* TTTEK.DLL, TEK escape sequences */ -void PASCAL TEKChangeCaret(PTEKVar tk, PTTSet ts); void ParseFirst(PTEKVar tk, PTTSet ts, PComVar cv, BYTE b); void TEKEscape(PTEKVar tk, PTTSet ts, PComVar cv, BYTE b); void SelectCode(PTEKVar tk, PTTSet ts, BYTE b); Modified: trunk/teraterm/ttptek/tttek.c =================================================================== --- trunk/teraterm/ttptek/tttek.c 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/teraterm/ttptek/tttek.c 2019-03-25 13:47:32 UTC (rev 7509) @@ -36,10 +36,15 @@ #include <string.h> #include "ttcommon.h" -#include "tekesc.h" #include "compat_w95.h" +#undef DllExport +#define DllExport __declspec(dllexport) + +#include "tekesc.h" +#include "tttek.h" + static HANDLE hInst; void PASCAL TEKInit(PTEKVar tk, PTTSet ts) Copied: trunk/teraterm/ttptek/tttek.h (from rev 7508, trunk/teraterm/ttptek/tekesc.h) =================================================================== --- trunk/teraterm/ttptek/tttek.h (rev 0) +++ trunk/teraterm/ttptek/tttek.h 2019-03-25 13:47:32 UTC (rev 7509) @@ -0,0 +1,50 @@ +/* + * Copyright (C) 1994-1998 T. Teranishi + * (C) 2018 TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* TTTEK.DLL, TEK escape sequences */ + +DllExport void WINAPI TEKInit(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKChangeCaret(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKDestroyCaret(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKResizeWindow(PTEKVar tk, PTTSet ts, int W, int H); +DllExport int WINAPI TEKParse(PTEKVar tk, PTTSet ts, PComVar cv); +DllExport void WINAPI TEKReportGIN(PTEKVar tk, PTTSet ts, PComVar cv, BYTE KeyCode); +DllExport void WINAPI TEKPaint(PTEKVar tk, PTTSet ts, HDC PaintDC, PAINTSTRUCT *PaintInfo); +DllExport void WINAPI TEKWMLButtonDown(PTEKVar tk, PTTSet ts, PComVar cv, POINT pos); +DllExport void WINAPI TEKWMLButtonUp(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKWMMouseMove(PTEKVar tk, PTTSet ts, POINT p); +DllExport void WINAPI TEKWMSize(PTEKVar tk, PTTSet ts, int W, int H, int cx, int cy); +DllExport void WINAPI TEKCMCopy(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKCMCopyScreen(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKPrint(PTEKVar tk, PTTSet ts, HDC PrintDC, BOOL SelFlag); +DllExport void WINAPI TEKClearScreen(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKSetupFont(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKResetWin(PTEKVar tk, PTTSet ts, WORD EmuOld); +DllExport void WINAPI TEKRestoreSetup(PTEKVar tk, PTTSet ts); +DllExport void WINAPI TEKEnd(PTEKVar tk); Modified: trunk/ttpmenu/CMakeLists.txt =================================================================== --- trunk/ttpmenu/CMakeLists.txt 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/ttpmenu/CMakeLists.txt 2019-03-25 13:47:32 UTC (rev 7509) @@ -3,10 +3,12 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/") set(COMMON_SRC + ../teraterm/common/ttlib.h ../teraterm/common/ttlib.c - ../teraterm/common/ttlib.h + ../teraterm/common/i18n.h ../teraterm/common/i18n.c - ../teraterm/common/i18n.h + ../teraterm/common/codeconv.h + ../teraterm/common/codeconv.cpp ) source_group( @@ -18,8 +20,10 @@ set(SRC resource.h registry.cpp + ttpmenu.h ttpmenu.cpp winmisc.cpp + # left.ico right.ico teraterm.ico Modified: trunk/ttpmenu/ttpmenu.cpp =================================================================== --- trunk/ttpmenu/ttpmenu.cpp 2019-03-24 03:44:58 UTC (rev 7508) +++ trunk/ttpmenu/ttpmenu.cpp 2019-03-25 13:47:32 UTC (rev 7509) @@ -17,7 +17,8 @@ #include "winmisc.h" #include "resource.h" -#include "compat_w95.h" +#include "compat_w95.h" +#include "ttlib.h" // UTF-8 TeraTerm\x82ł́A\x83f\x83t\x83H\x83\x8B\x83g\x83C\x83\x93\x83X\x83g\x81[\x83\x8B\x90\xE6\x82\xF0\x89\xBA\x8BL\x82ɕύX\x82\xB5\x82\xBD\x81B(2004.12.2 yutaka) // \x82\xB3\x82\xE7\x82ɁA\x83f\x83t\x83H\x83\x8B\x83g\x83C\x83\x93\x83X\x83g\x81[\x83\x8B\x90\xE6\x82̓J\x83\x8C\x83\x93\x83g\x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82ɕύX\x81B(2004.12.14 yutaka)