From f4584ad861c7cdb444a2145d8472754af492aa2d Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 23 Nov 2016 22:47:05 +0300 Subject: options dialog - last call of CreateDialogParam in mir_app.dll --- src/mir_app/src/miranda.h | 4 - src/mir_app/src/options.cpp | 1700 +++++++++++++++++++++---------------------- src/mir_app/src/sounds.cpp | 18 + 3 files changed, 849 insertions(+), 873 deletions(-) (limited to 'src/mir_app') diff --git a/src/mir_app/src/miranda.h b/src/mir_app/src/miranda.h index 3f3888f216..a440c951ad 100644 --- a/src/mir_app/src/miranda.h +++ b/src/mir_app/src/miranda.h @@ -90,10 +90,6 @@ __forceinline char* Utf8DecodeA(const char* src) #pragma optimize("", on) -/**** options.cpp **********************************************************************/ - -HTREEITEM FindNamedTreeItemAtRoot(HWND hwndTree, const wchar_t* name); - /**** skinicons.cpp ********************************************************************/ extern int g_iIconX, g_iIconY, g_iIconSX, g_iIconSY; diff --git a/src/mir_app/src/options.cpp b/src/mir_app/src/options.cpp index e2d7c54df1..9d4d497954 100644 --- a/src/mir_app/src/options.cpp +++ b/src/mir_app/src/options.cpp @@ -26,22 +26,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" #include "filter.h" +#define OPTSTATE_PREFIX "s_" + #define FILTER_TIMEOUT_TIMER 10012 +#define HM_MODULELOAD (WM_USER+12) +#define HM_MODULEUNLOAD (WM_USER+13) + #define ALL_MODULES_FILTER LPGENW("") #define CORE_MODULES_FILTER LPGENW("") int LangpackOptionsInit(WPARAM, LPARAM); static HANDLE hOptionsInitEvent; -static HWND hwndOptions = NULL; -static HWND hFilterSearchWnd = NULL; +static class COptionsDlg *pOptionsDlg = NULL; // Thread for search keywords in dialogs static BYTE bSearchState = 0; // 0 - not executed; 1 - in progress; 2 - completed; -static int FilterPage = 0; static int FilterLoadProgress = 100; -static int FilterTimerId = 0; struct OptionsPage : public OPTIONSDIALOGPAGE { @@ -57,12 +59,112 @@ struct OptionsPage : public OPTIONSDIALOGPAGE typedef OBJLIST OptionsPageList; -struct OPENOPTIONSDIALOG +static BOOL CALLBACK BoldGroupTitlesEnumChildren(HWND hwnd, LPARAM lParam) { - const wchar_t *pszGroup, *pszPage, *pszTab; -}; + wchar_t szClass[64]; + GetClassName(hwnd, szClass, _countof(szClass)); + + if (!mir_wstrcmp(szClass, L"Button") && (GetWindowLongPtr(hwnd, GWL_STYLE) & 0x0F) == BS_GROUPBOX) + SendMessage(hwnd, WM_SETFONT, lParam, 0); + return TRUE; +} + +static void ThemeDialogBackground(HWND hwnd, BOOL tabbed) +{ + EnableThemeDialogTexture(hwnd, (tabbed ? ETDT_ENABLE : ETDT_DISABLE) | ETDT_USETABTEXTURE); +} + +static wchar_t* GetPluginName(HINSTANCE hInstance, wchar_t *buffer, int size) +{ + wchar_t tszModuleName[MAX_PATH]; + GetModuleFileName(hInstance, tszModuleName, _countof(tszModuleName)); + wchar_t *dllName = wcsrchr(tszModuleName, '\\'); + if (!dllName) + dllName = tszModuleName; + else + dllName++; + + wcsncpy_s(buffer, size, dllName, _TRUNCATE); + return buffer; +} + +static BOOL IsAeroMode() +{ + BOOL result; + return dwmIsCompositionEnabled && (dwmIsCompositionEnabled(&result) == S_OK) && result; +} + +static LRESULT CALLBACK AeroPaintSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +static void AeroPaintControl(HWND hwnd, HDC hdc, UINT msg, LPARAM lpFlags) +{ + RECT rc; + GetClientRect(hwnd, &rc); + + HDC tempDC = CreateCompatibleDC(hdc); + + BITMAPINFO bmi = { 0 }; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = rc.right; + bmi.bmiHeader.biHeight = -rc.bottom; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + BYTE *pBits; + HBITMAP hBmp = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0); + HBITMAP hOldBmp = (HBITMAP)SelectObject(tempDC, hBmp); + + // paint + SetPropA(hwnd, "Miranda.AeroRender.Active", (HANDLE)TRUE); + mir_callNextSubclass(hwnd, AeroPaintSubclassProc, msg, (WPARAM)tempDC, lpFlags); + SetPropA(hwnd, "Miranda.AeroRender.Active", (HANDLE)FALSE); + + // Fix alpha channel + GdiFlush(); + for (int i = 0; i < rc.right*rc.bottom; i++, pBits += 4) + if (!pBits[3]) + pBits[3] = 255; + + // Copy to output + BitBlt(hdc, 0, 0, rc.right, rc.bottom, tempDC, 0, 0, SRCCOPY); + SelectObject(tempDC, hOldBmp); + DeleteObject(hBmp); + DeleteDC(tempDC); +} + +static LRESULT CALLBACK AeroPaintSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_CTLCOLOREDIT: + if (!GetPropA((HWND)lParam, "Miranda.AeroRender.Active")) + RedrawWindow((HWND)lParam, NULL, NULL, RDW_INVALIDATE); + break; + + case WM_ERASEBKGND: + return TRUE; + + case WM_PRINT: + case WM_PRINTCLIENT: + AeroPaintControl(hwnd, (HDC)wParam, msg, lParam); + return TRUE; + + case WM_DESTROY: + RemovePropA(hwnd, "Miranda.AeroRender.Active"); + break; + + case WM_PAINT: + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + AeroPaintControl(hwnd, hdc, WM_PRINT, PRF_CLIENT | PRF_NONCLIENT); + EndPaint(hwnd, &ps); + return TRUE; + } + return mir_callNextSubclass(hwnd, AeroPaintSubclassProc, msg, wParam, lParam); +} ///////////////////////////////////////////////////////////////////////////////////////// +// Stub for the old options (hinst + resource + window procedure + lParam) class COptionPageDialog : public CDlgBase { @@ -91,33 +193,36 @@ public: } }; +///////////////////////////////////////////////////////////////////////////////////////// +// One option page + struct OptionsPageData : public MZeroedObject { - OptionsPageData(OPTIONSDIALOGPAGE *src) + OptionsPageData(const OPTIONSDIALOGPAGE &src) { - if (src->hInstance != NULL && src->pszTemplate != NULL) - pDialog = new COptionPageDialog(src->hInstance, (INT_PTR)src->pszTemplate, src->pfnDlgProc, src->dwInitParam); + if (src.hInstance != NULL && src.pszTemplate != NULL) + pDialog = new COptionPageDialog(src.hInstance, (INT_PTR)src.pszTemplate, src.pfnDlgProc, src.dwInitParam); else - pDialog = src->pDialog; + pDialog = src.pDialog; assert(pDialog != NULL); - flags = src->flags; - hLangpack = src->hLangpack; + flags = src.flags; + hLangpack = src.hLangpack; - if (src->flags & ODPF_UNICODE) - ptszTitle = mir_wstrdup(src->szTitle.w); + if (src.flags & ODPF_UNICODE) + ptszTitle = mir_wstrdup(src.szTitle.w); else - ptszTitle = mir_a2u(src->szTitle.a); + ptszTitle = mir_a2u(src.szTitle.a); - if (src->flags & ODPF_UNICODE) - ptszGroup = mir_wstrdup(src->szGroup.w); + if (src.flags & ODPF_UNICODE) + ptszGroup = mir_wstrdup(src.szGroup.w); else - ptszGroup = mir_a2u(src->szGroup.a); + ptszGroup = mir_a2u(src.szGroup.a); - if (src->flags & ODPF_UNICODE) - ptszTab = mir_wstrdup(src->szTab.w); + if (src.flags & ODPF_UNICODE) + ptszTab = mir_wstrdup(src.szTab.w); else - ptszTab = mir_a2u(src->szTab.a); + ptszTab = mir_a2u(src.szTab.a); } ~OptionsPageData() @@ -145,156 +250,49 @@ struct OptionsPageData : public MZeroedObject return ptszStr; return TranslateW_LP(ptszStr, hLangpack); } -}; -struct OptionsDlgData : public MZeroedObject -{ - OptionsDlgData() : - arOpd(10) - {} - - int currentPage; - HTREEITEM hCurrentPage; - LIST arOpd; - RECT rcDisplay; - RECT rcTab; - HFONT hBoldFont; - wchar_t szFilterString[1024]; - HANDLE hPluginLoad, hPluginUnload; - - OptionsPageData* getCurrent() const - { return (currentPage == -1) ? NULL : arOpd[currentPage]; + HWND CreateOptionWindow(HWND hWndParent) const + { + pDialog->SetParent(hWndParent); + pDialog->Create(); + return pDialog->GetHwnd(); } -}; -HTREEITEM FindNamedTreeItemAtRoot(HWND hwndTree, const wchar_t* name) -{ - wchar_t str[128]; - TVITEM tvi; - tvi.mask = TVIF_TEXT; - tvi.pszText = str; - tvi.cchTextMax = _countof(str); - tvi.hItem = TreeView_GetRoot(hwndTree); - while (tvi.hItem != NULL) { - SendMessage(hwndTree, TVM_GETITEM, 0, (LPARAM)&tvi); - if (!mir_wstrcmpi(str, name)) - return tvi.hItem; - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return NULL; -} - -static HTREEITEM FindNamedTreeItemAtChildren(HWND hwndTree, HTREEITEM hItem, const wchar_t* name) -{ - wchar_t str[128]; - TVITEM tvi; - tvi.mask = TVIF_TEXT; - tvi.pszText = str; - tvi.cchTextMax = _countof(str); - tvi.hItem = TreeView_GetChild(hwndTree, hItem); - while (tvi.hItem != NULL) { - SendMessage(hwndTree, TVM_GETITEM, 0, (LPARAM)&tvi); - if (!mir_wstrcmpi(str, name)) - return tvi.hItem; - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); + PageHash GetPluginPageHash() const + { + return mir_hashstrW(ptszGroup) + mir_hashstrW(ptszTitle) + mir_hashstrW(ptszTab); } - return NULL; -} - -static BOOL CALLBACK BoldGroupTitlesEnumChildren(HWND hwnd, LPARAM lParam) -{ - wchar_t szClass[64]; - GetClassName(hwnd, szClass, _countof(szClass)); - - if (!mir_wstrcmp(szClass, L"Button") && (GetWindowLongPtr(hwnd, GWL_STYLE) & 0x0F) == BS_GROUPBOX) - SendMessage(hwnd, WM_SETFONT, lParam, 0); - return TRUE; -} - -#define OPTSTATE_PREFIX "s_" -static void SaveOptionsTreeState(HWND hdlg) -{ - TVITEMA tvi; - char buf[130], str[128]; - tvi.mask = TVIF_TEXT | TVIF_STATE; - tvi.pszText = str; - tvi.cchTextMax = _countof(str); - tvi.hItem = TreeView_GetRoot(GetDlgItem(hdlg, IDC_PAGETREE)); - while (tvi.hItem != NULL) { - if (SendDlgItemMessageA(hdlg, IDC_PAGETREE, TVM_GETITEMA, 0, (LPARAM)&tvi)) { - mir_snprintf(buf, "%s%s", OPTSTATE_PREFIX, str); - db_set_b(NULL, "Options", buf, (BYTE)((tvi.state & TVIS_EXPANDED) ? 1 : 0)); + void FindFilterStrings(int enableKeywordFiltering, int current, HWND hWndParent) + { + HWND hWnd = 0; + if (enableKeywordFiltering) { + if (current) + hWnd = getHwnd(); + else { + hWnd = CreateOptionWindow(hWndParent); + ShowWindow(hWnd, SW_HIDE); // make sure it's hidden + } } - tvi.hItem = TreeView_GetNextSibling(GetDlgItem(hdlg, IDC_PAGETREE), tvi.hItem); - } -} - -#define DM_FOCUSPAGE (WM_USER+10) -#define DM_REBUILDPAGETREE (WM_USER+11) - -#define HM_MODULELOAD (WM_USER+12) -#define HM_MODULEUNLOAD (WM_USER+13) - -static void ThemeDialogBackground(HWND hwnd, BOOL tabbed) -{ - EnableThemeDialogTexture(hwnd, (tabbed ? ETDT_ENABLE : ETDT_DISABLE) | ETDT_USETABTEXTURE); -} - -static wchar_t* GetPluginName(HINSTANCE hInstance, wchar_t *buffer, int size) -{ - wchar_t tszModuleName[MAX_PATH]; - GetModuleFileName(hInstance, tszModuleName, _countof(tszModuleName)); - wchar_t *dllName = wcsrchr(tszModuleName, '\\'); - if (!dllName) - dllName = tszModuleName; - else - dllName++; - wcsncpy_s(buffer, size, dllName, _TRUNCATE); - return buffer; -} - -PageHash GetPluginPageHash(const OptionsPageData *page) -{ - return mir_hashstrT(page->ptszGroup) + mir_hashstrT(page->ptszTitle) + mir_hashstrT(page->ptszTab); -} + DWORD key = GetPluginPageHash(); // get the plugin page hash -static HWND CreateOptionWindow(const OptionsPageData *opd, HWND hWndParent) -{ - opd->pDialog->SetParent(hWndParent); - opd->pDialog->Create(); - return opd->pDialog->GetHwnd(); -} + wchar_t pluginName[MAX_PATH]; + char *temp = GetPluginNameByInstance(getInst()); + GetDialogStrings(enableKeywordFiltering, key, GetPluginName(getInst(), pluginName, _countof(pluginName)), hWnd, ptszGroup, ptszTitle, ptszTab, _A2T(temp)); -static void FindFilterStrings(int enableKeywordFiltering, int current, HWND hWndParent, const OptionsPageData *page) -{ - HWND hWnd = 0; - if (enableKeywordFiltering) { - if (current) - hWnd = page->getHwnd(); - else { - hWnd = CreateOptionWindow(page, hWndParent); - ShowWindow(hWnd, SW_HIDE); // make sure it's hidden - } + if (enableKeywordFiltering && !current) + DestroyWindow(hWnd); // destroy the page, we're done with it } - DWORD key = GetPluginPageHash(page); // get the plugin page hash - - wchar_t pluginName[MAX_PATH]; - char *temp = GetPluginNameByInstance(page->getInst()); - GetDialogStrings(enableKeywordFiltering, key, GetPluginName(page->getInst(), pluginName, _countof(pluginName)), hWnd, page->ptszGroup, page->ptszTitle, page->ptszTab, _A2T(temp)); - - if (enableKeywordFiltering && !current) - DestroyWindow(hWnd); // destroy the page, we're done with it -} + int MatchesFilter(wchar_t *szFilterString) + { + return ContainsFilterString(GetPluginPageHash(), szFilterString); + } +}; -static int MatchesFilter(const OptionsPageData *page, wchar_t *szFilterString) -{ - return ContainsFilterString(GetPluginPageHash(page), szFilterString); -} +///////////////////////////////////////////////////////////////////////////////////////// +// Options dialog static LRESULT CALLBACK OptionsFilterSubclassProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -361,777 +359,786 @@ static LRESULT CALLBACK OptionsFilterSubclassProc(HWND hWnd, UINT message, WPARA return 0; } -static bool CheckPageShow(HWND, OptionsDlgData *dat, int i) -{ - OptionsPageData *opd = dat->arOpd[i]; - if (dat->szFilterString[0] && !MatchesFilter(opd, dat->szFilterString)) - return false; - return true; -} - -static BOOL IsAeroMode() -{ - BOOL result; - return dwmIsCompositionEnabled && (dwmIsCompositionEnabled(&result) == S_OK) && result; -} - -static LRESULT CALLBACK AeroPaintSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -static void AeroPaintControl(HWND hwnd, HDC hdc, UINT msg, LPARAM lpFlags) +class COptionsDlg : public CDlgBase { - RECT rc; - GetClientRect(hwnd, &rc); - - HDC tempDC = CreateCompatibleDC(hdc); - - BITMAPINFO bmi = { 0 }; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = rc.right; - bmi.bmiHeader.biHeight = -rc.bottom; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - - BYTE *pBits; - HBITMAP hBmp = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0); - HBITMAP hOldBmp = (HBITMAP)SelectObject(tempDC, hBmp); - - // paint - SetPropA(hwnd, "Miranda.AeroRender.Active", (HANDLE)TRUE); - mir_callNextSubclass(hwnd, AeroPaintSubclassProc, msg, (WPARAM)tempDC, lpFlags); - SetPropA(hwnd, "Miranda.AeroRender.Active", (HANDLE)FALSE); - - // Fix alpha channel - GdiFlush(); - for (int i = 0; i < rc.right*rc.bottom; i++, pBits += 4) - if (!pBits[3]) - pBits[3] = 255; - - // Copy to output - BitBlt(hdc, 0, 0, rc.right, rc.bottom, tempDC, 0, 0, SRCCOPY); - SelectObject(tempDC, hOldBmp); - DeleteObject(hBmp); - DeleteDC(tempDC); -} - -static LRESULT CALLBACK AeroPaintSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_CTLCOLOREDIT: - if (!GetPropA((HWND)lParam, "Miranda.AeroRender.Active")) - RedrawWindow((HWND)lParam, NULL, NULL, RDW_INVALIDATE); - break; - - case WM_ERASEBKGND: - return TRUE; - - case WM_PRINT: - case WM_PRINTCLIENT: - AeroPaintControl(hwnd, (HDC)wParam, msg, lParam); - return TRUE; - - case WM_DESTROY: - RemovePropA(hwnd, "Miranda.AeroRender.Active"); - break; - - case WM_PAINT: - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps); - AeroPaintControl(hwnd, hdc, WM_PRINT, PRF_CLIENT | PRF_NONCLIENT); - EndPaint(hwnd, &ps); - return TRUE; + int m_currentPage; + HTREEITEM m_hCurrentPage; + LIST m_arOpd; + RECT m_rcDisplay; + RECT m_rcTab; + HFONT m_hBoldFont; + wchar_t m_szFilterString[1024]; + HANDLE m_hPluginLoad, m_hPluginUnload; + + const wchar_t *m_szCaption, *m_szGroup, *m_szPage, *m_szTab; + const OptionsPageList &m_pages; + + CCtrlTreeView m_pageTree; + CCtrlCombo m_keywordFilter; + CCtrlPages m_tab; + CCtrlButton m_btnApply, m_btnCancel; + + COptionsDlg& operator=(const COptionsDlg&); + + HTREEITEM FindNamedTreeItem(HTREEITEM hParent, const wchar_t *name) + { + wchar_t str[128]; + TVITEMEX tvi; + tvi.mask = TVIF_TEXT; + tvi.pszText = str; + tvi.cchTextMax = _countof(str); + tvi.hItem = (hParent == NULL) ? m_pageTree.GetRoot() : m_pageTree.GetChild(hParent); + while (tvi.hItem != NULL) { + m_pageTree.GetItem(&tvi); + if (!mir_wstrcmpi(str, name)) + return tvi.hItem; + + tvi.hItem = m_pageTree.GetNextSibling(tvi.hItem); + } + return NULL; } - return mir_callNextSubclass(hwnd, AeroPaintSubclassProc, msg, wParam, lParam); -} - -static void CALLBACK FilterSearchTimerFunc(HWND hwnd, UINT, UINT_PTR, DWORD) -{ - OptionsDlgData *dat = (OptionsDlgData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - if (!dat) - return; - if (hFilterSearchWnd == NULL) // Fake window to keep option page focused - hFilterSearchWnd = CreateWindowA("STATIC", "Test", WS_OVERLAPPED | WS_DISABLED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInst, 0); - - if (FilterPage < dat->arOpd.getCount()) - FindFilterStrings(TRUE, dat->currentPage == FilterPage, hFilterSearchWnd, dat->arOpd[FilterPage]); + void SaveOptionsTreeState() + { + wchar_t str[128]; + TVITEMEX tvi; + tvi.mask = TVIF_TEXT | TVIF_STATE; + tvi.pszText = str; + tvi.cchTextMax = _countof(str); + tvi.hItem = m_pageTree.GetRoot(); + while (tvi.hItem != NULL) { + if (m_pageTree.GetItem(&tvi)) { + char buf[130]; + mir_snprintf(buf, "%s%S", OPTSTATE_PREFIX, str); + db_set_b(NULL, "Options", buf, (BYTE)((tvi.state & TVIS_EXPANDED) ? 1 : 0)); + } + tvi.hItem = m_pageTree.GetNextSibling(tvi.hItem); + } + } - FilterPage++; - FilterLoadProgress = FilterPage * 100 / ((dat->arOpd.getCount()) ? dat->arOpd.getCount() : FilterPage); - if (FilterPage >= dat->arOpd.getCount()) { - KillTimer(hwnd, FilterTimerId); - FilterTimerId = 0; - bSearchState = 2; - FilterLoadProgress = 100; - DestroyWindow(hFilterSearchWnd); - hFilterSearchWnd = NULL; + bool CheckPageShow(int i) + { + OptionsPageData *opd = m_arOpd[i]; + if (m_szFilterString[0] && !opd->MatchesFilter(m_szFilterString)) + return false; + return true; } - RedrawWindow(GetDlgItem(hwnd, IDC_KEYWORD_FILTER), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE); -} -static void ExecuteFindFilterStringsTimer(HWND hdlg) -{ - bSearchState = 1; - FilterPage = 0; - if (FilterTimerId) KillTimer(hdlg, FilterTimerId); - FilterTimerId = SetTimer(hdlg, NULL, 1, FilterSearchTimerFunc); -} + void FillFilterCombo() + { + HINSTANCE *KnownInstances = (HINSTANCE*)alloca(sizeof(HINSTANCE)*m_arOpd.getCount()); + int countKnownInst = 0; + m_keywordFilter.ResetContent(); + m_keywordFilter.AddString(ALL_MODULES_FILTER, NULL); + m_keywordFilter.AddString(CORE_MODULES_FILTER, (LPARAM)g_hInst); + + for (int i = 0; i < m_arOpd.getCount(); i++) { + OptionsPageData *opd = m_arOpd[i]; + opd->FindFilterStrings(false, 0, m_hwnd); // only modules name (fast enougth) + + HINSTANCE inst = opd->getInst(); + if (inst == g_hInst) + continue; + + int j; + for (j = 0; j < countKnownInst; j++) + if (KnownInstances[j] == inst) + break; + if (j != countKnownInst) + continue; -static void FillFilterCombo(HWND hDlg, OptionsDlgData* dat) -{ - HINSTANCE *KnownInstances = (HINSTANCE*)alloca(sizeof(HINSTANCE)*dat->arOpd.getCount()); - int countKnownInst = 0; - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_RESETCONTENT, 0, 0); - int index = SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_ADDSTRING, 0, (LPARAM)ALL_MODULES_FILTER); - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_SETITEMDATA, (WPARAM)index, 0); - index = SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_ADDSTRING, 0, (LPARAM)CORE_MODULES_FILTER); - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_SETITEMDATA, (WPARAM)index, (LPARAM)g_hInst); - - for (int i = 0; i < dat->arOpd.getCount(); i++) { - OptionsPageData *opd = dat->arOpd[i]; - FindFilterStrings(FALSE, FALSE, hDlg, opd); // only modules name (fast enougth) + KnownInstances[countKnownInst] = inst; + countKnownInst++; - HINSTANCE inst = opd->getInst(); - if (inst == g_hInst) - continue; + wchar_t tszModuleName[MAX_PATH]; + GetModuleFileName(inst, tszModuleName, _countof(tszModuleName)); - int j; - for (j = 0; j < countKnownInst; j++) - if (KnownInstances[j] == inst) - break; - if (j != countKnownInst) - continue; - - KnownInstances[countKnownInst] = inst; - countKnownInst++; - - wchar_t tszModuleName[MAX_PATH]; - GetModuleFileName(inst, tszModuleName, _countof(tszModuleName)); - - wchar_t *dllName = mir_a2u(GetPluginNameByInstance(inst)); - if (!dllName) dllName = mir_wstrdup(wcsrchr(tszModuleName, '\\')); - if (!dllName) dllName = mir_wstrdup(tszModuleName); - if (dllName) { - index = SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_ADDSTRING, 0, (LPARAM)dllName); - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_SETITEMDATA, (WPARAM)index, (LPARAM)inst); - mir_free(dllName); + wchar_t *dllName = mir_a2u(GetPluginNameByInstance(inst)); + if (!dllName) dllName = mir_wstrdup(wcsrchr(tszModuleName, '\\')); + if (!dllName) dllName = mir_wstrdup(tszModuleName); + if (dllName) { + m_keywordFilter.AddString(dllName, (LPARAM)inst); + mir_free(dllName); + } } - } - - FilterLoadProgress = 100; -} -static void RebuildPageTree(HWND hdlg, OptionsDlgData *dat) -{ - LPARAM oldSel = SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, CB_GETEDITSEL, 0, 0); - GetDlgItemText(hdlg, IDC_KEYWORD_FILTER, dat->szFilterString, _countof(dat->szFilterString)); - - // if filter string is set to all modules then make the filter string empty (this will return all modules) - BOOL bRemoveFocusFromFilter = FALSE; - if (mir_wstrcmp(dat->szFilterString, ALL_MODULES_FILTER) == 0) { - dat->szFilterString[0] = 0; - bRemoveFocusFromFilter = TRUE; + FilterLoadProgress = 100; } - // if filter string is set to core modules replace it with the name of the executable (this will return all core modules) - else if (mir_wstrcmp(dat->szFilterString, CORE_MODULES_FILTER) == 0) { - // replace string with process name - that will show core settings - wchar_t szFileName[300]; - GetModuleFileName(g_hInst, szFileName, _countof(szFileName)); - wchar_t *pos = wcsrchr(szFileName, '\\'); - if (pos) - pos++; - else - pos = szFileName; - wcsncpy_s(dat->szFilterString, pos, _TRUNCATE); + void CreateOptionWindowEx(OptionsPageData *opd) + { + opd->CreateOptionWindow(m_hwnd); + if (opd->flags & ODPF_BOLDGROUPS) + EnumChildWindows(opd->getHwnd(), BoldGroupTitlesEnumChildren, (LPARAM)m_hBoldFont); + + RECT rcPage; + GetClientRect(opd->getHwnd(), &rcPage); + int w = opd->width = rcPage.right; + int h = opd->height = rcPage.bottom; + + RECT rc; + GetWindowRect(opd->getHwnd(), &rc); + + opd->insideTab = IsInsideTab(m_currentPage); + if (opd->insideTab) { + SetWindowPos(opd->getHwnd(), HWND_TOP, (m_rcTab.left + m_rcTab.right - w) >> 1, m_rcTab.top, w, h, 0); + ::ThemeDialogBackground(opd->getHwnd(), TRUE); + } + else { + SetWindowPos(opd->getHwnd(), HWND_TOP, (m_rcDisplay.left + m_rcDisplay.right - w) >> 1, (m_rcDisplay.top + m_rcDisplay.bottom - h) >> 1, w, h, 0); + ::ThemeDialogBackground(opd->getHwnd(), FALSE); + } } - else { - int sel = SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, (UINT)CB_GETCURSEL, 0, 0); - if (sel != -1) { - HINSTANCE hinst = (HINSTANCE)SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, (UINT)CB_GETITEMDATA, sel, 0); + + void RebuildPageTree() + { + LPARAM oldSel = m_keywordFilter.SendMsg(CB_GETEDITSEL, 0, 0); + m_keywordFilter.GetText(m_szFilterString, _countof(m_szFilterString)); + + // if filter string is set to all modules then make the filter string empty (this will return all modules) + BOOL bRemoveFocusFromFilter = FALSE; + if (mir_wstrcmp(m_szFilterString, ALL_MODULES_FILTER) == 0) { + m_szFilterString[0] = 0; + bRemoveFocusFromFilter = TRUE; + } + // if filter string is set to core modules replace it with the name of the executable (this will return all core modules) + else if (mir_wstrcmp(m_szFilterString, CORE_MODULES_FILTER) == 0) { + // replace string with process name - that will show core settings wchar_t szFileName[300]; - GetModuleFileName(hinst, szFileName, _countof(szFileName)); + GetModuleFileName(g_hInst, szFileName, _countof(szFileName)); wchar_t *pos = wcsrchr(szFileName, '\\'); - if (pos) pos++; - else pos = szFileName; - wcsncpy_s(dat->szFilterString, pos, _TRUNCATE); + if (pos) + pos++; + else + pos = szFileName; + + wcsncpy_s(m_szFilterString, pos, _TRUNCATE); + } + else { + int sel = m_keywordFilter.GetCurSel(); + if (sel != -1) { + HINSTANCE hinst = (HINSTANCE)m_keywordFilter.GetItemData(sel); + wchar_t szFileName[300]; + GetModuleFileName(hinst, szFileName, _countof(szFileName)); + wchar_t *pos = wcsrchr(szFileName, '\\'); + if (pos) pos++; + else pos = szFileName; + wcsncpy_s(m_szFilterString, pos, _TRUNCATE); + } } - } - _tcslwr_locale(dat->szFilterString); //all strings are stored as lowercase ... make sure filter string is lowercase too + _tcslwr_locale(m_szFilterString); //all strings are stored as lowercase ... make sure filter string is lowercase too - HWND hwndTree = GetDlgItem(hdlg, IDC_PAGETREE); - SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0); + m_pageTree.SendMsg(WM_SETREDRAW, FALSE, 0); - HWND oldWnd = NULL; - HWND oldTab = NULL; - CMStringW fullTitle; + HWND oldWnd = NULL; + HWND oldTab = NULL; + CMStringW fullTitle; + TVITEMEX tvi; - OptionsPageData *opd = dat->getCurrent(); - if (opd != NULL) { - oldWnd = opd->getHwnd(); - if (opd->insideTab) - oldTab = GetDlgItem(hdlg, IDC_TAB); - } + OptionsPageData *opd = getCurrent(); + if (opd != NULL) { + oldWnd = opd->getHwnd(); + if (opd->insideTab) + oldTab = GetDlgItem(m_hwnd, IDC_TAB); + } - dat->hCurrentPage = NULL; + m_hCurrentPage = NULL; - TreeView_SelectItem(hwndTree, NULL); - TreeView_DeleteAllItems(hwndTree); + m_pageTree.SelectItem(NULL); + m_pageTree.DeleteAllItems(); + + TVINSERTSTRUCT tvis; + tvis.hParent = NULL; + tvis.hInsertAfter = TVI_SORT; + tvis.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; + tvis.item.state = tvis.item.stateMask = TVIS_EXPANDED; + for (int i = 0; i < m_arOpd.getCount(); i++) { + if (!CheckPageShow(i)) + continue; - TVINSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; - tvis.item.state = tvis.item.stateMask = TVIS_EXPANDED; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - if (!CheckPageShow(hdlg, dat, i)) - continue; + opd = m_arOpd[i]; + wchar_t *ptszGroup = TranslateW_LP(opd->ptszGroup, opd->hLangpack); + wchar_t *ptszTitle = opd->getString(opd->ptszTitle), *useTitle; + wchar_t *ptszTab = TranslateW_LP(opd->ptszTab, opd->hLangpack); - opd = dat->arOpd[i]; - wchar_t *ptszGroup = TranslateW_LP(opd->ptszGroup, opd->hLangpack); - wchar_t *ptszTitle = opd->getString(opd->ptszTitle), *useTitle; - wchar_t *ptszTab = TranslateW_LP(opd->ptszTab, opd->hLangpack); + tvis.hParent = NULL; + useTitle = ptszTitle; - tvis.hParent = NULL; - useTitle = ptszTitle; - - if (ptszGroup != NULL) { - tvis.hParent = FindNamedTreeItemAtRoot(hwndTree, ptszGroup); - if (tvis.hParent == NULL) { - tvis.item.lParam = -1; - tvis.item.pszText = ptszGroup; - tvis.hParent = TreeView_InsertItem(hwndTree, &tvis); + if (ptszGroup != NULL) { + tvis.hParent = FindNamedTreeItem(NULL, ptszGroup); + if (tvis.hParent == NULL) { + tvis.item.lParam = -1; + tvis.item.pszText = ptszGroup; + tvis.hParent = m_pageTree.InsertItem(&tvis); + } } - } - else { - TVITEM tvi; - tvi.hItem = FindNamedTreeItemAtRoot(hwndTree, useTitle); - if (tvi.hItem != NULL) { - if (i == dat->currentPage) dat->hCurrentPage = tvi.hItem; - tvi.mask = TVIF_PARAM; - TreeView_GetItem(hwndTree, &tvi); - if (tvi.lParam == -1) { - tvi.lParam = i; - TreeView_SetItem(hwndTree, &tvi); + else { + tvi.hItem = FindNamedTreeItem(NULL, useTitle); + if (tvi.hItem != NULL) { + if (i == m_currentPage) m_hCurrentPage = tvi.hItem; + tvi.mask = TVIF_PARAM; + m_pageTree.GetItem(&tvi); + if (tvi.lParam == -1) { + tvi.lParam = i; + m_pageTree.SetItem(&tvi); + continue; + } + } + } + + if (ptszTab != NULL) { + HTREEITEM hItem; + if (tvis.hParent == NULL) + hItem = FindNamedTreeItem(NULL, useTitle); + else + hItem = FindNamedTreeItem(tvis.hParent, useTitle); + if (hItem != NULL) { + if (i == m_currentPage) { + tvi.hItem = hItem; + tvi.mask = TVIF_PARAM; + tvi.lParam = m_currentPage; + m_pageTree.SetItem(&tvi); + m_hCurrentPage = hItem; + } continue; } } + + tvis.item.pszText = useTitle; + tvis.item.lParam = i; + opd->hTreeItem = m_pageTree.InsertItem(&tvis); + if (i == m_currentPage) + m_hCurrentPage = opd->hTreeItem; } - if (ptszTab != NULL) { - HTREEITEM hItem; - if (tvis.hParent == NULL) - hItem = FindNamedTreeItemAtRoot(hwndTree, useTitle); - else - hItem = FindNamedTreeItemAtChildren(hwndTree, tvis.hParent, useTitle); - if (hItem != NULL) { - if (i == dat->currentPage) { - TVITEM tvi; - tvi.hItem = hItem; - tvi.mask = TVIF_PARAM; - tvi.lParam = dat->currentPage; - TreeView_SetItem(hwndTree, &tvi); - dat->hCurrentPage = hItem; - } - continue; + wchar_t str[128]; + tvi.mask = TVIF_TEXT | TVIF_STATE; + tvi.pszText = str; + tvi.cchTextMax = _countof(str); + tvi.hItem = m_pageTree.GetRoot(); + while (tvi.hItem != NULL) { + if (m_pageTree.GetItem(&tvi)) { + char buf[130]; + mir_snprintf(buf, "%s%S", OPTSTATE_PREFIX, str); + if (!db_get_b(NULL, "Options", buf, 1)) + m_pageTree.Expand(tvi.hItem, TVE_COLLAPSE); + } + tvi.hItem = m_pageTree.GetNextSibling(tvi.hItem); + } + + if (m_hCurrentPage == NULL) { + m_hCurrentPage = m_pageTree.GetRoot(); + m_currentPage = -1; + } + m_pageTree.SelectItem(m_hCurrentPage); + + if (oldWnd) { + opd = getCurrent(); + if (opd && oldWnd != opd->getHwnd()) { + ShowWindow(oldWnd, SW_HIDE); + if (oldTab && (opd == NULL || !opd->insideTab)) + ShowWindow(oldTab, SW_HIDE); } } - tvis.item.pszText = useTitle; - tvis.item.lParam = i; - opd->hTreeItem = TreeView_InsertItem(hwndTree, &tvis); - if (i == dat->currentPage) - dat->hCurrentPage = opd->hTreeItem; + if (m_szFilterString[0] == 0) // Clear the keyword combo box + m_keywordFilter.SetText(L""); + if (!bRemoveFocusFromFilter) + SetFocus(m_keywordFilter.GetHwnd()); //set the focus back to the combo box + + m_keywordFilter.SendMsg(CB_SETEDITSEL, 0, oldSel); //but don't select any of the text + + m_pageTree.SendMsg(WM_SETREDRAW, TRUE, 0); + m_pageTree.EnsureVisible(m_hCurrentPage); } - char str[128]; - TVITEMA tvi; - tvi.mask = TVIF_TEXT | TVIF_STATE; - tvi.pszText = str; - tvi.cchTextMax = _countof(str); - tvi.hItem = TreeView_GetRoot(hwndTree); - while (tvi.hItem != NULL) { - if (SendMessageA(hwndTree, TVM_GETITEMA, 0, (LPARAM)&tvi)) { - char buf[130]; - mir_snprintf(buf, "%s%s", OPTSTATE_PREFIX, str); - if (!db_get_b(NULL, "Options", buf, 1)) - TreeView_Expand(hwndTree, tvi.hItem, TVE_COLLAPSE); + BOOL IsInsideTab(int i) + { + OptionsPageData *opd = m_arOpd[i]; + int pages = 0; + if (opd->ptszTab != NULL) { + // Count tabs to calc position + for (int j = 0; j < m_arOpd.getCount() && pages < 2; j++) { + OptionsPageData* opd2 = m_arOpd[j]; + if (!CheckPageShow(j)) continue; + if (mir_wstrcmp(opd2->ptszTitle, opd->ptszTitle) || mir_wstrcmp(opd2->ptszGroup, opd->ptszGroup)) + continue; + pages++; + } } - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); + return (pages > 1); } - if (dat->hCurrentPage == NULL) { - dat->hCurrentPage = TreeView_GetRoot(hwndTree); - dat->currentPage = -1; - } - TreeView_SelectItem(hwndTree, dat->hCurrentPage); - - if (oldWnd) { - opd = dat->getCurrent(); - if (opd && oldWnd != opd->getHwnd()) { - ShowWindow(oldWnd, SW_HIDE); - if (oldTab && (opd == NULL || !opd->insideTab)) - ShowWindow(oldTab, SW_HIDE); + void LoadOptionsModule(HINSTANCE hInst) + { + OptionsPageList arPages(1); + CallPluginEventHook(hInst, hOptionsInitEvent, (WPARAM)&arPages, 0); + if (arPages.getCount() == 0) + return; + + for (int i = 0; i < arPages.getCount(); i++) { + OptionsPageData *opd = new OptionsPageData(arPages[i]); + if (opd->pDialog == NULL) // smth went wrong + delete opd; + else + m_arOpd.insert(opd); } + + RebuildPageTree(); } - if (dat->szFilterString[0] == 0) // Clear the keyword combo box - SetDlgItemText(hdlg, IDC_KEYWORD_FILTER, L""); - if (!bRemoveFocusFromFilter) - SetFocus(GetDlgItem(hdlg, IDC_KEYWORD_FILTER)); //set the focus back to the combo box + void UnloadOptionsModule(HINSTANCE hInst) + { + bool bToRebuildTree = false; - SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, CB_SETEDITSEL, 0, oldSel); //but don't select any of the text + for (int i = m_arOpd.getCount() - 1; i >= 0; i--) { + OptionsPageData *opd = m_arOpd[i]; + if (opd->getInst() != hInst) + continue; - SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0); - TreeView_EnsureVisible(hwndTree, dat->hCurrentPage); -} + if (m_currentPage > i) + m_currentPage--; -static BOOL IsInsideTab(HWND hdlg, OptionsDlgData *dat, int i) -{ - OptionsPageData *opd = dat->arOpd[i]; - int pages = 0; - if (opd->ptszTab != NULL) { - // Count tabs to calc position - for (int j = 0; j < dat->arOpd.getCount() && pages < 2; j++) { - OptionsPageData* opd2 = dat->arOpd[j]; - if (!CheckPageShow(hdlg, dat, j)) continue; - if (mir_wstrcmp(opd2->ptszTitle, opd->ptszTitle) || mir_wstrcmp(opd2->ptszGroup, opd->ptszGroup)) - continue; - pages++; + m_arOpd.remove(i); + delete opd; + bToRebuildTree = true; } + + if (bToRebuildTree) + RebuildPageTree(); } - return (pages > 1); -} -static void LoadOptionsModule(HWND hdlg, OptionsDlgData *dat, HINSTANCE hInst) -{ - OptionsPageList arPages(1); - CallPluginEventHook(hInst, hOptionsInitEvent, (WPARAM)&arPages, 0); - if (arPages.getCount() == 0) - return; + OptionsPageData* getCurrent() const + { return (m_currentPage == -1) ? NULL : m_arOpd[m_currentPage]; + } - for (int i = 0; i < arPages.getCount(); i++) { - OptionsPageData *opd = new OptionsPageData(&arPages[i]); - if (opd->pDialog == NULL) // smth went wrong - delete opd; - else - dat->arOpd.insert(opd); +public: + COptionsDlg(const wchar_t *pszCaption, const wchar_t *pszGroup, const wchar_t *pszPage, const wchar_t *pszTab, bool bSinglePage, const OptionsPageList &arPages) : + CDlgBase(g_hInst, bSinglePage ? IDD_OPTIONSPAGE : IDD_OPTIONS), + m_tab(this, IDC_TAB), + m_btnApply(this, IDC_APPLY), + m_btnCancel(this, IDCANCEL), + m_pageTree(this, IDC_PAGETREE), + m_keywordFilter(this, IDC_KEYWORD_FILTER), + m_arOpd(10), + m_szCaption(pszCaption), + m_szGroup(pszGroup), + m_szPage(pszPage), + m_szTab(pszTab), + m_pages(arPages) + { + m_pageTree.OnSelChanging = Callback(this, &COptionsDlg::OnChanging); + m_pageTree.OnSelChanged = Callback(this, &COptionsDlg::OnTreeChanged); + + m_btnCancel.OnClick = Callback(this, &COptionsDlg::OnCancel); + m_btnApply.OnClick = Callback(this, &COptionsDlg::btnApply); } - PostMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); -} + virtual void OnInitDialog() override + { + if (!ServiceExists(MS_MODERNOPT_SHOW)) + ShowWindow(GetDlgItem(m_hwnd, IDC_MODERN), FALSE); -static void UnloadOptionsModule(HWND hdlg, OptionsDlgData *dat, HINSTANCE hInst) -{ - bool bToRebuildTree = false; + Utils_RestoreWindowPositionNoSize(m_hwnd, NULL, "Options", ""); + Window_SetSkinIcon_IcoLib(m_hwnd, SKINICON_OTHER_OPTIONS); + m_btnApply.Disable(); - for (int i = dat->arOpd.getCount() - 1; i >= 0; i--) { - OptionsPageData *opd = dat->arOpd[i]; - if (opd->getInst() != hInst) - continue; + COMBOBOXINFO cbi; + cbi.cbSize = sizeof(COMBOBOXINFO); + GetComboBoxInfo(GetDlgItem(m_hwnd, IDC_KEYWORD_FILTER), &cbi); + mir_subclassWindow(cbi.hwndItem, OptionsFilterSubclassProc); - if (dat->currentPage > i) - dat->currentPage--; + if (IsAeroMode()) { + mir_subclassWindow(cbi.hwndCombo, AeroPaintSubclassProc); + mir_subclassWindow(cbi.hwndItem, AeroPaintSubclassProc); + } - dat->arOpd.remove(i); - delete opd; - bToRebuildTree = true; - } + SetCaption(m_szCaption); - if (bToRebuildTree) - PostMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); -} + LOGFONT lf; + m_hBoldFont = (HFONT)m_btnApply.SendMsg(WM_GETFONT, 0, 0); + GetObject(m_hBoldFont, sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + m_hBoldFont = CreateFontIndirect(&lf); -static INT_PTR CALLBACK OptionsDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - OptionsPageData *opd; - OptionsDlgData *dat = (OptionsDlgData*)GetWindowLongPtr(hdlg, GWLP_USERDATA); - HWND hwndTree = GetDlgItem(hdlg, IDC_PAGETREE); - PSHNOTIFY pshn; - - switch (message) { - case WM_CTLCOLORSTATIC: - switch (GetDlgCtrlID((HWND)lParam)) { - case IDC_WHITERECT: - case IDC_KEYWORD_FILTER: - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); + m_hPluginLoad = HookEventMessage(ME_SYSTEM_MODULELOAD, m_hwnd, HM_MODULELOAD); + m_hPluginUnload = HookEventMessage(ME_SYSTEM_MODULEUNLOAD, m_hwnd, HM_MODULEUNLOAD); + m_currentPage = -1; + + ptrW lastPage, lastGroup, lastTab; + if (m_szPage == NULL) { + lastPage = db_get_wsa(NULL, "Options", "LastPage"); + + if (m_szGroup == NULL) + lastGroup = db_get_wsa(NULL, "Options", "LastGroup"); + else + lastGroup = mir_wstrdup(m_szGroup); + } + else { + lastPage = mir_wstrdup(m_szPage); + lastGroup = mir_wstrdup(m_szGroup); } - break; - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); + if (m_szTab == NULL) + lastTab = db_get_wsa(NULL, "Options", "LastTab"); + else + lastTab = mir_wstrdup(m_szTab); - if (!ServiceExists(MS_MODERNOPT_SHOW)) - ShowWindow(GetDlgItem(hdlg, IDC_MODERN), FALSE); - - dat = new OptionsDlgData; - SetWindowLongPtr(hdlg, GWLP_USERDATA, (LONG_PTR)dat); - - Utils_RestoreWindowPositionNoSize(hdlg, NULL, "Options", ""); - Window_SetSkinIcon_IcoLib(hdlg, SKINICON_OTHER_OPTIONS); - EnableWindow(GetDlgItem(hdlg, IDC_APPLY), FALSE); - { - COMBOBOXINFO cbi; - cbi.cbSize = sizeof(COMBOBOXINFO); - GetComboBoxInfo(GetDlgItem(hdlg, IDC_KEYWORD_FILTER), &cbi); - mir_subclassWindow(cbi.hwndItem, OptionsFilterSubclassProc); - - if (IsAeroMode()) { - mir_subclassWindow(cbi.hwndCombo, AeroPaintSubclassProc); - mir_subclassWindow(cbi.hwndItem, AeroPaintSubclassProc); - } + for (int i = 0; i < m_pages.getCount(); i++) { + const OPTIONSDIALOGPAGE &odp = m_pages[i]; + OptionsPageData *opd = new OptionsPageData(odp); + if (opd->pDialog == NULL) // smth went wrong + delete opd; + else + m_arOpd.insert(opd); - PROPSHEETHEADER *psh = (PROPSHEETHEADER*)lParam; - SetWindowText(hdlg, psh->pszCaption); + if (!mir_wstrcmp(lastPage, odp.szTitle.w) && !mir_wstrcmp(lastGroup, odp.szGroup.w)) + if ((m_szTab == NULL && m_currentPage == -1) || !mir_wstrcmp(lastTab, odp.szTab.w)) + m_currentPage = (int)i; + } - LOGFONT lf; - dat->hBoldFont = (HFONT)SendDlgItemMessage(hdlg, IDC_APPLY, WM_GETFONT, 0, 0); - GetObject(dat->hBoldFont, sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - dat->hBoldFont = CreateFontIndirect(&lf); + GetWindowRect(GetDlgItem(m_hwnd, IDC_STNOPAGE), &m_rcDisplay); + MapWindowPoints(NULL, m_hwnd, (LPPOINT)&m_rcDisplay, 2); - dat->hPluginLoad = HookEventMessage(ME_SYSTEM_MODULELOAD, hdlg, HM_MODULELOAD); - dat->hPluginUnload = HookEventMessage(ME_SYSTEM_MODULEUNLOAD, hdlg, HM_MODULEUNLOAD); - dat->currentPage = -1; + // Add an item to count in height + TCITEM tie; + tie.mask = TCIF_TEXT | TCIF_IMAGE; + tie.iImage = -1; + tie.pszText = L"X"; + TabCtrl_InsertItem(GetDlgItem(m_hwnd, IDC_TAB), 0, &tie); - ptrW lastPage, lastGroup, lastTab; - OPENOPTIONSDIALOG *ood = (OPENOPTIONSDIALOG*)psh->pStartPage; - if (ood->pszPage == NULL) { - lastPage = db_get_wsa(NULL, "Options", "LastPage"); + GetWindowRect(GetDlgItem(m_hwnd, IDC_TAB), &m_rcTab); + MapWindowPoints(NULL, m_hwnd, (LPPOINT)&m_rcTab, 2); + TabCtrl_AdjustRect(GetDlgItem(m_hwnd, IDC_TAB), FALSE, &m_rcTab); - if (ood->pszGroup == NULL) - lastGroup = db_get_wsa(NULL, "Options", "LastGroup"); - else - lastGroup = mir_wstrdup(ood->pszGroup); - } - else { - lastPage = mir_wstrdup(ood->pszPage); - lastGroup = mir_wstrdup(ood->pszGroup); - } + FillFilterCombo(); + RebuildPageTree(); + } + + virtual void OnDestroy() override + { + ClearFilterStrings(); + m_szFilterString[0] = 0; + + UnhookEvent(m_hPluginLoad); + UnhookEvent(m_hPluginUnload); - if (ood->pszTab == NULL) - lastTab = db_get_wsa(NULL, "Options", "LastTab"); + SaveOptionsTreeState(); + Window_FreeIcon_IcoLib(m_hwnd); + + OptionsPageData *opd = getCurrent(); + if (opd) { + if (opd->ptszTab) + db_set_ws(NULL, "Options", "LastTab", opd->ptszTab); + else + db_unset(NULL, "Options", "LastTab"); + if (opd->ptszGroup) + db_set_ws(NULL, "Options", "LastGroup", opd->ptszGroup); else - lastTab = mir_wstrdup(ood->pszTab); + db_unset(NULL, "Options", "LastGroup"); + db_set_ws(NULL, "Options", "LastPage", opd->ptszTitle); + } + else { + db_unset(NULL, "Options", "LastTab"); + db_unset(NULL, "Options", "LastGroup"); + db_unset(NULL, "Options", "LastPage"); + } - OPTIONSDIALOGPAGE **odp = (OPTIONSDIALOGPAGE**)psh->ppsp; - for (UINT i = 0; i < psh->nPages; i++) { - opd = new OptionsPageData(odp[i]); - if (opd->pDialog == NULL) // smth went wrong - delete opd; - else - dat->arOpd.insert(opd); + Utils_SaveWindowPosition(m_hwnd, NULL, "Options", ""); - if (!mir_wstrcmp(lastPage, odp[i]->szTitle.w) && !mir_wstrcmp(lastGroup, odp[i]->szGroup.w)) - if ((ood->pszTab == NULL && dat->currentPage == -1) || !mir_wstrcmp(lastTab, odp[i]->szTab.w)) - dat->currentPage = (int)i; - } + for (int i = 0; i < m_arOpd.getCount(); i++) + delete m_arOpd[i]; - GetWindowRect(GetDlgItem(hdlg, IDC_STNOPAGE), &dat->rcDisplay); - MapWindowPoints(NULL, hdlg, (LPPOINT)&dat->rcDisplay, 2); + DeleteObject(m_hBoldFont); + pOptionsDlg = NULL; - // Add an item to count in height - TCITEM tie; - tie.mask = TCIF_TEXT | TCIF_IMAGE; - tie.iImage = -1; - tie.pszText = L"X"; - TabCtrl_InsertItem(GetDlgItem(hdlg, IDC_TAB), 0, &tie); + CallService(MS_MODERNOPT_RESTORE, 0, 0); + } - GetWindowRect(GetDlgItem(hdlg, IDC_TAB), &dat->rcTab); - MapWindowPoints(NULL, hdlg, (LPPOINT)&dat->rcTab, 2); - TabCtrl_AdjustRect(GetDlgItem(hdlg, IDC_TAB), FALSE, &dat->rcTab); + virtual void OnApply() override + { + PSHNOTIFY pshn; + m_btnApply.Disable(); + SetFocus(m_pageTree.GetHwnd()); - FillFilterCombo(hdlg, dat); - PostMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); + OptionsPageData *opd = getCurrent(); + if (opd != NULL) { + pshn.hdr.idFrom = 0; + pshn.lParam = IDC_APPLY; + pshn.hdr.code = PSN_KILLACTIVE; + pshn.hdr.hwndFrom = opd->getHwnd(); + if (SendMessage(opd->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn)) + return; } - return TRUE; - case DM_REBUILDPAGETREE: - RebuildPageTree(hdlg, dat); - break; + pshn.hdr.code = PSN_APPLY; + for (int i = 0; i < m_arOpd.getCount(); i++) { + OptionsPageData *p = m_arOpd[i]; + if (p->getHwnd() == NULL || !p->changed) continue; + p->changed = 0; + pshn.hdr.hwndFrom = p->getHwnd(); + if (SendMessage(p->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn) == PSNRET_INVALID_NOCHANGEPAGE) { + m_hCurrentPage = p->hTreeItem; + m_pageTree.SelectItem(m_hCurrentPage); + if (opd) + opd->pDialog->Show(SW_HIDE); + m_currentPage = i; + if (opd) + opd->pDialog->Show(); + return; + } + } + } - case HM_MODULELOAD: - LoadOptionsModule(hdlg, dat, (HINSTANCE)lParam); - break; + void btnApply(CCtrlButton*) + { + OnApply(); + m_btnApply.Disable(); + } - case HM_MODULEUNLOAD: - UnloadOptionsModule(hdlg, dat, (HINSTANCE)lParam); - break; + void OnOk(void*) + { + if (GetParent(GetFocus()) == GetDlgItem(m_hwnd, IDC_KEYWORD_FILTER)) + return; - case PSM_CHANGED: - EnableWindow(GetDlgItem(hdlg, IDC_APPLY), TRUE); + OnApply(); + Close(); + } - opd = dat->getCurrent(); - if (opd) - opd->changed = 1; + void OnCancel(CCtrlButton*) + { + PSHNOTIFY pshn; + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + pshn.hdr.code = PSN_RESET; + for (int i = 0; i < m_arOpd.getCount(); i++) { + OptionsPageData *p = m_arOpd[i]; + if (p->getHwnd() == NULL || !p->changed) + continue; + pshn.hdr.hwndFrom = p->getHwnd(); + SendMessage(p->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn); + } + } - return TRUE; + void OnChanging(CCtrlTreeView::TEventInfo*) + { + OptionsPageData *opd = getCurrent(); + if (opd && opd->getHwnd() != NULL) { + PSHNOTIFY pshn; + pshn.hdr.code = PSN_KILLACTIVE; + pshn.hdr.hwndFrom = m_arOpd[m_currentPage]->getHwnd(); + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + if (SendMessage(m_arOpd[m_currentPage]->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn)) { + SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE); + return; + } + } + } - case PSM_GETBOLDFONT: - SetWindowLongPtr(hdlg, DWLP_MSGRESULT, (LONG_PTR)dat->hBoldFont); - return TRUE; + void OnTreeChanged(CCtrlTreeView::TEventInfo *evt) + { + ShowWindow(GetDlgItem(m_hwnd, IDC_STNOPAGE), SW_HIDE); - case WM_NOTIFY: - switch (wParam) { - case IDC_TAB: - case IDC_PAGETREE: - switch (((LPNMHDR)lParam)->code) { - case TVN_ITEMEXPANDING: - SetWindowLongPtr(hdlg, DWLP_MSGRESULT, FALSE); - return TRUE; - - case TCN_SELCHANGING: - case TVN_SELCHANGING: - opd = dat->getCurrent(); - if (opd && opd->getHwnd() != NULL) { - pshn.hdr.code = PSN_KILLACTIVE; - pshn.hdr.hwndFrom = dat->arOpd[dat->currentPage]->getHwnd(); - pshn.hdr.idFrom = 0; - pshn.lParam = 0; - if (SendMessage(dat->arOpd[dat->currentPage]->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn)) { - SetWindowLongPtr(hdlg, DWLP_MSGRESULT, TRUE); - return TRUE; - } - } - break; + OptionsPageData *opd = getCurrent(); + if (opd && opd->getHwnd() != NULL) + ShowWindow(opd->getHwnd(), SW_HIDE); - case TCN_SELCHANGE: - case TVN_SELCHANGED: - ShowWindow(GetDlgItem(hdlg, IDC_STNOPAGE), SW_HIDE); + TVITEMEX tvi; + tvi.hItem = m_hCurrentPage = m_pageTree.GetSelection(); + if (tvi.hItem == NULL) { + ShowWindow(GetDlgItem(m_hwnd, IDC_TAB), SW_HIDE); + return; + } - opd = dat->getCurrent(); - if (opd && opd->getHwnd() != NULL) - ShowWindow(opd->getHwnd(), SW_HIDE); + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + m_pageTree.GetItem(&tvi); + m_currentPage = tvi.lParam; + ShowWindow(GetDlgItem(m_hwnd, IDC_TAB), SW_HIDE); - if (wParam != IDC_TAB) { - TVITEM tvi; - tvi.hItem = dat->hCurrentPage = TreeView_GetSelection(hwndTree); - if (tvi.hItem == NULL) { - ShowWindow(GetDlgItem(hdlg, IDC_TAB), SW_HIDE); - break; - } + opd = getCurrent(); + if (opd == NULL) { + ShowWindow(GetDlgItem(m_hwnd, IDC_STNOPAGE), SW_SHOW); + return; + } - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - TreeView_GetItem(hwndTree, &tvi); - dat->currentPage = tvi.lParam; - ShowWindow(GetDlgItem(hdlg, IDC_TAB), SW_HIDE); - } - else { - TCITEM tie; - tie.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hdlg, IDC_TAB), TabCtrl_GetCurSel(GetDlgItem(hdlg, IDC_TAB)), &tie); - dat->currentPage = tie.lParam; - - TVITEM tvi; - tvi.hItem = dat->hCurrentPage; - tvi.mask = TVIF_PARAM; - tvi.lParam = dat->currentPage; - TreeView_SetItem(hwndTree, &tvi); - } + if (opd->getHwnd() == NULL) + CreateOptionWindowEx(opd); - opd = dat->getCurrent(); - if (opd == NULL) { - ShowWindow(GetDlgItem(hdlg, IDC_STNOPAGE), SW_SHOW); - break; - } - if (opd->getHwnd() == NULL) { - CreateOptionWindow(opd, hdlg); - if (opd->flags & ODPF_BOLDGROUPS) - EnumChildWindows(opd->getHwnd(), BoldGroupTitlesEnumChildren, (LPARAM)dat->hBoldFont); - - RECT rcPage; - GetClientRect(opd->getHwnd(), &rcPage); - int w = opd->width = rcPage.right; - int h = opd->height = rcPage.bottom; - - RECT rc; - GetWindowRect(opd->getHwnd(), &rc); - - opd->insideTab = IsInsideTab(hdlg, dat, dat->currentPage); - if (opd->insideTab) { - SetWindowPos(opd->getHwnd(), HWND_TOP, (dat->rcTab.left + dat->rcTab.right - w) >> 1, dat->rcTab.top, w, h, 0); - ThemeDialogBackground(opd->getHwnd(), TRUE); - } - else { - SetWindowPos(opd->getHwnd(), HWND_TOP, (dat->rcDisplay.left + dat->rcDisplay.right - w) >> 1, (dat->rcDisplay.top + dat->rcDisplay.bottom - h) >> 1, w, h, 0); - ThemeDialogBackground(opd->getHwnd(), FALSE); - } - } + opd->insideTab = IsInsideTab(m_currentPage); + if (opd->insideTab) { + // Make tabbed pane + int pages = 0, sel = 0; + HWND hwndTab = GetDlgItem(m_hwnd, IDC_TAB); + TabCtrl_DeleteAllItems(hwndTab); - if (wParam != IDC_TAB) { - opd->insideTab = IsInsideTab(hdlg, dat, dat->currentPage); - if (opd->insideTab) { - // Make tabbed pane - int pages = 0, sel = 0; - HWND hwndTab = GetDlgItem(hdlg, IDC_TAB); - TabCtrl_DeleteAllItems(hwndTab); - - TCITEM tie; - tie.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; - tie.iImage = -1; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - if (!CheckPageShow(hdlg, dat, i)) - continue; - - OptionsPageData *p = dat->arOpd[i]; - if (mir_wstrcmp(opd->ptszTitle, p->ptszTitle) || mir_wstrcmp(opd->ptszGroup, p->ptszGroup)) - continue; - - tie.pszText = TranslateW_LP(p->ptszTab, p->hLangpack); - tie.lParam = i; - TabCtrl_InsertItem(hwndTab, pages, &tie); - if (!mir_wstrcmp(opd->ptszTab, p->ptszTab)) - sel = pages; - pages++; - } - TabCtrl_SetCurSel(hwndTab, sel); - ShowWindow(hwndTab, opd->insideTab ? SW_SHOW : SW_HIDE); - } + TCITEM tie; + tie.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; + tie.iImage = -1; + for (int i = 0; i < m_arOpd.getCount(); i++) { + if (!CheckPageShow(i)) + continue; - ThemeDialogBackground(opd->getHwnd(), opd->insideTab); - } + OptionsPageData *p = m_arOpd[i]; + if (mir_wstrcmp(opd->ptszTitle, p->ptszTitle) || mir_wstrcmp(opd->ptszGroup, p->ptszGroup)) + continue; - ShowWindow(opd->getHwnd(), SW_SHOW); - if (((LPNMTREEVIEW)lParam)->action == TVC_BYMOUSE) - PostMessage(hdlg, DM_FOCUSPAGE, 0, 0); - else - SetFocus(hwndTree); + tie.pszText = TranslateW_LP(p->ptszTab, p->hLangpack); + tie.lParam = i; + TabCtrl_InsertItem(hwndTab, pages, &tie); + if (!mir_wstrcmp(opd->ptszTab, p->ptszTab)) + sel = pages; + pages++; } + TabCtrl_SetCurSel(hwndTab, sel); + ShowWindow(hwndTab, opd->insideTab ? SW_SHOW : SW_HIDE); } - break; - case DM_FOCUSPAGE: - if (dat->currentPage != -1) - SetFocus(dat->arOpd[dat->currentPage]->getHwnd()); - break; + ::ThemeDialogBackground(opd->getHwnd(), opd->insideTab); - case WM_TIMER: - if (wParam == FILTER_TIMEOUT_TIMER) { - SaveOptionsTreeState(hdlg); - SendMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); + ShowWindow(opd->getHwnd(), SW_SHOW); + if (evt->nmtv->action == TVC_BYMOUSE) { + if (m_currentPage != -1) + SetFocus(m_arOpd[m_currentPage]->getHwnd()); + } + else SetFocus(m_pageTree.GetHwnd()); + } - KillTimer(hdlg, FILTER_TIMEOUT_TIMER); + void OnTabChanged() + { + ShowWindow(GetDlgItem(m_hwnd, IDC_STNOPAGE), SW_HIDE); + + OptionsPageData *opd = getCurrent(); + if (opd && opd->getHwnd() != NULL) + ShowWindow(opd->getHwnd(), SW_HIDE); + + TCITEM tie; + tie.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(m_hwnd, IDC_TAB), TabCtrl_GetCurSel(GetDlgItem(m_hwnd, IDC_TAB)), &tie); + m_currentPage = tie.lParam; + + TVITEMEX tvi; + tvi.hItem = m_hCurrentPage; + tvi.mask = TVIF_PARAM; + tvi.lParam = m_currentPage; + m_pageTree.SetItem(&tvi); + + opd = getCurrent(); + if (opd == NULL) { + ShowWindow(GetDlgItem(m_hwnd, IDC_STNOPAGE), SW_SHOW); + return; } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_KEYWORD_FILTER: - // add a timer - when the timer elapses filter the option pages - if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_EDITCHANGE)) - if (!SetTimer(hdlg, FILTER_TIMEOUT_TIMER, 400, NULL)) - MessageBeep(MB_ICONSTOP); + if (opd->getHwnd() == NULL) + CreateOptionWindowEx(opd); + + ShowWindow(opd->getHwnd(), SW_SHOW); + SetFocus(m_pageTree.GetHwnd()); + } + + virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override + { + switch (msg) { + case WM_CTLCOLORSTATIC: + switch (GetDlgCtrlID((HWND)lParam)) { + case IDC_WHITERECT: + case IDC_KEYWORD_FILTER: + SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); + return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); + } break; - case IDC_MODERN: - db_set_b(NULL, "Options", "Expert", 0); - SaveOptionsTreeState(hdlg); - PostMessage(hdlg, WM_CLOSE, 0, 0); - CallService(MS_MODERNOPT_SHOW, 0, 0); + case HM_MODULELOAD: + LoadOptionsModule((HINSTANCE)lParam); break; - case IDCANCEL: - pshn.hdr.idFrom = 0; - pshn.lParam = 0; - pshn.hdr.code = PSN_RESET; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - OptionsPageData *p = dat->arOpd[i]; - if (p->getHwnd() == NULL || !p->changed) - continue; - pshn.hdr.hwndFrom = p->getHwnd(); - SendMessage(p->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn); - } - DestroyWindow(hdlg); + case HM_MODULEUNLOAD: + UnloadOptionsModule((HINSTANCE)lParam); break; - case IDOK: - case IDC_APPLY: - if (LOWORD(wParam) == IDOK && GetParent(GetFocus()) == GetDlgItem(hdlg, IDC_KEYWORD_FILTER)) - return TRUE; - - EnableWindow(GetDlgItem(hdlg, IDC_APPLY), FALSE); - SetFocus(hwndTree); - - opd = dat->getCurrent(); - if (opd != NULL) { - pshn.hdr.idFrom = 0; - pshn.lParam = LOWORD(wParam); - pshn.hdr.code = PSN_KILLACTIVE; - pshn.hdr.hwndFrom = opd->getHwnd(); - if (SendMessage(opd->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn)) - break; + case PSM_CHANGED: + m_btnApply.Enable(); + { + OptionsPageData *opd = getCurrent(); + if (opd) + opd->changed = 1; } - - pshn.hdr.code = PSN_APPLY; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - OptionsPageData *p = dat->arOpd[i]; - if (p->getHwnd() == NULL || !p->changed) continue; - p->changed = 0; - pshn.hdr.hwndFrom = p->getHwnd(); - if (SendMessage(p->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn) == PSNRET_INVALID_NOCHANGEPAGE) { - dat->hCurrentPage = p->hTreeItem; - TreeView_SelectItem(hwndTree, dat->hCurrentPage); - if (opd) - opd->pDialog->Show(SW_HIDE); - dat->currentPage = i; - if (opd) - opd->pDialog->Show(); - return 0; + return TRUE; + + case PSM_GETBOLDFONT: + SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, (LONG_PTR)m_hBoldFont); + return TRUE; + + case WM_NOTIFY: + switch (wParam) { + case IDC_TAB: + case IDC_PAGETREE: + switch (((LPNMHDR)lParam)->code) { + case TVN_ITEMEXPANDING: + SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, FALSE); + return TRUE; + + case TCN_SELCHANGING: + OnChanging(NULL); + return TRUE; + + case TCN_SELCHANGE: + OnTabChanged(); + return TRUE; } } + break; - if (LOWORD(wParam) == IDOK) - DestroyWindow(hdlg); - } - break; - - case WM_DESTROY: - if (FilterTimerId) - KillTimer(hdlg, FilterTimerId); - DestroyWindow(hFilterSearchWnd); - ClearFilterStrings(); - dat->szFilterString[0] = 0; + case WM_TIMER: + if (wParam == FILTER_TIMEOUT_TIMER) { + SaveOptionsTreeState(); + RebuildPageTree(); - UnhookEvent(dat->hPluginLoad); - UnhookEvent(dat->hPluginUnload); + KillTimer(m_hwnd, FILTER_TIMEOUT_TIMER); + } + break; - SaveOptionsTreeState(hdlg); - Window_FreeIcon_IcoLib(hdlg); + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_KEYWORD_FILTER: + // add a timer - when the timer elapses filter the option pages + if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_EDITCHANGE)) + if (!SetTimer(m_hwnd, FILTER_TIMEOUT_TIMER, 400, NULL)) + MessageBeep(MB_ICONSTOP); + break; - opd = dat->getCurrent(); - if (opd) { - if (opd->ptszTab) - db_set_ws(NULL, "Options", "LastTab", opd->ptszTab); - else - db_unset(NULL, "Options", "LastTab"); - if (opd->ptszGroup) - db_set_ws(NULL, "Options", "LastGroup", opd->ptszGroup); - else - db_unset(NULL, "Options", "LastGroup"); - db_set_ws(NULL, "Options", "LastPage", opd->ptszTitle); - } - else { - db_unset(NULL, "Options", "LastTab"); - db_unset(NULL, "Options", "LastGroup"); - db_unset(NULL, "Options", "LastPage"); + case IDC_MODERN: + db_set_b(NULL, "Options", "Expert", 0); + SaveOptionsTreeState(); + PostMessage(m_hwnd, WM_CLOSE, 0, 0); + CallService(MS_MODERNOPT_SHOW, 0, 0); + break; + } + break; } - Utils_SaveWindowPosition(hdlg, NULL, "Options", ""); - - for (int i = 0; i < dat->arOpd.getCount(); i++) - delete dat->arOpd[i]; + return CDlgBase::DlgProc(msg, wParam, lParam); + } - DeleteObject(dat->hBoldFont); - delete dat; - hwndOptions = NULL; + void Locate(const wchar_t *pszGroup, const wchar_t *pszPage, int _hLang) + { + Show(SW_RESTORE); + SetForegroundWindow(m_hwnd); + if (pszPage != NULL) { + HTREEITEM hItem = NULL; + if (pszGroup != NULL) { + hItem = FindNamedTreeItem(NULL, TranslateW_LP(pszGroup, _hLang)); + if (hItem != NULL) + hItem = FindNamedTreeItem(hItem, TranslateW_LP(pszPage, _hLang)); + } + else hItem = FindNamedTreeItem(NULL, TranslateW_LP(pszPage, _hLang)); - CallService(MS_MODERNOPT_RESTORE, 0, 0); - break; + if (hItem != NULL) + m_pageTree.SelectItem(hItem); + } } - return FALSE; -} +}; void OpenAccountOptions(PROTOACCOUNT *pa) { @@ -1145,63 +1152,22 @@ void OpenAccountOptions(PROTOACCOUNT *pa) wchar_t tszTitle[100]; mir_snwprintf(tszTitle, TranslateT("%s options"), pa->tszAccountName); - - OPENOPTIONSDIALOG ood; - ood.pszGroup = LPGENW("Network"); - ood.pszPage = pa->tszAccountName; - ood.pszTab = NULL; - - PROPSHEETHEADER psh = { sizeof(psh) }; - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; - psh.hwndParent = NULL; - psh.nPages = arPages.getCount(); - psh.pStartPage = (LPCTSTR)&ood; - psh.pszCaption = tszTitle; - psh.ppsp = (PROPSHEETPAGE*)arPages.getArray(); - hwndOptions = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_OPTIONSPAGE), NULL, OptionsDlgProc, (LPARAM)&psh); + pOptionsDlg = new COptionsDlg(tszTitle, LPGENW("Network"), pa->tszAccountName, NULL, true, arPages); + pOptionsDlg->Show(); } static void OpenOptionsNow(int _hLang, const wchar_t *pszGroup, const wchar_t *pszPage, const wchar_t *pszTab, bool bSinglePage) { - if (IsWindow(hwndOptions)) { - ShowWindow(hwndOptions, SW_RESTORE); - SetForegroundWindow(hwndOptions); - if (pszPage != NULL) { - HTREEITEM hItem = NULL; - if (pszGroup != NULL) { - hItem = FindNamedTreeItemAtRoot(GetDlgItem(hwndOptions, IDC_PAGETREE), TranslateW_LP(pszGroup, _hLang)); - if (hItem != NULL) - hItem = FindNamedTreeItemAtChildren(GetDlgItem(hwndOptions, IDC_PAGETREE), hItem, TranslateW_LP(pszPage, _hLang)); - } - else hItem = FindNamedTreeItemAtRoot(GetDlgItem(hwndOptions, IDC_PAGETREE), TranslateW_LP(pszPage, _hLang)); - - if (hItem != NULL) - TreeView_SelectItem(GetDlgItem(hwndOptions, IDC_PAGETREE), hItem); - } - } - else { + if (pOptionsDlg == NULL) { OptionsPageList arPages(1); NotifyEventHooks(hOptionsInitEvent, (WPARAM)&arPages, 0); if (arPages.getCount() == 0) return; - OPENOPTIONSDIALOG ood = { 0 }; - ood.pszGroup = pszGroup; - ood.pszPage = pszPage; - ood.pszTab = pszTab; - - PROPSHEETHEADER psh = { 0 }; - psh.dwSize = sizeof(psh); - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; - psh.nPages = arPages.getCount(); - psh.pStartPage = (LPCTSTR)&ood; // more structure misuse - psh.pszCaption = TranslateT("Miranda NG options"); - psh.ppsp = (PROPSHEETPAGE*)arPages.getArray(); // blatent misuse of the structure, but what the hell - - hwndOptions = CreateDialogParam(g_hInst, - MAKEINTRESOURCE(bSinglePage ? IDD_OPTIONSPAGE : IDD_OPTIONS), - NULL, OptionsDlgProc, (LPARAM)&psh); + pOptionsDlg = new COptionsDlg(TranslateT("Miranda NG options"), pszGroup, pszPage, pszTab, bSinglePage, arPages); + pOptionsDlg->Show(); } + else pOptionsDlg->Locate(pszGroup, pszPage, _hLang); } MIR_APP_DLL(int) Options_Open(const wchar_t *pszGroup, const wchar_t *pszPage, const wchar_t *pszTab, int _hLangpack) @@ -1213,7 +1179,7 @@ MIR_APP_DLL(int) Options_Open(const wchar_t *pszGroup, const wchar_t *pszPage, c MIR_APP_DLL(HWND) Options_OpenPage(const wchar_t *pszGroup, const wchar_t *pszPage, const wchar_t *pszTab, int _hLangpack) { OpenOptionsNow(_hLangpack, pszGroup, pszPage, pszTab, true); - return hwndOptions; + return pOptionsDlg->GetHwnd(); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -1266,7 +1232,7 @@ MIR_APP_DLL(int) Options_AddPage(WPARAM wParam, OPTIONSDIALOGPAGE *odp, int _hLa static INT_PTR OpenOptionsDialog(WPARAM, LPARAM) { - if (hwndOptions || !ServiceExists(MS_MODERNOPT_SHOW)) + if (pOptionsDlg || !ServiceExists(MS_MODERNOPT_SHOW)) OpenOptionsNow(NULL, NULL, NULL, NULL, false); else CallService(MS_MODERNOPT_SHOW, 0, 0); @@ -1288,16 +1254,12 @@ static int OptModulesLoaded(WPARAM, LPARAM) int ShutdownOptionsModule(WPARAM, LPARAM) { - if (IsWindow(hwndOptions)) { - DestroyWindow(hwndOptions); - hwndOptions = NULL; - } + delete pOptionsDlg; pOptionsDlg = NULL; return 0; } int LoadOptionsModule(void) { - hwndOptions = NULL; hOptionsInitEvent = CreateHookableEvent(ME_OPT_INITIALISE); HookEvent(ME_OPT_INITIALISE, LangpackOptionsInit); diff --git a/src/mir_app/src/sounds.cpp b/src/mir_app/src/sounds.cpp index 8c60ee3b62..37203dbf62 100644 --- a/src/mir_app/src/sounds.cpp +++ b/src/mir_app/src/sounds.cpp @@ -68,6 +68,24 @@ MIR_APP_DLL(void) KillModuleSounds(int _hLang) /////////////////////////////////////////////////////////////////////////////// +HTREEITEM FindNamedTreeItemAtRoot(HWND hwndTree, const wchar_t* name) +{ + wchar_t str[128]; + TVITEM tvi; + tvi.mask = TVIF_TEXT; + tvi.pszText = str; + tvi.cchTextMax = _countof(str); + tvi.hItem = TreeView_GetRoot(hwndTree); + while (tvi.hItem != NULL) { + SendMessage(hwndTree, TVM_GETITEM, 0, (LPARAM)&tvi); + if (!mir_wstrcmpi(str, name)) + return tvi.hItem; + + tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); + } + return NULL; +} + static BOOL bModuleInitialized = FALSE; static HANDLE hPlayEvent = NULL; -- cgit v1.2.3