From b5bb7bfe0a4da1fb1e9664da06ec708c809dbe6d Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 20 May 2015 18:21:14 +0000 Subject: adaptation of CCtrlPages for the real life git-svn-id: http://svn.miranda-ng.org/main/trunk@13719 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- bin10/lib/mir_core.lib | Bin 333118 -> 333084 bytes bin10/lib/mir_core64.lib | Bin 335000 -> 335498 bytes bin12/lib/mir_core.lib | Bin 333118 -> 333084 bytes bin12/lib/mir_core64.lib | Bin 335000 -> 335498 bytes include/m_gui.h | 32 +++-- src/mir_core/src/mir_core.def | 4 +- src/mir_core/src/mir_core64.def | 4 +- src/mir_core/src/ui_utils.cpp | 291 +++++++++++++++++++++++++++------------- 8 files changed, 224 insertions(+), 107 deletions(-) diff --git a/bin10/lib/mir_core.lib b/bin10/lib/mir_core.lib index 8f8ecaada2..d9349e8b5a 100644 Binary files a/bin10/lib/mir_core.lib and b/bin10/lib/mir_core.lib differ diff --git a/bin10/lib/mir_core64.lib b/bin10/lib/mir_core64.lib index 6aaa60f2e6..ebeb8bac0b 100644 Binary files a/bin10/lib/mir_core64.lib and b/bin10/lib/mir_core64.lib differ diff --git a/bin12/lib/mir_core.lib b/bin12/lib/mir_core.lib index 8f8ecaada2..d9349e8b5a 100644 Binary files a/bin12/lib/mir_core.lib and b/bin12/lib/mir_core.lib differ diff --git a/bin12/lib/mir_core64.lib b/bin12/lib/mir_core64.lib index 6aaa60f2e6..ebeb8bac0b 100644 Binary files a/bin12/lib/mir_core64.lib and b/bin12/lib/mir_core64.lib differ diff --git a/include/m_gui.h b/include/m_gui.h index 51d2d3ddd0..01d5f1808f 100644 --- a/include/m_gui.h +++ b/include/m_gui.h @@ -852,7 +852,7 @@ class MIR_CORE_EXPORT CCtrlTreeView : public CCtrlBase { typedef CCtrlBase CSuper; - HTREEITEM MoveItemAbove(HTREEITEM hItem, HTREEITEM hInsertAfter); + HTREEITEM MoveItemAbove(HTREEITEM hItem, HTREEITEM hInsertAfter); public: CCtrlTreeView(CDlgBase *dlg, int ctrlId); @@ -990,6 +990,12 @@ protected: ///////////////////////////////////////////////////////////////////////////////////////// // CCtrlTreeView +#define PSN_INFOCHANGED 1 +#define PSN_PARAMCHANGED 2 + +// force-send a PSN_INFOCHANGED to all pages +#define PSM_FORCECHANGED (WM_USER+100) + class MIR_CORE_EXPORT CCtrlPages : public CCtrlBase { typedef CCtrlBase CSuper; @@ -997,16 +1003,17 @@ class MIR_CORE_EXPORT CCtrlPages : public CCtrlBase public: CCtrlPages(CDlgBase *dlg, int ctrlId); - void AddPage(TCHAR *ptszName, HICON hIcon, CCallback onCreate = CCallback(), void *param = NULL); - void AttachDialog(int iPage, CDlgBase *pDlg); - + void AddPage(TCHAR *ptszName, HICON hIcon, CDlgBase *pDlg); void ActivatePage(int iPage); - protected: virtual BOOL OnNotify(int idCtrl, NMHDR *pnmh); - void OnInit(); - void OnDestroy(); + + virtual void OnInit(); + virtual void OnDestroy(); + + virtual void OnApply(); + virtual void OnReset(); virtual LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam); @@ -1014,14 +1021,19 @@ private: HIMAGELIST m_hIml; CDlgBase *m_pActivePage; - struct TPageInfo + struct TPageInfo : public MZeroedObject { - CCallback m_onCreate; - void *m_param; + int m_pageId; + ptrT m_ptszHeader; + HICON m_hIcon; + BOOL m_bChanged; CDlgBase *m_pDlg; }; void ShowPage(CDlgBase *pDlg); + + TPageInfo* GetCurrPage(); + LIST m_pages; }; ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def index f42a795ad6..0373655320 100644 --- a/src/mir_core/src/mir_core.def +++ b/src/mir_core/src/mir_core.def @@ -703,13 +703,12 @@ mir_wstrcmpi @280 ?AddGroup@CCtrlListView@@QAEXHPA_W@Z @702 NONAME ?AddInfoItem@CCtrlClc@@QAEPAXPAUCLCINFOITEM@@@Z @703 NONAME ?AddItem@CCtrlListView@@QAEHPA_WHJH@Z @704 NONAME -?AddPage@CCtrlPages@@QAEXPA_WPAUHICON__@@U?$CCallback@X@@PAX@Z @705 NONAME +?AddPage@CCtrlPages@@QAEXPA_WPAUHICON__@@PAVCDlgBase@@@Z @705 NONAME ?AddString@CCtrlCombo@@QAEHPB_WJ@Z @706 NONAME ?AddString@CCtrlListBox@@QAEHPA_WJ@Z @707 NONAME ?AddStringA@CCtrlCombo@@QAEHPBDJ@Z @708 NONAME ?ApproximateViewRect@CCtrlListView@@QAEKHHH@Z @709 NONAME ?Arrange@CCtrlListView@@QAEXI@Z @710 NONAME -?AttachDialog@CCtrlPages@@QAEXHPAVCDlgBase@@@Z @711 NONAME ?AutoRebuild@CCtrlClc@@QAEXXZ @712 NONAME ?CancelEditLabel@CCtrlListView@@QAEXXZ @713 NONAME ?Close@CDlgBase@@QAEXXZ @714 NONAME @@ -1090,3 +1089,4 @@ Proto_RegisterModule @1074 NONAME ?Unselect@CCtrlTreeView@@QAEXPAU_TREEITEM@@@Z @1092 NONAME ?UnselectAll@CCtrlTreeView@@QAEXXZ @1093 NONAME ?MoveItemAbove@CCtrlTreeView@@AAEPAU_TREEITEM@@PAU2@0@Z @1094 NONAME +?GetCurrPage@CCtrlPages@@AAEPAUTPageInfo@1@XZ @1095 NONAME diff --git a/src/mir_core/src/mir_core64.def b/src/mir_core/src/mir_core64.def index b2adec82c1..29ae97a79f 100644 --- a/src/mir_core/src/mir_core64.def +++ b/src/mir_core/src/mir_core64.def @@ -703,13 +703,12 @@ mir_wstrcmpi @280 ?AddGroup@CCtrlListView@@QEAAXHPEA_W@Z @702 NONAME ?AddInfoItem@CCtrlClc@@QEAAPEAXPEAUCLCINFOITEM@@@Z @703 NONAME ?AddItem@CCtrlListView@@QEAAHPEA_WH_JH@Z @704 NONAME -?AddPage@CCtrlPages@@QEAAXPEA_WPEAUHICON__@@U?$CCallback@X@@PEAX@Z @705 NONAME +?AddPage@CCtrlPages@@QEAAXPEA_WPEAUHICON__@@PEAVCDlgBase@@@Z @705 NONAME ?AddString@CCtrlCombo@@QEAAHPEB_W_J@Z @706 NONAME ?AddString@CCtrlListBox@@QEAAHPEA_W_J@Z @707 NONAME ?AddStringA@CCtrlCombo@@QEAAHPEBD_J@Z @708 NONAME ?ApproximateViewRect@CCtrlListView@@QEAAKHHH@Z @709 NONAME ?Arrange@CCtrlListView@@QEAAXI@Z @710 NONAME -?AttachDialog@CCtrlPages@@QEAAXHPEAVCDlgBase@@@Z @711 NONAME ?AutoRebuild@CCtrlClc@@QEAAXXZ @712 NONAME ?CancelEditLabel@CCtrlListView@@QEAAXXZ @713 NONAME ?Close@CDlgBase@@QEAAXXZ @714 NONAME @@ -1090,3 +1089,4 @@ Proto_RegisterModule @1074 NONAME ?Unselect@CCtrlTreeView@@QEAAXPEAU_TREEITEM@@@Z @1092 NONAME ?UnselectAll@CCtrlTreeView@@QEAAXXZ @1093 NONAME ?MoveItemAbove@CCtrlTreeView@@AEAAPEAU_TREEITEM@@PEAU2@0@Z @1094 NONAME +?GetCurrPage@CCtrlPages@@AEAAPEAUTPageInfo@1@XZ @1095 NONAME diff --git a/src/mir_core/src/ui_utils.cpp b/src/mir_core/src/ui_utils.cpp index deb0ed00ed..53b4cc5f0e 100644 --- a/src/mir_core/src/ui_utils.cpp +++ b/src/mir_core/src/ui_utils.cpp @@ -152,10 +152,22 @@ INT_PTR CDlgBase::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) return result; } - if (idCode == BN_CLICKED && - ((idCtrl == IDOK) && (m_autoClose & CLOSE_ON_OK) || - (idCtrl == IDCANCEL) && (m_autoClose & CLOSE_ON_CANCEL))) { - PostMessage(m_hwnd, WM_CLOSE, 0, 0); + if (idCode == BN_CLICKED) { + // close dialog automatically if 'Cancel' button is pressed + if (idCtrl == IDCANCEL && (m_autoClose & CLOSE_ON_CANCEL)) + PostMessage(m_hwnd, WM_CLOSE, 0, 0); + + // close dialog automatically if 'OK' button is pressed + if (idCtrl == IDOK && (m_autoClose & CLOSE_ON_OK)) { + // validate dialog data first + m_lresult = TRUE; + NotifyControls(&CCtrlBase::OnApply); + OnApply(); + + // everything ok? good, let's close it + if (m_lresult == TRUE) + PostMessage(m_hwnd, WM_CLOSE, 0, 0); + } } } return FALSE; @@ -2042,146 +2054,239 @@ void CCtrlTreeView::SortChildrenCB(TVSORTCB *cb, BOOL fRecurse) CCtrlPages::CCtrlPages(CDlgBase* dlg, int ctrlId) : CCtrlBase(dlg, ctrlId), m_hIml(NULL), - m_pActivePage(NULL) + m_pActivePage(NULL), + m_pages(4) {} void CCtrlPages::OnInit() { CSuper::OnInit(); Subclass(); + + for (int i = 0; i < m_pages.getCount(); i++) { + TPageInfo *p = m_pages[i]; + TCITEM tci = { 0 }; + tci.mask = TCIF_PARAM | TCIF_TEXT; + tci.lParam = (LPARAM)p; + tci.pszText = TranslateTS(p->m_ptszHeader); + if (p->m_hIcon) { + if (!m_hIml) { + m_hIml = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1); + TabCtrl_SetImageList(m_hwnd, m_hIml); + } + + tci.mask |= TCIF_IMAGE; + tci.iImage = ImageList_AddIcon(m_hIml, p->m_hIcon); + } + + p->m_pageId = TabCtrl_InsertItem(m_hwnd, TabCtrl_GetItemCount(m_hwnd), &tci); + } + + ::SetWindowLong(m_hwnd, GWL_EXSTYLE, ::GetWindowLong(m_hwnd, GWL_EXSTYLE) | WS_EX_CONTROLPARENT); + + TPageInfo *info = GetCurrPage(); + if (info) { + m_pActivePage = info->m_pDlg; + ShowPage(m_pActivePage); + + PSHNOTIFY pshn; + pshn.hdr.code = PSN_INFOCHANGED; + pshn.hdr.hwndFrom = m_pActivePage->GetHwnd(); + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + SendMessage(pshn.hdr.hwndFrom, WM_NOTIFY, 0, (LPARAM)&pshn); + } } LRESULT CCtrlPages::CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_SIZE) - ShowPage(m_pActivePage); + PSHNOTIFY pshn; + + switch (msg) { + case WM_SIZE: + RECT rc; + GetClientRect(m_hwnd, &rc); + TabCtrl_AdjustRect(m_hwnd, FALSE, &rc); + + for (int i = 0; i < m_pages.getCount(); i++) { + TPageInfo *p = m_pages[i]; + if (p->m_pDlg->GetHwnd() != NULL) + SetWindowPos(m_pActivePage->GetHwnd(), HWND_TOP, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + } + break; + + case PSM_CHANGED: + if (TPageInfo *info = GetCurrPage()) + info->m_bChanged = TRUE; + return TRUE; + + case PSM_FORCECHANGED: + pshn.hdr.code = PSN_INFOCHANGED; + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + for (int i = 0; i < m_pages.getCount(); i++) { + pshn.hdr.hwndFrom = m_pages[i]->m_pDlg->GetHwnd(); + if (pshn.hdr.hwndFrom != NULL) + SendMessage(pshn.hdr.hwndFrom, WM_NOTIFY, 0, (LPARAM)&pshn); + } + break; + } return CSuper::CustomWndProc(msg, wParam, lParam); } -void CCtrlPages::AddPage(TCHAR *ptszName, HICON hIcon, CCallback onCreate, void *param) +void CCtrlPages::AddPage(TCHAR *ptszName, HICON hIcon, CDlgBase *pDlg) { TPageInfo *info = new TPageInfo; - info->m_onCreate = onCreate; - info->m_param = param; - info->m_pDlg = NULL; + info->m_pDlg = pDlg; + info->m_hIcon = hIcon; + info->m_ptszHeader = mir_tstrdup(ptszName); + m_pages.insert(info); +} - TCITEM tci = { 0 }; - tci.mask = TCIF_PARAM | TCIF_TEXT; - tci.lParam = (LPARAM)info; - tci.pszText = ptszName; - if (hIcon) { - if (!m_hIml) { - m_hIml = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1); - TabCtrl_SetImageList(m_hwnd, m_hIml); - } +void CCtrlPages::ActivatePage(int iPage) +{ + TPageInfo *info = m_pages[iPage]; + if (info == NULL) + return; - tci.mask |= TCIF_IMAGE; - tci.iImage = ImageList_AddIcon(m_hIml, hIcon); - } + if (m_pActivePage != NULL) + ShowWindow(m_pActivePage->GetHwnd(), SW_HIDE); + + m_pActivePage = info->m_pDlg; + ShowPage(m_pActivePage); - TabCtrl_InsertItem(m_hwnd, TabCtrl_GetItemCount(m_hwnd), &tci); + TabCtrl_SetCurSel(m_hwnd, info->m_pageId); } -void CCtrlPages::AttachDialog(int iPage, CDlgBase *pDlg) +CCtrlPages::TPageInfo* CCtrlPages::GetCurrPage() { - if ((iPage < 0) || (iPage >= TabCtrl_GetItemCount(m_hwnd))) - return; - TCITEM tci = { 0 }; tci.mask = TCIF_PARAM; - TabCtrl_GetItem(m_hwnd, iPage, &tci); - - if (TPageInfo *info = (TPageInfo *)tci.lParam) { - if (info->m_pDlg) - info->m_pDlg->Close(); - - info->m_pDlg = pDlg; - if (pDlg->GetHwnd() == NULL) { - pDlg->SetParent(m_hwnd); - pDlg->Create(); - } + if (!TabCtrl_GetItem(m_hwnd, TabCtrl_GetCurSel(m_hwnd), &tci)) + return NULL; - if (iPage == TabCtrl_GetCurSel(m_hwnd)) { - m_pActivePage = pDlg; - ShowPage(pDlg); - } - } + return (TPageInfo*)tci.lParam; } void CCtrlPages::ShowPage(CDlgBase *pDlg) { - if (!pDlg) return; + if (pDlg->GetHwnd() == NULL) { + pDlg->SetParent(m_hwnd); + pDlg->Create(); - RECT rc; - GetClientRect(m_hwnd, &rc); - TabCtrl_AdjustRect(m_hwnd, FALSE, &rc); + RECT rc; + GetClientRect(m_hwnd, &rc); + TabCtrl_AdjustRect(m_hwnd, FALSE, &rc); + SetWindowPos(pDlg->GetHwnd(), HWND_TOP, rc.left, rc.top, 0, 0, SWP_NOSIZE); - EnableThemeDialogTexture(pDlg->GetHwnd(), ETDT_ENABLETAB); - SetWindowPos(pDlg->GetHwnd(), HWND_TOP, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); -} + EnableThemeDialogTexture(pDlg->GetHwnd(), ETDT_ENABLETAB); -void CCtrlPages::ActivatePage(int iPage) -{ - TabCtrl_SetCurSel(m_hwnd, iPage); + PSHNOTIFY pshn; + pshn.hdr.code = PSN_INFOCHANGED; + pshn.hdr.hwndFrom = pDlg->GetHwnd(); + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + SendMessage(pshn.hdr.hwndFrom, WM_NOTIFY, 0, (LPARAM)&pshn); + } + ShowWindow(pDlg->GetHwnd(), SW_SHOW); } BOOL CCtrlPages::OnNotify(int /*idCtrl*/, NMHDR *pnmh) { + TPageInfo *info; + PSHNOTIFY pshn; + switch (pnmh->code) { case TCN_SELCHANGING: - { - TCITEM tci = { 0 }; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(m_hwnd, TabCtrl_GetCurSel(m_hwnd), &tci); - - if (TPageInfo *info = (TPageInfo *)tci.lParam) { - if (info->m_pDlg) { - m_pActivePage = NULL; - ShowWindow(info->m_pDlg->GetHwnd(), SW_HIDE); - } - } + if (info = GetCurrPage()) { + pshn.hdr.code = PSN_KILLACTIVE; + pshn.hdr.hwndFrom = info->m_pDlg->GetHwnd(); + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + if (SendMessage(pshn.hdr.hwndFrom, WM_NOTIFY, 0, (LPARAM)&pshn)) { + SetWindowLongPtr(GetParent()->GetHwnd(), DWLP_MSGRESULT, TRUE); + return TRUE; + } } return TRUE; case TCN_SELCHANGE: - { - TCITEM tci = { 0 }; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(m_hwnd, TabCtrl_GetCurSel(m_hwnd), &tci); - - if (TPageInfo *info = (TPageInfo *)tci.lParam) { - if (info->m_pDlg) { - m_pActivePage = info->m_pDlg; - ShowPage(info->m_pDlg); - } - else { - m_pActivePage = NULL; - info->m_onCreate(info->m_param); - } - } + if (m_pActivePage != NULL) + ShowWindow(m_pActivePage->GetHwnd(), SW_HIDE); + + if (info = GetCurrPage()) { + m_pActivePage = info->m_pDlg; + ShowPage(m_pActivePage); } + else m_pActivePage = NULL; return TRUE; } return FALSE; } -void CCtrlPages::OnDestroy() -{ - int count = TabCtrl_GetItemCount(m_hwnd); - for (int i = 0; i < count; i++) { - TCITEM tci = { 0 }; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(m_hwnd, i, &tci); - - if (TPageInfo *info = (TPageInfo *)tci.lParam) { - if (info->m_pDlg) - info->m_pDlg->Close(); +void CCtrlPages::OnReset() +{ + CSuper::OnReset(); + + PSHNOTIFY pshn; + pshn.hdr.code = PSN_INFOCHANGED; + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + + for (int i = 0; i < m_pages.getCount(); i++) { + TPageInfo *p = m_pages[i]; + if (p->m_pDlg->GetHwnd() == NULL || !p->m_bChanged) + continue; + + pshn.hdr.hwndFrom = p->m_pDlg->GetHwnd(); + SendMessage(pshn.hdr.hwndFrom, WM_NOTIFY, 0, (LPARAM)&pshn); + } +} - delete info; - } +void CCtrlPages::OnApply() +{ + PSHNOTIFY pshn; + pshn.hdr.idFrom = 0; + pshn.lParam = 0; + + if (m_pActivePage != NULL) { + pshn.hdr.code = PSN_KILLACTIVE; + pshn.hdr.hwndFrom = m_pActivePage->GetHwnd(); + if (SendMessage(pshn.hdr.hwndFrom, WM_NOTIFY, 0, (LPARAM)&pshn)) + return; + } + + pshn.hdr.code = PSN_APPLY; + for (int i = 0; i < m_pages.getCount(); i++) { + TPageInfo *p = m_pages[i]; + if (p->m_pDlg->GetHwnd() == NULL || !p->m_bChanged) + continue; + + pshn.hdr.hwndFrom = p->m_pDlg->GetHwnd(); + SendMessage(pshn.hdr.hwndFrom, WM_NOTIFY, 0, (LPARAM)&pshn); + if (GetWindowLongPtr(pshn.hdr.hwndFrom, DWLP_MSGRESULT) == PSNRET_INVALID_NOCHANGEPAGE) { + TabCtrl_SetCurSel(m_hwnd, p->m_pageId); + if (m_pActivePage != NULL) + ShowWindow(m_pActivePage->GetHwnd(), SW_HIDE); + m_pActivePage = p->m_pDlg; + ShowWindow(m_pActivePage->GetHwnd(), SW_SHOW); + return; + } } + + CSuper::OnApply(); +} + +void CCtrlPages::OnDestroy() +{ + for (int i = 0; i < m_pages.getCount(); i++) { + TPageInfo *p = m_pages[i]; + if (p->m_pDlg->GetHwnd()) + p->m_pDlg->Close(); + delete p; + } TabCtrl_DeleteAllItems(m_hwnd); -- cgit v1.2.3