From 077e9b9bc473dcdcf679b3790d571972b3a8364e Mon Sep 17 00:00:00 2001 From: zmatsuo <6488847+zmatsuo@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:44:09 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=92=E3=82=B9=E3=83=88=E3=83=AA(=E5=B1=A5?= =?UTF-8?q?=E6=AD=B4)=E3=82=92=E6=89=B1=E3=81=86=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=82=92=E8=BF=BD=E5=8A=A0=20#402?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - common/histroy_store.cpp,h 追加 - broadcastのヒストリの読み込みと保存を差し替え - logダイアログにヒストリ追加 - 実行ファイルが起動してから終了するまでの履歴 - 履歴はini等には保存しない - sendfileダイアログにヒストリを追加 - 実行ファイルが起動してから終了するまでの履歴 - 履歴はini等には保存しない - _AddValueToList (ttset.c) を差し替え - edithistoryのヒストリの保存を差し替え --- teraterm/common/CMakeLists.txt | 2 + teraterm/common/dlglib_cpp.cpp | 36 ---- teraterm/common/edithistory.cpp | 29 +-- teraterm/common/history_store.cpp | 316 ++++++++++++++++++++++++++++++ teraterm/common/history_store.h | 52 +++++ teraterm/teraterm/broadcast.cpp | 26 +-- teraterm/teraterm/filesys_log.rc | 2 +- teraterm/teraterm/logdlg.cpp | 108 ++++++---- teraterm/teraterm/logdlg.h | 1 + teraterm/teraterm/sendfiledlg.cpp | 20 +- teraterm/teraterm/sendfiledlg.h | 1 + teraterm/teraterm/ttermpro.rc | 2 +- teraterm/teraterm/vtwin.cpp | 2 + teraterm/ttpset/ttset.c | 85 +------- 14 files changed, 479 insertions(+), 203 deletions(-) create mode 100644 teraterm/common/history_store.cpp create mode 100644 teraterm/common/history_store.h diff --git a/teraterm/common/CMakeLists.txt b/teraterm/common/CMakeLists.txt index 9c195fdea..0fd2b5f33 100644 --- a/teraterm/common/CMakeLists.txt +++ b/teraterm/common/CMakeLists.txt @@ -29,6 +29,8 @@ add_library( fileread.h getcontent.cpp getcontent.h + history_store.cpp + history_store.h i18n.c i18n.h i18n_static.c diff --git a/teraterm/common/dlglib_cpp.cpp b/teraterm/common/dlglib_cpp.cpp index 30ee02619..4043e3dd4 100644 --- a/teraterm/common/dlglib_cpp.cpp +++ b/teraterm/common/dlglib_cpp.cpp @@ -486,42 +486,6 @@ void SetDlgItemIcon(HWND dlg, int nID, const wchar_t *name, int cx, int cy) SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)data); } -/** - * ڑzXgR{{bNX܂̓Xg{bNXɃZbg - */ -void SetComboBoxHostHistory(HWND dlg, int dlg_item, int maxhostlist, const wchar_t *SetupFNW) -{ - char class_name[32]; - UINT message; - int r = GetClassNameA(GetDlgItem(dlg, dlg_item), class_name, _countof(class_name)); - if (r == 0) { - return; - } - if (strcmp(class_name, "ComboBox") == 0) { - message = CB_ADDSTRING; - } - else if (strcmp(class_name, "ListBox") == 0) { - message = LB_ADDSTRING; - } - else { - assert(FALSE); - return; - } - - int i = 1; - do { - wchar_t EntNameW[128]; - wchar_t *TempHostW; - _snwprintf_s(EntNameW, _countof(EntNameW), _TRUNCATE, L"host%d", i); - hGetPrivateProfileStringW(L"Hosts", EntNameW, L"", SetupFNW, &TempHostW); - if (TempHostW[0] != 0) { - SendDlgItemMessageW(dlg, dlg_item, message, 0, (LPARAM)TempHostW); - } - free(TempHostW); - i++; - } while (i <= maxhostlist); -} - /** * EBhEɃACRZbg * diff --git a/teraterm/common/edithistory.cpp b/teraterm/common/edithistory.cpp index 16f49a138..f97b896c9 100644 --- a/teraterm/common/edithistory.cpp +++ b/teraterm/common/edithistory.cpp @@ -43,6 +43,7 @@ #include "helpid.h" #include "win32helper.h" #include "resize_helper.h" +#include "history_store.h" #include "edithistory_res.h" #include "edithistory.h" @@ -87,28 +88,10 @@ static void ModifyListboxHScrollWidth(HWND dlg, int dlg_item) */ static void WriteListBoxHostHistory(HWND dlg, int dlg_item, int maxhostlist, const wchar_t *SetupFNW) { - LRESULT item_count; - LRESULT i; - - item_count = SendDlgItemMessageW(dlg, dlg_item, LB_GETCOUNT, 0, 0); - if (item_count == LB_ERR) { - return; - } - - // [Hosts] ׂč폜 - WritePrivateProfileStringW(L"Hosts", NULL, NULL, SetupFNW); - - if (item_count > maxhostlist) { - item_count = maxhostlist; - } - for (i = 0; i < item_count; i++) { - wchar_t EntNameW[10]; - wchar_t *strW; - GetDlgItemIndexTextW(dlg, dlg_item, (WPARAM)i, &strW); - _snwprintf_s(EntNameW, _countof(EntNameW), _TRUNCATE, L"Host%i", (int)i + 1); - WritePrivateProfileStringW(L"Hosts", EntNameW, strW, SetupFNW); - free(strW); - } + HistoryStore *hs = HistoryStoreCreate(maxhostlist); + HistoryStoreGetControl(hs, dlg, dlg_item); + HistoryStoreSaveIni(hs, SetupFNW, L"Hosts", L"host"); + HistoryStoreDestroy(hs); } /** @@ -142,7 +125,7 @@ static void TCPIPDlgButtons(HWND Dialog) typedef struct { ReiseDlgHelper_t *resize_helper; - EditHistoryDlgData *parent_data; + const EditHistoryDlgData *parent_data; } DlgData; static INT_PTR CALLBACK TCPIPDlg(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) diff --git a/teraterm/common/history_store.cpp b/teraterm/common/history_store.cpp new file mode 100644 index 000000000..98ef55178 --- /dev/null +++ b/teraterm/common/history_store.cpp @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2024- 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. + */ + +#include +#include +#ifndef _CRTDBG_MAP_ALLOC +#define _CRTDBG_MAP_ALLOC +#endif +#include +#include +#include + +#include "asprintf.h" +#include "win32helper.h" +#include "dlglib.h" // for SetComboBoxHostHistory() + +#include "history_store.h" + +typedef struct HistoryStoreTag { + size_t max; + size_t count; + wchar_t **ptr; +} HistoryStore; + +HistoryStore *HistoryStoreCreate(size_t max) +{ + HistoryStore *h = (HistoryStore *)calloc(1, sizeof(*h)); + if (h == NULL) { + return NULL; + } + h->max = max; + h->count = 0; + h->ptr = (wchar_t **)calloc(h->max, sizeof(wchar_t *)); + if (h->ptr == NULL) { + free(h); + return NULL; + } + return h; +} + +void HistoryStoreClear(HistoryStore *h) +{ + for (size_t i = 0; i < h->count; i++) { + free(h->ptr[i]); + h->ptr[i] = NULL; + } + h->count = 0; +} + +void HistoryStoreDestroy(HistoryStore *h) +{ + if (h == NULL) { + return; + } + HistoryStoreClear(h); + free(h->ptr); + free(h); +} + +/** + * history̍ŐVɒlj + * + * @param h + * @param add_str lj + * @param enable_duplicate FALSE / TRUE = lj̏d‚Ȃ / + * @retval TRUE ̓eω + * @retval FALSE ̓eωȂ + */ +BOOL HistoryStoreAddTop(HistoryStore *h, const wchar_t *add_str, BOOL enable_duplicate) +{ + if (add_str == NULL) { + return FALSE; + } + wchar_t *s = _wcsdup(add_str); + if (s == NULL) { + return FALSE; + } + + if (h->count != 0) { + size_t from = 0; + size_t to = h->count - 1; + if (!enable_duplicate) { + for (size_t i = 0; i < h->count; i++) { + if (wcscmp(h->ptr[i], add_str) == 0) { + if (i == 0) { + // Top AHistory͕ωȂ + free(s); + return FALSE; + } + from = 0; + to = i - 1; + free(h->ptr[i]); + h->ptr[i] = NULL; + break; + } + } + } + + if (to + 1 == h->max) { + // čőTCY𒴂ꍇ́AŌ폜Ă + free(h->ptr[to]); + h->ptr[to] = NULL; + to--; + } + else if (to == h->count - 1) { + // TCY1‘ + h->count++; + } + else { + // ړ + } + + // ړ + memmove(&h->ptr[from + 1], &h->ptr[from], (to - from + 1) * sizeof(wchar_t *)); + } + else { + h->count++; + } + + // lj + h->ptr[0] = s; + + return TRUE; +} + +/** + * init@CqXgǂݍ + * + * @param h + * @param FName init@C + * @param section section + * @param key keỹx[X + * + * section="Hosts" + * key="host" ̂Ƃ̗ + * + * [Hosts] + * host1=sample1 + * host2=sample2 + * host3=sample3 + */ +void HistoryStoreReadIni(HistoryStore *h, const wchar_t *FName, const wchar_t *section, const wchar_t *key) +{ + size_t count = 0; + int unset_count = 0; + for (size_t i = 0 ; i < h->max; i++) { + wchar_t *EntName; + aswprintf(&EntName, L"%s%d", key, i + 1); + wchar_t *item; + hGetPrivateProfileStringW(section, EntName, L"", FName, &item); + free(EntName); + if (item[0] == 0) { + free(item); + unset_count++; + if (unset_count == 10) { + break; + } + } + else { + h->ptr[count] = item; + count++; + } + } + h->count = count; +} + +/** + * qXginit@C֕ۑ + * + * @param h + * @param FName init@C + * @param section section + * @param key keỹx[X + */ +void HistoryStoreSaveIni(HistoryStore *h, const wchar_t *FName, const wchar_t *section, const wchar_t *key) +{ + if (FName == NULL || FName[0] == 0) { + return; + } + + // sectionS + WritePrivateProfileStringW(section, NULL, NULL, FName); + + if (h->count == 0) { + return; + } + + for (size_t i = 0 ; i < h->count; i++) { + wchar_t *EntName; + + aswprintf(&EntName, L"%s%i", key, (int)i + 1); + WritePrivateProfileStringW(section, EntName, h->ptr[i], FName); + free(EntName); + } + + /* update file */ + /* NULL̎N邩MS̃hLgɏĂȂ */ + WritePrivateProfileStringW(NULL, NULL, NULL, FName); +} + +/** + * qXghbv_EɃZbg + */ +void HistoryStoreSetControl(HistoryStore *h, HWND dlg, int dlg_item) +{ + char class_name[32]; + UINT ADDSTRING; + int r = GetClassNameA(GetDlgItem(dlg, dlg_item), class_name, _countof(class_name)); + if (r == 0) { + return; + } + if (strcmp(class_name, "ComboBox") == 0) { + ADDSTRING = CB_ADDSTRING; + } + else if (strcmp(class_name, "ListBox") == 0) { + ADDSTRING = LB_ADDSTRING; + } + else { + assert(FALSE); + return; + } + + for (size_t i = 0; i < h->count; i++) { + SendDlgItemMessageW(dlg, dlg_item, ADDSTRING, 0, (LPARAM)h->ptr[i]); + } +} + +void HistoryStoreGetControl(HistoryStore *h, HWND dlg, int dlg_item) +{ + LRESULT item_count; + LRESULT i; + char class_name[32]; + UINT GETCOUNT; + int r = GetClassNameA(GetDlgItem(dlg, dlg_item), class_name, _countof(class_name)); + if (r == 0) { + return; + } + if (strcmp(class_name, "ListBox") == 0) { + GETCOUNT = LB_GETCOUNT; + } + else { + assert(FALSE); + return; + } + + item_count = SendDlgItemMessageW(dlg, dlg_item, GETCOUNT, 0, 0); + if (item_count == LB_ERR) { + return; + } + if (item_count > h->max) { + item_count = h->max; + } + + HistoryStoreClear(h); + + for (i = 0; i < item_count; i++) { + wchar_t *strW; + GetDlgItemIndexTextW(dlg, dlg_item, (WPARAM)i, &strW); + h->ptr[i] = strW; + } + h->count = item_count; +} + +/** + * ڑzXgR{{bNX܂̓Xg{bNXɃZbg + * dlglib.h + */ +void SetComboBoxHostHistory(HWND dlg, int dlg_item, int maxhostlist, const wchar_t *SetupFNW) +{ + HistoryStore *hs = HistoryStoreCreate(maxhostlist); + HistoryStoreReadIni(hs, SetupFNW, L"Hosts", L"host"); + HistoryStoreSetControl(hs, dlg, dlg_item); + HistoryStoreDestroy(hs); +} + +const wchar_t *HistoryStoreGet(HistoryStore *h, size_t index) +{ + if (index >= h->count) { + return NULL; + } + return h->ptr[index]; +} + +void HistoryStoreSet(HistoryStore *h, size_t index, const wchar_t *str) +{ + if (index >= h->count) { + return; + } + free(h->ptr[index]); + h->ptr[index] = _wcsdup(str); +} diff --git a/teraterm/common/history_store.h b/teraterm/common/history_store.h new file mode 100644 index 000000000..1f53a225c --- /dev/null +++ b/teraterm/common/history_store.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024- 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. + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct HistoryStoreTag HistoryStore; + +HistoryStore *HistoryStoreCreate(size_t max); +void HistoryStoreDestroy(HistoryStore *h); +void HistoryStoreClear(HistoryStore *h); +BOOL HistoryStoreAddTop(HistoryStore *h, const wchar_t *add_str, BOOL enable_duplicate); +void HistoryStoreReadIni(HistoryStore *h, const wchar_t *FName, const wchar_t *section, const wchar_t *key); +void HistoryStoreSaveIni(HistoryStore *h, const wchar_t *FName, const wchar_t *section, const wchar_t *key); +void HistoryStoreSetControl(HistoryStore *h, HWND dlg, int dlg_item); +void HistoryStoreGetControl(HistoryStore *h, HWND dlg, int dlg_item); +const wchar_t *HistoryStoreGet(HistoryStore *h, size_t index); +void HistoryStoreSet(HistoryStore *h, size_t index, const wchar_t *str); + +#ifdef __cplusplus +} +#endif diff --git a/teraterm/teraterm/broadcast.cpp b/teraterm/teraterm/broadcast.cpp index 162ff29d8..5a9fcadaf 100644 --- a/teraterm/teraterm/broadcast.cpp +++ b/teraterm/teraterm/broadcast.cpp @@ -54,6 +54,7 @@ #include "sendmem.h" #include "clipboar.h" // for CBPreparePaste() #include "ttime.h" +#include "history_store.h" #include "helpid.h" #include "broadcast.h" @@ -105,28 +106,13 @@ static wchar_t *GetHistoryFileName(TTTSet *ts_) return fname; } -static void ApplyBroadCastCommandHisotry(HWND Dialog, wchar_t *historyfile) +static void ApplyBroadCastCommandHisotry(HWND Dialog, const wchar_t *historyfile) { - int i = 1; - SendDlgItemMessage(Dialog, IDC_COMMAND_EDIT, CB_RESETCONTENT, 0, 0); - for (i = 1; i <= ts.MaxBroadcatHistory; i++) { - wchar_t *EntName; - wchar_t *Command; - aswprintf(&EntName, L"Command%d", i); - hGetPrivateProfileStringW(L"BroadcastCommands", EntName, L"", historyfile, &Command); - if (Command != NULL && Command[0] != 0) { - SendDlgItemMessageW(Dialog, IDC_COMMAND_EDIT, CB_ADDSTRING, - 0, (LPARAM)Command); - } - else { - // I - i = ts.MaxBroadcatHistory; - } - free(Command); - free(EntName); - } - + HistoryStore *hs = HistoryStoreCreate(ts.MaxBroadcatHistory); + HistoryStoreReadIni(hs, historyfile, L"BroadcastCommands", L"Command"); + HistoryStoreSetControl(hs, Dialog, IDC_COMMAND_EDIT); + HistoryStoreDestroy(hs); SendDlgItemMessage(Dialog, IDC_COMMAND_EDIT, CB_SETCURSEL,0,0); } diff --git a/teraterm/teraterm/filesys_log.rc b/teraterm/teraterm/filesys_log.rc index f3893658c..79e592973 100644 --- a/teraterm/teraterm/filesys_log.rc +++ b/teraterm/teraterm/filesys_log.rc @@ -66,7 +66,7 @@ CAPTION "Log" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "&Filename (drop file in this dialog)",IDC_SENDFILE_FILENAME_TITLE,9,7,172,8 - EDITTEXT IDC_FOPT_FILENAME_EDIT,19,21,224,14,ES_AUTOHSCROLL + COMBOBOX IDC_FOPT_FILENAME_EDIT,19,21,224,93,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "...",IDC_FOPT_FILENAME_BUTTON,245,21,14,14 GROUPBOX "Write mode",IDC_APPEND_GROUP,7,42,250,45 CONTROL "&New / Overwrite",IDC_NEW_OVERWRITE,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,19,55,150,10 diff --git a/teraterm/teraterm/logdlg.cpp b/teraterm/teraterm/logdlg.cpp index 02f3ff806..6c358dd13 100644 --- a/teraterm/teraterm/logdlg.cpp +++ b/teraterm/teraterm/logdlg.cpp @@ -1,4 +1,4 @@ -/* +/* * (C) 2023- TeraTerm Project * All rights reserved. * @@ -46,6 +46,7 @@ #include "helpid.h" #include "asprintf.h" #include "win32helper.h" +#include "history_store.h" #include "filesys_log_res.h" #include "filesys_log.h" @@ -58,7 +59,7 @@ typedef struct { FLogDlgInfo_t *info; // work bool file_exist; - int current_bom; // ݂t@C̃GR[fBOit@CBOM画j + int current_bom; // 存在するファイルのエンコーディング(ファイルのBOMから判定) bool available_timer; bool enable_timer; bool on_initdialog; @@ -67,12 +68,14 @@ typedef struct { TComVar *pcv; } LogDlgWork_t; +static HistoryStore *hs; + /** - * _CAO̓e ts ɏ߂ + * ダイアログの内容を ts に書き戻し * * TODO - * _CAOŐݒ肵l͈ꎞIȂ̂ - * ݒ㏑̂͗ǂȂ̂ł͂Ȃ낤? + * ダイアログで設定した値は一時的なもので + * 設定を上書きするのは良くないのではないだろうか? */ static void SetLogFlags(HWND Dialog, TTTSet *pts) { @@ -102,7 +105,7 @@ static void SetLogFlags(HWND Dialog, TTTSet *pts) } /** - * Ot@C`FbN + * ログファイルチェック * * @param[in] filename * @param[out] exist ture/false @@ -116,13 +119,13 @@ static void CheckLogFile(const wchar_t *filename, bool *exist, int *bom) *exist = FALSE; *bom = 0; - // t@C݂? + // ファイルが存在する? DWORD logdir = GetFileAttributesW(filename); if ((logdir != INVALID_FILE_ATTRIBUTES) && ((logdir & FILE_ATTRIBUTE_DIRECTORY) == 0)) { - // t@C + // ファイルがあった *exist = TRUE; - // BOML/`FbN + // BOM有り/無しチェック FILE *fp; errno_t e = _wfopen_s(&fp, filename, L"rb"); if (e == 0 && fp != NULL) { @@ -157,17 +160,17 @@ static void CheckLogFile(const wchar_t *filename, LogDlgWork_t *work) } /** - * WI{^At@C̏ԂRg[Enable/Disable + * ラジオボタン、ファイルの状態からコントロールをEnable/Disableする */ static void ArrangeControls(HWND Dialog, LogDlgWork_t *work) { - // Append WI{^ + // Append ラジオボタン if (work->file_exist) { - // w肳ꂽt@C݂ꍇ Enable + // 指定されたファイルが存在する場合は Enable EnableWindow(GetDlgItem(Dialog, IDC_APPEND), TRUE); } else { - // w肳ꂽt@C݂Ȃꍇ Disable + // 指定されたファイルが存在しない場合は Disable EnableWindow(GetDlgItem(Dialog, IDC_APPEND), FALSE); } @@ -176,43 +179,43 @@ static void ArrangeControls(HWND Dialog, LogDlgWork_t *work) // BOM, Encoding if (!log_binary && new_overwrite) { - // Text New/Overwrite ̏ꍇ Enable + // Text かつ New/Overwrite の場合に Enable EnableWindow(GetDlgItem(Dialog, IDC_BOM), TRUE); EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), TRUE); } else { - // łȂꍇ Disable - // BOM ̓t@C̐擪珑ނƂӖȂ - // Encoding ͒NjLłӖ邪At@C̃GR[fBO - // IɃ_CAOɔf̂ŁA[Uɂw͂Ȃ + // そうでない場合に Disable + // BOM はファイルの先頭から書き込むときしか意味がない + // Encoding は追記でも意味があるが、既存ファイルのエンコーディングを + // 強制的にダイアログに反映するので、ユーザによる指定はさせない EnableWindow(GetDlgItem(Dialog, IDC_BOM), FALSE); EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE); } - // Plain Text, Timestamp, Timestamp + // Plain Text, Timestamp, Timestamp 種別 if (log_binary) { - // Binary ̏ꍇ Disable + // Binary の場合は Disable DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_PLAINTEXT); DisableDlgItem(Dialog, IDC_TIMESTAMP, IDC_TIMESTAMP); DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE); } else { - // Text ̏ꍇ Enable + // Text の場合は Enable EnableDlgItem(Dialog, IDC_PLAINTEXT, IDC_PLAINTEXT); EnableDlgItem(Dialog, IDC_TIMESTAMP, IDC_TIMESTAMP); - // Timestamp + // Timestamp 種別 if (IsDlgButtonChecked(Dialog, IDC_TIMESTAMP) == BST_UNCHECKED) { - // Timestamp=off ̏ꍇ Disable + // Timestamp=off の場合は Disable DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE); } else { - // Timestamp=on ̏ꍇ Enable + // Timestamp=on の場合は Enable EnableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE); } } if (work->file_exist && !new_overwrite) { - // t@C̃GR[fBO𔽉f + // 既存ファイルのエンコーディングを反映する int bom = work->current_bom; int cur = bom == 1 ? 0 : @@ -263,7 +266,7 @@ static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPAR LogDlgWork_t *work = (LogDlgWork_t *)GetWindowLongPtr(Dialog, DWLP_USER); if (Message == RegisterWindowMessage(HELPMSGSTRING)) { - // R_CAÕwvbZ[Wtւ + // コモンダイアログからのヘルプメッセージを付け替える Message = WM_COMMAND; wParam = IDHELP; } @@ -291,7 +294,7 @@ static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPAR // timestamp CheckDlgButton(Dialog, IDC_TIMESTAMP, pts->LogTimestamp == 0 ? BST_UNCHECKED : BST_CHECKED); - // timestamp + // timestamp 種別 int tstype = pts->LogTimestampType == TIMESTAMP_LOCAL ? 0 : pts->LogTimestampType == TIMESTAMP_UTC ? 1 : pts->LogTimestampType == TIMESTAMP_ELAPSED_LOGSTART ? 2 : @@ -301,12 +304,12 @@ static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPAR // plain text CheckDlgButton(Dialog, IDC_PLAINTEXT, pts->LogTypePlainText == 0 ? BST_UNCHECKED : BST_CHECKED); - // Hide dialog `FbN{bNX + // Hide dialog チェックボックス if (pts->LogHideDialog) { SetRB(Dialog, 1, IDC_HIDEDIALOG, IDC_HIDEDIALOG); } - // Include screen buffer `FbN{bNX + // Include screen buffer チェックボックス if (pts->LogAllBuffIncludedInFirst) { SetRB(Dialog, 1, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST); } @@ -314,16 +317,19 @@ static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPAR // text/binary radio button CheckRadioButton(Dialog, IDC_FOPTBIN, IDC_FOPTTEXT, pts->LogBinary == 0 ? IDC_FOPTTEXT : IDC_FOPTBIN); - // t@Cݒ肷 - // t@C̃`FbNARg[̐ݒs - // WM_COMMAND, EN_CHANGE + // ファイル名を設定する + // ファイルのチェック、コントロールの設定も行われる + // WM_COMMAND, EN_CHANGE が発生する wchar_t *fname = FLogGetLogFilename(work->info->filename); SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, fname); - free(fname); HWND file_edit = GetDlgItem(Dialog, IDC_FOPT_FILENAME_EDIT); SetWindowLongPtr(file_edit, GWLP_USERDATA, (LONG_PTR)work); work->proc = (WNDPROC)SetWindowLongPtrW(file_edit, GWLP_WNDPROC, (LONG_PTR)FNameEditProc); + HistoryStoreSetControl(hs, Dialog, IDC_FOPT_FILENAME_EDIT); + ExpandCBWidth(Dialog, IDC_FOPT_FILENAME_EDIT); + free(fname); + CenterWindow(Dialog, GetParent(Dialog)); SetFocus(GetDlgItem(Dialog, IDC_FOPT_FILENAME_EDIT)); @@ -413,12 +419,12 @@ static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPAR free(filename); if (work->on_initdialog || file_exist_prev != work->file_exist) { if (work->file_exist) { - // t@C݂Aݒɍ킹ĐVK(㏑)/NjLI + // ファイルが存在する、設定に合わせて新規(上書き)/追記を選択する CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, work->pts->Append == 0 ? IDC_NEW_OVERWRITE : IDC_APPEND); } else { - // t@C݂ȂAVKI + // ファイルが存在しない、新規を選択する CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_NEW_OVERWRITE); } ArrangeControls(Dialog, work); @@ -428,7 +434,7 @@ static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPAR } break; case WM_DROPFILES: { - // hbvĂŏ1‚ + // 複数ドロップされても最初の1つだけを扱う HDROP hDrop = (HDROP)wParam; wchar_t *filename; hDragQueryFileW(hDrop, 0, &filename); @@ -462,14 +468,18 @@ static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPAR } /** - * O_CAOJ - * @param[in,out] info.filename t@Cl - * OKAt@CAsvɂȂfree()邱 - * @retval TRUE [ok] ꂽ - * @retval FALSE LZꂽ + * ログダイアログを開く + * @param[in,out] info.filename ファイル名初期値 + * OK時、ファイル名、不要になったらfree()すること + * @retval TRUE [ok] が押された + * @retval FALSE キャンセルされた */ BOOL FLogOpenDialog(HINSTANCE hInst_, HWND hWnd, FLogDlgInfo_t *info) { + if (hs == NULL) { + hs = HistoryStoreCreate(20); + } + LogDlgWork_t *work = (LogDlgWork_t *)calloc(1, sizeof(LogDlgWork_t)); work->info = info; work->pts = info->pts; @@ -478,5 +488,19 @@ BOOL FLogOpenDialog(HINSTANCE hInst_, HWND hWnd, FLogDlgInfo_t *info) hInst_, MAKEINTRESOURCEW(IDD_LOGDLG), hWnd, LogFnHook, (LPARAM)work); free(work); - return ret == IDOK ? TRUE : FALSE; + if (ret == IDOK) { + HistoryStoreAddTop(hs, info->filename, FALSE); + return TRUE; + } + else { + return FALSE; + } +} + +void FLogOpenDialogUnInit(void) +{ + if (hs != NULL) { + HistoryStoreDestroy(hs); + hs = NULL; + } } diff --git a/teraterm/teraterm/logdlg.h b/teraterm/teraterm/logdlg.h index e798b4dde..dbe5f1e60 100644 --- a/teraterm/teraterm/logdlg.h +++ b/teraterm/teraterm/logdlg.h @@ -40,3 +40,4 @@ typedef struct { } FLogDlgInfo_t; BOOL FLogOpenDialog(HINSTANCE hInst, HWND hWnd, FLogDlgInfo_t *info); +void FLogOpenDialogUnInit(void); diff --git a/teraterm/teraterm/sendfiledlg.cpp b/teraterm/teraterm/sendfiledlg.cpp index 47870b0ec..c54877212 100644 --- a/teraterm/teraterm/sendfiledlg.cpp +++ b/teraterm/teraterm/sendfiledlg.cpp @@ -44,6 +44,7 @@ #include "win32helper.h" #include "tipwin2.h" #include "sendmem.h" +#include "history_store.h" #include "sendfiledlg.h" @@ -54,6 +55,8 @@ typedef struct { UINT MsgDlgHelp; } SendFileDlgWork_t; +static HistoryStore *hs; + static void ArrangeControls(HWND hDlgWnd) { LRESULT index = SendDlgItemMessageA(hDlgWnd, IDC_SENDFILE_DELAYTYPE_DROPDOWN, CB_GETCURSEL, 0, 0); @@ -145,9 +148,11 @@ static INT_PTR CALLBACK SendFileDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARA data->UILanguageFileW, data->delay_type); if (data->initial_file != NULL) { - SetDlgItemTextW(hDlgWnd, IDC_SENDFILE_FILENAME_EDIT, data->initial_file); + HistoryStoreAddTop(hs, data->initial_file, FALSE); } + HistoryStoreSetControl(hs, hDlgWnd, IDC_SENDFILE_FILENAME_EDIT); + // MTCY for (size_t i = 0; i < _countof(send_size_list); i++) { char buf[32]; @@ -201,6 +206,7 @@ static INT_PTR CALLBACK SendFileDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARA return TRUE; } + HistoryStoreAddTop(hs, filename, FALSE); data->filename = filename; data->binary = IsDlgButtonChecked(hDlgWnd, IDC_SENDFILE_CHECK_BINARY) == BST_CHECKED ? TRUE : FALSE; @@ -285,6 +291,10 @@ static INT_PTR CALLBACK SendFileDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARA INT_PTR sendfiledlg(HINSTANCE hInstance, HWND hWndParent, sendfiledlgdata *data) { + if (hs == NULL) { + hs = HistoryStoreCreate(20); + } + BOOL skip_dialog = data->skip_dialog; if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) { skip_dialog = !skip_dialog; @@ -305,3 +315,11 @@ INT_PTR sendfiledlg(HINSTANCE hInstance, HWND hWndParent, sendfiledlgdata *data) return Ok ? (INT_PTR)IDOK : (INT_PTR)IDCANCEL; } } + +void sendfiledlgUnInit(void) +{ + if (hs != NULL) { + HistoryStoreDestroy(hs); + hs = NULL; + } +} diff --git a/teraterm/teraterm/sendfiledlg.h b/teraterm/teraterm/sendfiledlg.h index f6a3371d9..462d87da7 100644 --- a/teraterm/teraterm/sendfiledlg.h +++ b/teraterm/teraterm/sendfiledlg.h @@ -53,6 +53,7 @@ typedef struct { } sendfiledlgdata; INT_PTR sendfiledlg(HINSTANCE hInstance, HWND hWndParent, sendfiledlgdata *data); +void sendfiledlgUnInit(void); #ifdef __cplusplus } diff --git a/teraterm/teraterm/ttermpro.rc b/teraterm/teraterm/ttermpro.rc index 32335d3c2..eef09c2df 100644 --- a/teraterm/teraterm/ttermpro.rc +++ b/teraterm/teraterm/ttermpro.rc @@ -347,7 +347,7 @@ CAPTION "Send file" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "&Filename (drop file in this dialog)",IDC_SENDFILE_FILENAME_TITLE,9,7,172,8 - EDITTEXT IDC_SENDFILE_FILENAME_EDIT,18,21,228,14,ES_AUTOHSCROLL + COMBOBOX IDC_SENDFILE_FILENAME_EDIT,18,21,228,93,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "...",IDC_SENDFILE_FILENAME_BUTTON,251,21,14,14 CONTROL "Send in same way as Tera Term 4",IDC_SENDFILE_CHECK_4, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,42,124,10 diff --git a/teraterm/teraterm/vtwin.cpp b/teraterm/teraterm/vtwin.cpp index f8a2c7e2b..5b92d3fb1 100644 --- a/teraterm/teraterm/vtwin.cpp +++ b/teraterm/teraterm/vtwin.cpp @@ -1495,6 +1495,8 @@ void CVTWindow::OnDestroy() EndTerm(); EndDisp(); + sendfiledlgUnInit(); + FLogOpenDialogUnInit(); FreeBuffer(); diff --git a/teraterm/ttpset/ttset.c b/teraterm/ttpset/ttset.c index 19c79a259..51aa06c9a 100644 --- a/teraterm/ttpset/ttset.c +++ b/teraterm/ttpset/ttset.c @@ -57,6 +57,7 @@ #include "compat_win.h" #include "vtdisp.h" #include "makeoutputstring.h" +#include "history_store.h" #define DllExport __declspec(dllexport) #include "ttset.h" @@ -3328,11 +3329,6 @@ void PASCAL _CopySerialList(const wchar_t *IniSrc, const wchar_t *IniDest, const void PASCAL _AddValueToList(const wchar_t *FName, const wchar_t *Host, const wchar_t *section, const wchar_t *key, int MaxList) { - int ent_no; - int host_index; - BOOL Update; - wchar_t **hostnames; - if ((FName[0] == 0) || (Host[0] == 0)) return; @@ -3340,81 +3336,12 @@ void PASCAL _AddValueToList(const wchar_t *FName, const wchar_t *Host, const wch return; } - hostnames = (wchar_t **)calloc(MaxList, sizeof(wchar_t *)); - if (hostnames == NULL) { - return; + HistoryStore *hs = HistoryStoreCreate(MaxList); + HistoryStoreReadIni(hs, FName, section, key); + if (HistoryStoreAddTop(hs, Host, FALSE)) { + HistoryStoreSaveIni(hs, FName, section, key); } - - hostnames[0] = _wcsdup(Host); - ent_no = 1; - host_index = 1; - Update = TRUE; - do { - wchar_t *EntName; - wchar_t *hostname; - - aswprintf(&EntName, L"%s%i", key, ent_no); - /* Get a hostname */ - hGetPrivateProfileStringW(section, EntName, L"", FName, &hostname); - free(EntName); - - if (hostname == NULL || hostname[0] == L'\0') { - // lZbgĂȂ = Ō܂œǂݍ - // hostname[0] == L'\0' ̂Ƃ L"" free() Kv - free(hostname); - break; - } - else if (_wcsicmp(hostname, Host) == 0) { - // ̂ƃXgɉȂ - if (host_index == 1) { - // 擪ꂾXVsv - Update = FALSE; - } - free(hostname); - } - else { - hostnames[host_index] = hostname; - host_index++; - } - ent_no++; - } while ((ent_no <= MaxList) && Update); - - if (Update) { - // sectionS - WritePrivateProfileStringW(section, NULL, NULL, FName); - - ent_no = 1; - host_index = 0; - do { - wchar_t *EntName; - wchar_t *hostname; - - hostname = hostnames[host_index]; - if (hostname == NULL) { - break; - } - aswprintf(&EntName, L"%s%i", key, ent_no); - WritePrivateProfileStringW(section, EntName, hostname, FName); - free(EntName); - host_index++; - ent_no++; - } while (ent_no <= MaxList); - - /* update file */ - WritePrivateProfileStringW(NULL, NULL, NULL, FName); - } - - host_index = 0; - do { - wchar_t *hostname = hostnames[host_index]; - if (hostname == NULL) { - break; - } - free(hostname); - hostnames[host_index] = NULL; - host_index++; - } while (host_index < MaxList); - free(hostnames); + HistoryStoreDestroy(hs); } /* copy hostlist from source IniFile to dest IniFile */