summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-03-25 15:33:17 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-03-25 15:33:17 +0300
commit983c5ac518db7fce3143c05d590813222bfa2625 (patch)
treef3a498eb4ab906b37ae720a63f0385606f667c26 /src
parentacdaebe9729b0d50168ff51657f1b8220302d82a (diff)
EnterString dialog -> UI classes (also fixes crash in #2803)
Diffstat (limited to 'src')
-rw-r--r--src/mir_app/src/enterstring.cpp385
1 files changed, 199 insertions, 186 deletions
diff --git a/src/mir_app/src/enterstring.cpp b/src/mir_app/src/enterstring.cpp
index 0614ab882a..c4acdceac8 100644
--- a/src/mir_app/src/enterstring.cpp
+++ b/src/mir_app/src/enterstring.cpp
@@ -24,11 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stdafx.h"
-struct EnterStringFormParam : public ENTER_STRING
-{
- int idcControl;
- int height;
-};
+#define WM_MODULE_UNLOAD (WM_USER + 1)
static int UIEmulateBtnClick(HWND hwndDlg, UINT idcButton)
{
@@ -37,230 +33,247 @@ static int UIEmulateBtnClick(HWND hwndDlg, UINT idcButton)
return 0;
}
-static int sttEnterStringResizer(HWND, LPARAM, UTILRESIZECONTROL *urc)
+struct CCtrlMemo : public CCtrlRichEdit
{
- switch (urc->wId) {
- case IDC_TXT_MULTILINE:
- case IDC_TXT_COMBO:
- case IDC_TXT_RICHEDIT:
- return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
-
- case IDOK:
- case IDCANCEL:
- return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
+ CCtrlMemo(CDlgBase *dlg, int ctrlId) :
+ CCtrlRichEdit(dlg, ctrlId)
+ {}
+
+ BOOL OnNotify(int, NMHDR *pnmhdr) override
+ {
+ ENLINK *param = (ENLINK *)pnmhdr;
+ if (pnmhdr->code == EN_LINK && param->msg == WM_LBUTTONUP) {
+ CHARRANGE sel;
+ SendMessage(param->nmhdr.hwndFrom, EM_EXGETSEL, 0, (LPARAM)&sel);
+ if (sel.cpMin == sel.cpMax) { // allow link selection
+ TEXTRANGE tr;
+ tr.chrg = param->chrg;
+ tr.lpstrText = (wchar_t *)mir_alloc(sizeof(wchar_t) * (tr.chrg.cpMax - tr.chrg.cpMin + 2));
+ SendMessage(param->nmhdr.hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
+
+ Utils_OpenUrlW(tr.lpstrText);
+ mir_free(tr.lpstrText);
+ }
+ return TRUE;
+ }
+ return FALSE;
}
- return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
-}
+};
-static void ComboLoadRecentStrings(HWND hwndDlg, EnterStringFormParam *pForm)
+class CEnterStringDlg : public CDlgBase
{
- for (int i = 0; i < pForm->recentCount; i++) {
- char setting[MAXMODULELABELLENGTH];
- mir_snprintf(setting, "%s%d", pForm->szDataPrefix, i);
- ptrW tszRecent(db_get_wsa(0, pForm->szModuleName, setting));
- if (tszRecent != nullptr)
- SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_ADDSTRING, 0, tszRecent);
+ int idcControl = 0;
+ HANDLE m_hEvent = nullptr;
+ ENTER_STRING m_param;
+
+ void ComboLoadRecentStrings()
+ {
+ for (int i = 0; i < m_param.recentCount; i++) {
+ char setting[MAXMODULELABELLENGTH];
+ mir_snprintf(setting, "%s%d", m_param.szDataPrefix, i);
+ ptrW tszRecent(db_get_wsa(0, m_param.szModuleName, setting));
+ if (tszRecent != nullptr)
+ combo.AddString(tszRecent);
+ }
+
+ if (!combo.GetCount())
+ combo.AddString(L"");
}
- if (!SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_GETCOUNT, 0, 0))
- SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_ADDSTRING, 0, (LPARAM)L"");
-}
+ void ComboAddRecentString()
+ {
+ wchar_t *string = m_param.ptszResult;
+ if (!string || !*string)
+ return;
-static void ComboAddRecentString(HWND hwndDlg, EnterStringFormParam *pForm)
-{
- wchar_t *string = pForm->ptszResult;
- if (!string || !*string)
- return;
-
- if (SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_FINDSTRING, (WPARAM)-1, (LPARAM)string) != CB_ERR)
- return;
-
- int id;
- SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_ADDSTRING, 0, (LPARAM)string);
- if ((id = SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_FINDSTRING, (WPARAM)-1, (LPARAM)L"")) != CB_ERR)
- SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_DELETESTRING, id, 0);
-
- id = db_get_b(0, pForm->szModuleName, pForm->szDataPrefix, 0);
- char setting[MAXMODULELABELLENGTH];
- mir_snprintf(setting, "%s%d", pForm->szDataPrefix, id);
- db_set_ws(0, pForm->szModuleName, setting, string);
- db_set_b(0, pForm->szModuleName, pForm->szDataPrefix, (id + 1) % pForm->idcControl);
-}
+ if (combo.FindString(string) != -1)
+ return;
-static INT_PTR CALLBACK sttEnterStringDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- EnterStringFormParam *params = (EnterStringFormParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- Window_SetSkinIcon_IcoLib(hwndDlg, SKINICON_OTHER_RENAME);
- params = (EnterStringFormParam *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)params);
- SetWindowText(hwndDlg, params->caption);
- {
- RECT rc; GetWindowRect(hwndDlg, &rc);
- switch (params->type) {
- case ESF_PASSWORD:
- params->idcControl = IDC_TXT_PASSWORD;
- params->height = rc.bottom - rc.top;
- break;
-
- case ESF_MULTILINE:
- params->idcControl = IDC_TXT_MULTILINE;
- params->height = 0;
- rc.bottom += (rc.bottom - rc.top) * 2;
- SetWindowPos(hwndDlg, nullptr, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOREPOSITION);
- break;
-
- case ESF_COMBO:
- params->idcControl = IDC_TXT_COMBO;
- params->height = rc.bottom - rc.top;
- if (params->szDataPrefix && params->recentCount)
- ComboLoadRecentStrings(hwndDlg, params);
- break;
-
- case ESF_RICHEDIT:
- params->idcControl = IDC_TXT_RICHEDIT;
- SendDlgItemMessage(hwndDlg, IDC_TXT_RICHEDIT, EM_AUTOURLDETECT, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_TXT_RICHEDIT, EM_SETEVENTMASK, 0, ENM_LINK);
- params->height = 0;
- rc.bottom += (rc.bottom - rc.top) * 2;
- SetWindowPos(hwndDlg, nullptr, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOREPOSITION);
- break;
-
- default: // single string edit field
- params->idcControl = IDC_TXT_SIMPLE;
- params->height = rc.bottom - rc.top;
- }
- }
- ShowWindow(GetDlgItem(hwndDlg, params->idcControl), SW_SHOW);
- if (params->ptszInitVal)
- SetDlgItemText(hwndDlg, params->idcControl, params->ptszInitVal);
+ int id;
+ combo.AddString(string);
+ if ((id = combo.FindString(L"")) != CB_ERR)
+ combo.DeleteString(id);
+
+ id = db_get_b(0, m_param.szModuleName, m_param.szDataPrefix, 0);
+ char setting[MAXMODULELABELLENGTH];
+ mir_snprintf(setting, "%s%d", m_param.szDataPrefix, id);
+ db_set_ws(0, m_param.szModuleName, setting, string);
+ db_set_b(0, m_param.szModuleName, m_param.szDataPrefix, (id + 1) % idcControl);
+ }
- if (params->szDataPrefix)
- Utils_RestoreWindowPosition(hwndDlg, 0, params->szModuleName, params->szDataPrefix);
+ LRESULT onModuleUnload(UINT, WPARAM wParam, LPARAM)
+ {
+ auto *pPlugin = (HPLUGIN)wParam;
+ if (!mir_strcmp(m_param.szModuleName, pPlugin->getModule()))
+ EndModal(0);
+ return 0;
+ }
- SetTimer(hwndDlg, 1000, 50, nullptr);
+ UI_MESSAGE_MAP(CEnterStringDlg, CDlgBase);
+ UI_MESSAGE(WM_MODULE_UNLOAD, onModuleUnload);
+ UI_MESSAGE_MAP_END();
+
+ CTimer m_timer1, m_timer2;
+ CCtrlEdit edit1, edit2;
+ CCtrlMemo memo;
+ CCtrlCombo combo;
+
+public:
+ CEnterStringDlg(const ENTER_STRING &param) :
+ CDlgBase(g_plugin, IDD_ENTER_STRING),
+ m_param(param),
+ memo(this, IDC_TXT_RICHEDIT),
+ edit1(this, IDC_TXT_SIMPLE),
+ edit2(this, IDC_TXT_MULTILINE),
+ combo(this, IDC_TXT_COMBO),
+ m_timer1(this, 1001),
+ m_timer2(this, 1002)
+ {
+ m_timer1.OnEvent = Callback(this, &CEnterStringDlg::onTimer1);
+ m_timer2.OnEvent = Callback(this, &CEnterStringDlg::onTimer2);
+
+ memo.OnChange = edit1.OnChange = edit2.OnChange = combo.OnChange = Callback(this, &CEnterStringDlg::onChange_Field);
+ }
- if (params->timeout > 0) {
- SetTimer(hwndDlg, 1001, 1000, nullptr);
- wchar_t buf[128];
- mir_snwprintf(buf, TranslateT("OK (%d)"), params->timeout);
- SetDlgItemText(hwndDlg, IDOK, buf);
- }
+ bool OnInitDialog() override
+ {
+ Window_SetSkinIcon_IcoLib(m_hwnd, SKINICON_OTHER_RENAME);
+ SetCaption(m_param.caption);
- return TRUE;
+ RECT rc;
+ GetWindowRect(m_hwnd, &rc);
- case WM_DESTROY:
- Window_FreeIcon_IcoLib(hwndDlg);
- break;
+ if (m_param.szModuleName)
+ m_hEvent = HookEventMessage(ME_SYSTEM_MODULEUNLOAD, m_hwnd, WM_MODULE_UNLOAD);
- case WM_TIMER:
- switch (wParam) {
- case 1000:
- KillTimer(hwndDlg, 1000);
- EnableWindow(GetParent(hwndDlg), TRUE);
+ switch (m_param.type) {
+ case ESF_PASSWORD:
+ idcControl = IDC_TXT_PASSWORD;
+ SetMinSize(rc.right - rc.left, rc.bottom - rc.top);
break;
- case 1001:
- wchar_t buf[128];
- mir_snwprintf(buf, TranslateT("OK (%d)"), --params->timeout);
- SetDlgItemText(hwndDlg, IDOK, buf);
+ case ESF_MULTILINE:
+ idcControl = IDC_TXT_MULTILINE;
+ rc.bottom += (rc.bottom - rc.top) * 2;
+ SetWindowPos(m_hwnd, nullptr, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOREPOSITION);
+ break;
- if (params->timeout < 0) {
- KillTimer(hwndDlg, 1001);
- UIEmulateBtnClick(hwndDlg, IDOK);
- }
- }
- return TRUE;
+ case ESF_COMBO:
+ idcControl = IDC_TXT_COMBO;
+ SetMinSize(rc.right - rc.left, rc.bottom - rc.top);
+ if (m_param.szDataPrefix && m_param.recentCount)
+ ComboLoadRecentStrings();
+ break;
- case WM_SIZE:
- Utils_ResizeDialog(hwndDlg, g_plugin.getInst(), MAKEINTRESOURCEA(IDD_ENTER_STRING), sttEnterStringResizer);
- break;
+ case ESF_RICHEDIT:
+ idcControl = IDC_TXT_RICHEDIT;
+ SendDlgItemMessage(m_hwnd, IDC_TXT_RICHEDIT, EM_AUTOURLDETECT, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_TXT_RICHEDIT, EM_SETEVENTMASK, 0, ENM_LINK);
+ rc.bottom += (rc.bottom - rc.top) * 2;
+ SetWindowPos(m_hwnd, nullptr, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOREPOSITION);
+ break;
- case WM_GETMINMAXINFO:
- {
- LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam;
- if (params && params->height)
- lpmmi->ptMaxSize.y = lpmmi->ptMaxTrackSize.y = params->height;
+ default: // single string edit field
+ idcControl = IDC_TXT_SIMPLE;
+ SetMinSize(rc.right - rc.left, rc.bottom - rc.top);
}
- break;
- case WM_NOTIFY:
- {
- ENLINK *param = (ENLINK *)lParam;
- if (param->nmhdr.idFrom != IDC_TXT_RICHEDIT) break;
- if (param->nmhdr.code != EN_LINK) break;
- if (param->msg != WM_LBUTTONUP) break;
+ ShowWindow(GetDlgItem(m_hwnd, idcControl), SW_SHOW);
+ if (m_param.ptszInitVal)
+ SetDlgItemText(m_hwnd, idcControl, m_param.ptszInitVal);
- CHARRANGE sel;
- SendMessage(param->nmhdr.hwndFrom, EM_EXGETSEL, 0, (LPARAM)& sel);
- if (sel.cpMin != sel.cpMax) break; // allow link selection
+ if (m_param.szDataPrefix)
+ Utils_RestoreWindowPosition(m_hwnd, 0, m_param.szModuleName, m_param.szDataPrefix);
- TEXTRANGE tr;
- tr.chrg = param->chrg;
- tr.lpstrText = (wchar_t *)mir_alloc(sizeof(wchar_t)*(tr.chrg.cpMax - tr.chrg.cpMin + 2));
- SendMessage(param->nmhdr.hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
+ SetTimer(m_hwnd, 1000, 50, nullptr);
- Utils_OpenUrlW(tr.lpstrText);
- mir_free(tr.lpstrText);
+ if (m_param.timeout > 0) {
+ m_timer2.Start(1000);
+
+ wchar_t buf[128];
+ mir_snwprintf(buf, TranslateT("OK (%d)"), m_param.timeout);
+ SetDlgItemText(m_hwnd, IDOK, buf);
}
- return TRUE;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_TXT_MULTILINE:
- case IDC_TXT_RICHEDIT:
- if ((HIWORD(wParam) != EN_SETFOCUS) && (HIWORD(wParam) != EN_KILLFOCUS)) {
- SetDlgItemText(hwndDlg, IDOK, TranslateT("OK"));
- KillTimer(hwndDlg, 1001);
- }
- break;
+ return true;
+ }
- case IDC_TXT_COMBO:
- if ((HIWORD(wParam) != CBN_SETFOCUS) && (HIWORD(wParam) != CBN_KILLFOCUS)) {
- SetDlgItemText(hwndDlg, IDOK, TranslateT("OK"));
- KillTimer(hwndDlg, 1001);
- }
- break;
+ bool OnApply() override
+ {
+ HWND hWnd = GetDlgItem(m_hwnd, idcControl);
+ int len = GetWindowTextLength(hWnd)+1;
+ m_param.ptszResult = (LPTSTR)mir_alloc(sizeof(wchar_t)*len);
+ GetWindowText(hWnd, m_param.ptszResult, len);
- case IDCANCEL:
- if (params->szDataPrefix)
- Utils_SaveWindowPosition(hwndDlg, 0, params->szModuleName, params->szDataPrefix);
+ if ((m_param.type == ESF_COMBO) && m_param.szDataPrefix && m_param.recentCount)
+ ComboAddRecentString();
+ return true;
+ }
- EndDialog(hwndDlg, 0);
- break;
+ void OnDestroy() override
+ {
+ if (m_param.szDataPrefix)
+ Utils_SaveWindowPosition(m_hwnd, 0, m_param.szModuleName, m_param.szDataPrefix);
+
+ Window_FreeIcon_IcoLib(m_hwnd);
+ UnhookEvent(m_hEvent);
+ }
+
+ int Resizer(UTILRESIZECONTROL *urc) override
+ {
+ switch (urc->wId) {
+ case IDC_TXT_MULTILINE:
+ case IDC_TXT_COMBO:
+ case IDC_TXT_RICHEDIT:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
case IDOK:
- HWND hWnd = GetDlgItem(hwndDlg, params->idcControl);
- int len = GetWindowTextLength(hWnd)+1;
- params->ptszResult = (LPTSTR)mir_alloc(sizeof(wchar_t)*len);
- GetWindowText(hWnd, params->ptszResult, len);
+ case IDCANCEL:
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
+ }
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
+ }
+
+ void onTimer1(CTimer *)
+ {
+ m_timer1.Stop();
+ EnableWindow(GetParent(m_hwnd), TRUE);
+ }
- if ((params->type == ESF_COMBO) && params->szDataPrefix && params->recentCount)
- ComboAddRecentString(hwndDlg, params);
- if (params->szDataPrefix)
- Utils_SaveWindowPosition(hwndDlg, 0, params->szModuleName, params->szDataPrefix);
+ void onTimer2(CTimer *)
+ {
+ wchar_t buf[128];
+ mir_snwprintf(buf, TranslateT("OK (%d)"), --m_param.timeout);
+ SetDlgItemText(m_hwnd, IDOK, buf);
- EndDialog(hwndDlg, 1);
- break;
+ if (m_param.timeout < 0) {
+ m_timer1.Stop();
+ UIEmulateBtnClick(m_hwnd, IDOK);
}
}
- return FALSE;
-}
+ void onChange_Field(CCtrlData*)
+ {
+ SetDlgItemText(m_hwnd, IDOK, TranslateT("OK"));
+ m_timer1.Stop();
+ }
+
+ wchar_t* GetResult() const
+ {
+ return m_param.ptszResult;
+ }
+};
MIR_APP_DLL(bool) EnterString(ENTER_STRING *pForm)
{
if (pForm == nullptr)
return false;
- EnterStringFormParam param = {};
- memcpy(&param, pForm, sizeof(ENTER_STRING));
- if (!DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_ENTER_STRING), GetForegroundWindow(), sttEnterStringDlgProc, LPARAM(&param)))
+ CEnterStringDlg dlg(*pForm);
+ dlg.SetParent(GetForegroundWindow());
+ if (!dlg.DoModal())
return false;
- pForm->ptszResult = param.ptszResult;
+ pForm->ptszResult = dlg.GetResult();
return true;
}