From 733fadd44d1d58c1e1707d06b9cbe6b223c301a6 Mon Sep 17 00:00:00 2001 From: Erich Willems Date: Thu, 18 Jul 2019 23:23:31 +0200 Subject: [PATCH] fill --- TaskDialogEmu.h | 2848 ++++++++++++++++++++ TaskDialogEmu.h.DLURect.incl | 913 +++++++ TaskDialogEmu.h.PixelRect.incl | 775 ++++++ TaskDialogEmu.h.PreVistaDeclarations.incl | 148 + TaskDialogEmu.h.TaskDialogConfig_X.incl | 172 ++ TaskDialogEmu.h.WTLPreBaseUnitsHelper.incl | 140 + TaskDialogEmu.h.WinXPDeclarations.incl | 59 + res/Error.png | Bin 0 -> 2423 bytes res/Information.png | Bin 0 -> 2290 bytes res/Question.png | Bin 0 -> 2325 bytes res/Shield.png | Bin 0 -> 2121 bytes res/ShieldError.png | Bin 0 -> 2454 bytes res/ShieldOK.png | Bin 0 -> 2477 bytes res/ShieldQuestion.png | Bin 0 -> 2457 bytes res/ShieldWarning.png | Bin 0 -> 2369 bytes res/TaskDlgArrowHot.ico | Bin 0 -> 2902 bytes res/TaskDlgArrowNormal.ico | Bin 0 -> 2902 bytes res/TaskDlgChevronLess.ico | Bin 0 -> 766 bytes res/TaskDlgChevronMore.ico | Bin 0 -> 766 bytes res/Warning.png | Bin 0 -> 1873 bytes 20 files changed, 5055 insertions(+) create mode 100644 TaskDialogEmu.h create mode 100644 TaskDialogEmu.h.DLURect.incl create mode 100644 TaskDialogEmu.h.PixelRect.incl create mode 100644 TaskDialogEmu.h.PreVistaDeclarations.incl create mode 100644 TaskDialogEmu.h.TaskDialogConfig_X.incl create mode 100644 TaskDialogEmu.h.WTLPreBaseUnitsHelper.incl create mode 100644 TaskDialogEmu.h.WinXPDeclarations.incl create mode 100644 res/Error.png create mode 100644 res/Information.png create mode 100644 res/Question.png create mode 100644 res/Shield.png create mode 100644 res/ShieldError.png create mode 100644 res/ShieldOK.png create mode 100644 res/ShieldQuestion.png create mode 100644 res/ShieldWarning.png create mode 100644 res/TaskDlgArrowHot.ico create mode 100644 res/TaskDlgArrowNormal.ico create mode 100644 res/TaskDlgChevronLess.ico create mode 100644 res/TaskDlgChevronMore.ico create mode 100644 res/Warning.png diff --git a/TaskDialogEmu.h b/TaskDialogEmu.h new file mode 100644 index 0000000..dd2049e --- /dev/null +++ b/TaskDialogEmu.h @@ -0,0 +1,2848 @@ +#if !defined(AFX_TASKDIALOGEMU_H__20073232_5AA0_1E88_3A6D_0080AD509054__INCLUDED_) +#define AFX_TASKDIALOGEMU_H__20073232_5AA0_1E88_3A6D_0080AD509054__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +///////////////////////////////////////////////////////////////////////////// +// CTask98Dialog - Task Dialog for legacy Windows platforms +// +// Written by Bjarke Viksoe (bjarke@viksoe.dk) +// Copyright (c) 2007 Bjarke Viksoe. +// +// Thanks to David Brown and Yarp of senosoft.com +// for submitting several fixes. +// +// This code may be used in compiled form in any way you desire. +// +// This source file may be redistributed by any means PROVIDING +// it is not sold for profit without the authors written consent, +// and providing that this notice and the authors name is included. +// +// This file is provided "as is" with no expressed or implied warranty. +// The author accepts no liability if it causes any damage to you or your +// computer whatsoever. It's free, so don't hassle me about it. +// +// Beware of bugs. +// + + +// The dialog requires a few string and icon resources to be defined. Ironic isn't it: the dialog +// is dynamically constructed but we still need resources. +// Here is a list: +// IDS_TASKDLG_OK "&OK" +// IDS_TASKDLG_YES "&Yes" +// IDS_TASKDLG_NO "&No" +// IDS_TASKDLG_CANCEL "&Cancel" +// IDS_TASKDLG_RETRY "&Retry" +// IDS_TASKDLG_CLOSE "Close" +// +// IDI_TASKDLG_CHEVRON_LESS Expander icon (less) +// IDI_TASKDLG_CHEVRON_MORE Expander icon (more) +// IDI_TASKDLG_ARROW_NORMAL Green Link Arrow +// IDI_TASKDLG_ARROW_HOT Green Link Arrow (hover) +// + + +/*By Erich Willems: Small changes and fixes are applied to this version of the source code. + *The changed code is intended only to use in compiled form, + *so 'This code may be used in compiled form "in any way you desire".' + *is taking effect. + *The purpose of the small adaptions is to make the code better fit into + *the needs of the framework used in. + */ + +#include "resource.h" +//#include "atlmisc.h" +//#include "VersWin.h" + +//#define CString ATL::CString + +///////////////////////////////////////////////////////////////////////// +// /// TaskDialogEmu declares +// +#include "TaskDialogEmu.h.WinXPDeclarations.incl" +#include "TaskDialogEmu.h.PreVistaDeclarations.incl" + +#include "TaskDialogEmu.h.WTLPreBaseUnitsHelper.incl" + +#include "TaskDialogEmu.h.TaskDialogConfig_X.incl" //support for mixed custom push and commandbuttons +#include "TaskDialogEmu.h.PixelRect.incl" +#include "TaskDialogEmu.h.DLURect.incl" + +//some constants: +#ifndef PBM_SETSTATE + const UINT PBM_SETSTATE = WM_USER + 16; +#endif +#ifndef PBM_SETMARQUEE + const UINT PBM_SETMARQUEE = WM_USER + 10; +#endif +#ifndef PBS_MARQUEE + const DWORD PBS_MARQUEE = 0x08; +#endif +#ifndef WS_EX_LAYOUTRTL + const UINT WS_EX_LAYOUTRTL = 0x00400000L; +#endif +#ifndef BS_COMMANDLINK + const DWORD BS_COMMANDLINK = 0x0000000E; + const DWORD BS_DEFCOMMANDLINK = 0x0000000F; +#endif // BS_COMMANDLINK + + + + +#ifndef DECL_dThis + #define DECL_dThis const DERIVED* dThis = static_cast(this) ///1.0) {what+= sign*(LONG)(lns*f); + } + else {double f =unitNow/unitPre; + what-= sign*(LONG)(lns*f); + } +} +// ----------------------------------------------- + + void makeTxtColFromBackground(COLORREF& txt,COLORREF& backg) + { + int txt1=0x000000ff & (txt>>2*8); + int txt2=0x000000ff & (txt>>1*8); + int txt3=0x000000ff & (txt>>0*8); + + txt1=0xff -txt1; + txt2=0xff -txt2; + txt3=0xff -txt3; + + int bak1=0x000000ff & (backg>>2*8); + int bak2=0x000000ff & (backg>>1*8); + int bak3=0x000000ff & (backg>>0*8); + + txt1=abs(bak1-txt1); + txt2=abs(bak2-txt2); + txt3=abs(bak3-txt3); + + txt =txt1<<2*8 + |txt2<<1*8 + |txt3<<0*8 + ; + } + + + +template< class DERIVED > +#if _WTL_VER < 0x0810 +class CTask98DialogImpl : public CIndirectDialogImpl, public CDialogBaseUnits +#else +class CTask98DialogImpl : public CIndirectDialogImpl, public WTL::CDialogBaseUnits +#endif +{ +public: typedef CTask98DialogImpl Tp; + typedef CIndirectDialogImpl TpParent; + friend TpParent; + +public: + enum + {IDC_TASKDLG_OK = IDOK, + IDC_TASKDLG_YES = IDYES, + IDC_TASKDLG_NO = IDNO, + IDC_TASKDLG_CANCEL = IDCANCEL, + IDC_TASKDLG_RETRY = IDRETRY, + IDC_TASKDLG_CLOSE = IDCLOSE, + // + IDC_TASKDLG_TITLETEXT = 0x7400, + IDC_TASKDLG_INSTRUCTIONSTEXT, + IDC_TASKDLG_INSTRUCTIONSICON, + IDC_TASKDLG_CONTENTTEXT, + IDC_TASKDLG_BOTTOMDIVIDER, + IDC_TASKDLG_VERIFYBUTTON, + IDC_TASKDLG_EXPANDERICON, + IDC_TASKDLG_EXPANDERTEXT, + IDC_TASKDLG_EXTRATEXT, + IDC_TASKDLG_FOOTERDIVIDER, + IDC_TASKDLG_FOOTERTEXT, + IDC_TASKDLG_FOOTERICON, + IDC_TASKDLG_PROGRESSBAR, + // + IDC_TASKDLG_CUSTOMBUTTON_FIRST, + IDC_TASKDLG_CUSTOMBUTTON_LAST = IDC_TASKDLG_CUSTOMBUTTON_FIRST + 20 //mutatebale + + 20 //non mutatebale + , + IDC_TASKDLG_RADIOBUTTON_FIRST, + IDC_TASKDLG_RADIOBUTTON_LAST = IDC_TASKDLG_RADIOBUTTON_FIRST + 20, + }; + + enum {TIMERID_TIGGER = 4050, + TIMERID_HOVERLINK = 4051, + WIDTH_PROBE = 99999, + }; + + enum {MAX_TEXT_LENGTH = 2048 + }; +public: + CTask98DialogImpl() : m_bNavigated(false),ShowExpanderIcon(false) + {DECL_dThis; + ::ZeroMemory(&m_cfg, sizeof(m_cfg)); + m_cfg.cbSize = sizeof(TASKDIALOGCONFIG); + m_cfg.cbSize_X = sizeof(TASKDIALOGCONFIG_X); + m_cfg.hInstance = ModuleHelper::GetResourceInstance(); + m_cfg.pfCallback = DERIVED::TaskDialogCallback; //use the one of the derived if defined otherwise the own as default + m_cfg.lpCallbackData = (LONG_PTR) dThis; //as callback owning instance use the defived + _Reset(); + } + +public: + BEGIN_MSG_MAP(CTask98DialogImpl) + MESSAGE_HANDLER(WM_INITDIALOG, OnWmInitDialog) + MESSAGE_HANDLER(WM_DESTROY, OnWmDestroy) + MESSAGE_HANDLER(WM_HELP, OnWmHelp) + MESSAGE_HANDLER(WM_TIMER, OnWmTimer) + MESSAGE_HANDLER(WM_ERASEBKGND, OnWmEraseBkgnd) + MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnWmCtlColor) + MESSAGE_HANDLER(WM_CTLCOLORBTN, OnWmCtlColor) + MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand) + MESSAGE_HANDLER(WM_DRAWITEM, OnWmDrawItem) + MESSAGE_HANDLER(TDM_CLICK_BUTTON, OnMsgClickButton) + MESSAGE_HANDLER(TDM_CLICK_VERIFICATION, OnMsgClickVerification) + MESSAGE_HANDLER(TDM_CLICK_RADIO_BUTTON, OnMsgClickRadioButton) + MESSAGE_HANDLER(TDM_ENABLE_BUTTON, OnMsgEnableButton) + MESSAGE_HANDLER(TDM_ENABLE_RADIO_BUTTON, OnMsgEnableRadioButton) + MESSAGE_HANDLER(TDM_SET_PROGRESS_BAR_POS, OnMsgSetProgressBarPos) + MESSAGE_HANDLER(TDM_SET_PROGRESS_BAR_RANGE, OnMsgSetProgressBarRange) + MESSAGE_HANDLER(TDM_SET_PROGRESS_BAR_STATE, OnMsgSetProgressBarState) + MESSAGE_HANDLER(TDM_SET_PROGRESS_BAR_MARQUEE, OnMsgSetProgressBarMarquee) + MESSAGE_HANDLER(TDM_SET_MARQUEE_PROGRESS_BAR, OnMsgSetMarqueeProgressBar) + MESSAGE_HANDLER(TDM_SET_ELEMENT_TEXT, OnMsgSetElementText) + MESSAGE_HANDLER(TDM_UPDATE_ELEMENT_TEXT, OnMsgUpdateElementText) + COMMAND_HANDLER(IDC_TASKDLG_EXPANDERICON, STN_CLICKED, OnMsgExpandoClick); + COMMAND_HANDLER(IDC_TASKDLG_EXPANDERTEXT, STN_CLICKED, OnMsgExpandoClick); + COMMAND_HANDLER(IDC_TASKDLG_EXPANDERICON, STN_DBLCLK, OnMsgExpandoClick); + COMMAND_HANDLER(IDC_TASKDLG_EXPANDERTEXT, STN_DBLCLK, OnMsgExpandoClick); + COMMAND_ID_HANDLER(IDC_TASKDLG_VERIFYBUTTON, OnMsgVerificationClick); + COMMAND_RANGE_HANDLER(1, 64, OnMsgCommonButtonClick) + COMMAND_RANGE_HANDLER(IDC_TASKDLG_CUSTOMBUTTON_FIRST, IDC_TASKDLG_CUSTOMBUTTON_LAST, OnMsgCustomButtonClick) + COMMAND_RANGE_HANDLER(IDC_TASKDLG_RADIOBUTTON_FIRST, IDC_TASKDLG_RADIOBUTTON_LAST, OnMsgRadioClick) + NOTIFY_HANDLER(IDC_TASKDLG_CONTENTTEXT, NM_CLICK, OnMsgHyperlinkClicked) + NOTIFY_HANDLER(IDC_TASKDLG_FOOTERTEXT, NM_CLICK, OnMsgHyperlinkClicked) + NOTIFY_HANDLER(IDC_TASKDLG_EXTRATEXT, NM_CLICK, OnMsgHyperlinkClicked) + END_MSG_MAP() + +public:// Operations + + bool SetConfig(const TASKDIALOGCONFIG* pConfig) + { AXF_(IS(pConfig) ,return false); + m_cfg = *pConfig; + AXE_(m_cfg.cButtons <= 20 ,return false); + AXE_(m_cfg.cRadioButtons <= 20 ,return false); + AXE_(IMPLICATES(IS((TDF_USE_COMMAND_LINKS //command link buttos ==> defined buttons + |TDF_USE_COMMAND_LINKS_NO_ICON + ) & m_cfg.dwFlags) + ,IS(m_cfg.cButtons)) ,return false); + + if( IS (m_cfg.pszExpandedInformation) + AND NOT(m_cfg.pszExpandedControlText) + )m_cfg.pszExpandedControlText = L"Hide details"; + + if( IS (m_cfg.pszExpandedInformation) + AND NOT(m_cfg.pszCollapsedControlText) + )m_cfg.pszCollapsedControlText= L"Show details"; + + return true; + } + + bool SetConfig(const TASKDIALOGCONFIG_X* pConfig) + { AXE_(IS(pConfig) ,return false); + m_cfg = *pConfig; + AXE_(m_cfg.cButtons <= 20 ,return false); + AXE_(m_cfg.cRadioButtons <= 20 ,return false); + AXE_(m_cfg.SzPushButtons <= 20 ,return false); + AXE_(IMPLICATES(IS((TDF_USE_COMMAND_LINKS //command link buttos ==> defined buttons + |TDF_USE_COMMAND_LINKS_NO_ICON + ) & m_cfg.dwFlags) + ,IS(m_cfg.cButtons)) ,return false); + + if( IS (m_cfg.pszExpandedInformation) + AND NOT(m_cfg.pszExpandedControlText) + )m_cfg.pszExpandedControlText = L"Hide details"; + + if( IS (m_cfg.pszExpandedInformation) + AND NOT(m_cfg.pszCollapsedControlText) + )m_cfg.pszCollapsedControlText= L"Show details"; + + return true; + } + + bool IsNavigated()const {return m_bNavigated;} + + void GetDialogResult(int* pnButton, int* pnRadioButton, BOOL* pfVerificationFlagChecked) const + { AXE_(NOT(::IsWindow(m_hWnd)) ,if(IS(pnButton)) *pnButton =0; + if(IS(pnRadioButton))*pnRadioButton =0; + if(IS(pfVerificationFlagChecked)) *pfVerificationFlagChecked =false; + return); + + if(IS(pnButton)) *pnButton = m_iButtonResult; + if(IS(pnRadioButton)) *pnRadioButton = m_iRadioResult; + if(IS(pfVerificationFlagChecked)) *pfVerificationFlagChecked= m_bVerificationResult; + } + + BOOL NavigatePage(TASKDIALOGCONFIG* pTaskConfig) + { AXE_(::IsWindow(m_hWnd) ,return FALSE); + AXE_(SetConfig(pTaskConfig) ,return FALSE); + + m_bNavigated = true; + // BUG: Unlike the real Task Dialog we destroy the window and recreate + // a new dialog. There will be flicker and possible reposition of window. + return EndDialog(IDCANCEL); + } + + UINT GetButton(UINT uID) + { AXE_(::IsWindow(m_hWnd) ,return 0); + + bool found =false; + UINT idRes =uID; + UINT i = 0; + for( i = 0; (i < m_cfg.cButtons) AND NOT(found); i++ + ){if( m_cfg.pButtons[i].nButtonID == (int) uID ){idRes =(IDC_TASKDLG_CUSTOMBUTTON_FIRST + i); + found=true; + } + } + for( UINT j = 0; (j < m_cfg.SzPushButtons) AND NOT(found); j++ + ){if( m_cfg.PushButtons[j].nButtonID == (int) uID ){idRes =(IDC_TASKDLG_CUSTOMBUTTON_FIRST + i+j); + found=true; + } + } + + return idRes; + } + + BOOL ClickButton(UINT uID) + { AXE_(::IsWindow(m_hWnd) ,return FALSE); + + CButton ctrl = GetDlgItem(GetButton(uID)); AXE_(IS(ctrl.IsWindow()) + ,return FALSE); + ctrl.Click(); + return TRUE; + } + + BOOL EnableButton(UINT uID, BOOL bEnable) + { AXE_(::IsWindow(m_hWnd) ,return FALSE); + + CButton ctrl = GetDlgItem(GetButton(uID)); AXE_(IS(ctrl.IsWindow()) + ,return FALSE); + return ctrl.EnableWindow(bEnable); + } + + BOOL ClickRadioButton(UINT uID) + { AXE_(::IsWindow(m_hWnd) ,return FALSE); + + CButton ctrl; + for(UINT i = 0; i < m_cfg.cRadioButtons; i++ + ){ + if(m_cfg.pRadioButtons[i].nButtonID == (int) uID + )ctrl = GetDlgItem(IDC_TASKDLG_RADIOBUTTON_FIRST +i); + } AXE_(IS(ctrl.IsWindow()) + ,return FALSE); + ctrl.Click(); + return TRUE; + } + + BOOL EnableRadioButton(UINT uID, BOOL bEnable) + { AXE_(::IsWindow(m_hWnd) ,return FALSE); + + CButton ctrl; + for(UINT i = 0; i < m_cfg.cRadioButtons; i++ + ){ + if(m_cfg.pRadioButtons[i].nButtonID == (int) uID + )ctrl = GetDlgItem(IDC_TASKDLG_RADIOBUTTON_FIRST +i); + } AXE_(IS(ctrl.IsWindow()) + ,return FALSE); + return ctrl.EnableWindow(bEnable); + } + + BOOL ClickVerification(BOOL bChecked, BOOL bTakeFocus) + {BOOL bRes = CheckDlgButton(IDC_TASKDLG_VERIFYBUTTON + ,bChecked ? BST_CHECKED : BST_UNCHECKED); + if(bRes AND bTakeFocus + )CWindow(GetDlgItem(IDC_TASKDLG_VERIFYBUTTON)).SetFocus(); + + return bRes; + } + + BOOL SetElementText(TASKDIALOG_ELEMENTS Element, LPCWSTR pstrText) + { AXE_(::IsWindow(m_hWnd) ,return FALSE); + + UINT uID = 0; + switch(Element) + {case TDE_CONTENT: uID = IDC_TASKDLG_CONTENTTEXT; break; + case TDE_MAIN_INSTRUCTION: uID = IDC_TASKDLG_INSTRUCTIONSTEXT; break; + case TDE_EXPANDED_INFORMATION: uID = IDC_TASKDLG_EXTRATEXT; break; + case TDE_FOOTER: uID = IDC_TASKDLG_FOOTERTEXT; break; + } + AXE_(IS(uID) + ,return FALSE); + + LPTSTR pstrBuffer = (LPTSTR)malloc(MAX_TEXT_LENGTH * sizeof(TCHAR)); AXE_(IS(pstrBuffer) + ,return FALSE); + _LoadString(pstrText, pstrBuffer, MAX_TEXT_LENGTH); + SetDlgItemText(uID, pstrBuffer); + free(pstrBuffer); + + // BUG: We need to reconstruct the dialog to make space for the new text + return TRUE; + } + + BOOL UpdateElementText(TASKDIALOG_ELEMENTS Element, LPCWSTR pstrText) + {return SetElementText(Element, pstrText); + } + + BOOL UpdateIcon(TASKDIALOG_ICON_ELEMENTS Element, LPCWSTR pstrIcon) + { AXE_(::IsWindow(m_hWnd) ,return FALSE); + AXE_( (TDIE_ICON_FOOTER ==Element) + OR(TDIE_ICON_MAIN ==Element) ,return FALSE); + + UINT nCtlId = 0; + switch(Element) + {case TDIE_ICON_FOOTER: {nCtlId = IDC_TASKDLG_FOOTERICON; + m_iconMain = _LoadIcon(pstrIcon, m_Metrics.cxyLargeIcon); + break; + } + case TDIE_ICON_MAIN: {nCtlId = IDC_TASKDLG_INSTRUCTIONSICON; + m_iconFooter = _LoadIcon(pstrIcon, m_Metrics.cxySmallIcon); + break; + } + } + + CWindow wnd = GetDlgItem(nCtlId); AXE_(wnd.IsWindow() + ,return FALSE); + return wnd.Invalidate(); + } + + BOOL SetProgressBarPos(UINT nPos) + { AXE_(::IsWindow(GetDlgItem(IDC_TASKDLG_PROGRESSBAR)) ,return FALSE); + + return SendDlgItemMessage(IDC_TASKDLG_PROGRESSBAR, PBM_SETPOS, nPos) != 0; + } + + BOOL SetProgressBarRange(UINT nMin, UINT nMax) + { AXE_(::IsWindow(GetDlgItem(IDC_TASKDLG_PROGRESSBAR)) ,return FALSE); + + return SendDlgItemMessage(IDC_TASKDLG_PROGRESSBAR + ,PBM_SETRANGE + ,0 + ,MAKELPARAM(nMin, nMax) + ) != 0; + } + + BOOL SetProgressBarState(int nNewState) + { AXE_(RunTimeHelper::IsVista() ,return FALSE); + AXE_(::IsWindow(GetDlgItem(IDC_TASKDLG_PROGRESSBAR)) ,return FALSE); + + + return SendDlgItemMessage(IDC_TASKDLG_PROGRESSBAR + ,PBM_SETSTATE + ,(WPARAM)nNewState + ,0) != 0; + } + + BOOL SetProgressBarMarquee(int iMarquee, UINT uTimer) + { AXE_(RunTimeHelper::IsVista() ,return FALSE); + AXE_(::IsWindow(GetDlgItem(IDC_TASKDLG_PROGRESSBAR)) ,return FALSE); + + CWindow wnd = GetDlgItem(IDC_TASKDLG_PROGRESSBAR); AXE_(IS(wnd.IsWindow()) + ,return FALSE); + + return wnd.SendMessage(PBM_SETMARQUEE + ,(WPARAM) iMarquee + ,uTimer + ) != 0; + } + + void SetMarqueeProgressBar(BOOL bMarquee) + { AXE_(RunTimeHelper::IsVista() ,return); + AXE_(::IsWindow(GetDlgItem(IDC_TASKDLG_PROGRESSBAR)) ,return); + CWindow wnd = GetDlgItem(IDC_TASKDLG_PROGRESSBAR); AXE_(IS(wnd.IsWindow()) + ,return); + + wnd.ModifyStyle(bMarquee ?0 + :PBS_MARQUEE + ,bMarquee ?PBS_MARQUEE + :0 + ); + SetProgressBarMarquee(1, 30); + } + + // Default TaskDialogEmu callback implementation + static HRESULT CALLBACK TaskDialogCallback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) + { AXE_(lpRefData!=0 ,E_Implementation); + + DERIVED* dThis = (DERIVED*) lpRefData; + ATLASSERT(hwnd==dThis->m_hWnd); hwnd; + HRESULT bRet = Ok; + switch( msg ) + {case TDN_DIALOG_CONSTRUCTED: {dThis->OnDialogConstructed(); break;} + case TDN_CREATED: {dThis->OnCreated(); break;} + case TDN_BUTTON_CLICKED: {bRet = dThis->OnButtonClicked((int) wParam); break;} + case TDN_RADIO_BUTTON_CLICKED: {dThis->OnRadioButtonClicked((int) wParam); break;} + case TDN_HYPERLINK_CLICKED: {dThis->OnHyperlinkClicked((LPCWSTR) lParam); break;} + case TDN_EXPANDO_BUTTON_CLICKED:{dThis->OnExpandoButtonClicked(wParam != 0); break;} + case TDN_VERIFICATION_CLICKED: {dThis->OnVerificationClicked(wParam != 0); break;} + case TDN_HELP: {dThis->OnHelp(); break;} + case TDN_TIMER: {bRet = dThis->OnTimer((DWORD) wParam); break;} + case TDN_NAVIGATED: {dThis->OnNavigated(); break;} + case TDN_DESTROYED: {dThis->OnDestroyed(); break;} + default: { AE(false + ,_T("known: msg")); + LOGGVALDWD(_T("TDL CallBack Notification") + ,_T("unknown") + ,msg); break; + } + } + + return (HRESULT)bRet; //depends form th specific handler + } + + // Overrideables - notification handlers + + void OnDialogConstructed (){} + void OnCreated (){} + BOOL OnButtonClicked (int /*nButton*/){return FALSE;} // don't prevent dialog to close + void OnRadioButtonClicked (int /*nRadioButton*/){} + void OnHyperlinkClicked (LPCWSTR /*pszHREF*/){} + void OnExpandoButtonClicked(bool /*bExpanded*/){} + void OnVerificationClicked (bool /*bChecked*/){} + void OnHelp (){} + BOOL OnTimer (DWORD /*dwTickCount*/){return FALSE;} // don't reset counter + void OnNavigated (){} + void OnDestroyed (){} + + +public: // Data Members + TASKDIALOGCONFIG_X m_cfg; // Copy of configuration + bool m_bNavigated; // Dialog was navigated? + int m_iButtonResult; // Button result + int m_iRadioResult; // Radio-button result + BOOL m_bVerificationResult; // Verification button result + DWORD m_dwTick; // Start tick when dialog was shown + UINT m_nDefCtlId; // Default dialog button + UINT m_nHoverId; // Current hover Command Link button ID + DLUSize m_sizeDialog; // Recommended dialog size (in pixels) + CFont m_fontTitle; // Title font + CFont m_fontText; // Text font + CBrush m_brWhite; // Brush for white (top) background + CBrush m_brGrey; // Brush for grey (bottom) background + CIcon m_iconMain; // Icon in Main Instructions text + CIcon m_iconFooter; // Icon in Footer text + CIcon m_iconArrowNormal; // Command Link arrow + CIcon m_iconArrowHot; // Command Link arrow (hot) + CIcon m_iconChevronLess; // Chevron icon (less) + CIcon m_iconChevronMore; // Chevron icon (more) + bool m_bCreated; // Dialog fully initialized yet? + bool m_bExpanded; // Expando-area is expanded? + bool m_bHasCustomLinks; // Has custom Command Link buttons? + + bool ShowExpanderIcon; ///< as it says. + + struct Metrics {void init(Tp& dlg, CFont& m_fontText,HWND hwndParent) + {bool bIsCommCtrl6 = RunTimeHelper::IsCommCtrl6(); + szCharTtl =DLUSize(4,8)/*DLU*/; + szChar =DLUSize(4,8)/*DLU*/; + + RectDlg = DLURect(); + dlg.InitDialogBaseUnits(dlg.m_fontText, hwndParent); + szCharTtl =PixSize(dlg.GetDialogBaseUnits().cx + ,dlg.GetDialogBaseUnits().cy); + dlg.InitDialogBaseUnits(dlg.m_fontText, hwndParent); + BaseUnit = dlg.GetDialogBaseUnits(); + ActBaseUnit::val() =BaseUnit; + szChar =BaseUnit; + + + RectDlgWork = DLURect(); + sizeDialogPadding = DLUSize(szChar.cx *2//freier rand + ,szChar.cy *1 + ); + cxySmallIcon = PixSize(::GetSystemMetrics(SM_CYSMICON) + ,::GetSystemMetrics(SM_CYSMICON) + ); + cxyLargeIcon = PixSize(::GetSystemMetrics(SM_CYICON) + ,::GetSystemMetrics(SM_CYICON) + ); + cxSmallIconGap = DLUSize(szChar.cx * 3 / 2 + ,0 + ); + + RectTop = DLURect(); + clrBkTop = ::GetSysColor((true || bIsCommCtrl6) ? COLOR_WINDOW : COLOR_BTNFACE); + + RectIconMain = DLURect(); + cyInstructionsGapTop = yDlu(szChar.cy * 1// / 5 + ); + + RectContent = DLURect(); + cxLargeIconGap = DLUSize(szChar.cx * 3 / 2 + ,0 + ); + RectTextMain = DLURect(); + cxBestMainInstruction.n = szChar.cx * 10; //70 zeichen + //clrTitleText = bIsCommCtrl6 ? RGB(0,51,153) : ::GetSysColor(COLOR_BTNTEXT); + clrTitleText = RGB(0,51,153); + makeTxtColFromBackground(clrTitleText,clrBkTop); + + RectTextSub = DLURect(); + cyInstructionsGap = yDlu(szChar.cy * 1);// / 5; + cxBestContent = xDlu(szChar.cx * 10//10 zeichen weniger ls msg main + ); + cyContentGap = yDlu(szChar.cy * 1 / 2 + ); + + RectExpoInside = DLURect(); + RectProgress = DLURect(); + cyProgressBar = yDlu(szChar.cy * 1); + cxBestProgressBar = xDlu(szChar.cx * 25//55 zeichen lang + ); + + RectRadio = DLURect(); + cxRadioIndent = xDlu(szChar.cx * 2// / 2; + ); + sizeRadioButton.cx = ::GetSystemMetrics(SM_CXMENUCHECK) + 6; + sizeRadioButton.cy = ::GetSystemMetrics(SM_CYMENUCHECK); + cxBestRadioButton = xDlu(szChar.cx * 50); + cyRadioGap = yDlu(szChar.cy * 0);//2; + + RectCommand = DLURect(); + cxyArrowIcon = PixSize(20,20); + cxMinCommandLink = xDlu(szChar.cx * 60); + cxBestCommandLink = xDlu(szChar.cx * 70); + sizeLinkPadding.cx = szChar.cx * 2; + sizeLinkPadding.cy = szChar.cy / 2; + clrCommandLinkText = ::GetSysColor(COLOR_BTNTEXT); + clrCommandLinkTextSelected= bIsCommCtrl6 ? RGB(0,51,153) : ::GetSysColor(COLOR_BTNTEXT); + clrCmdLinkSelect = bIsCommCtrl6 ? RGB(140,232,255) : RGB(140,140,140); + makeTxtColFromBackground(clrCmdLinkSelect,clrBkTop); + clrBkCommandSelect = ::GetSysColor(COLOR_BTNFACE);//RGB(0xf0,0xf0,0xf0); + DWORD c1=0x00ff0000 & clrBkCommandSelect; + c1=c1+3*((0x00ff0000-c1)/4); + DWORD c2=0x0000ff00 & clrBkCommandSelect; + c2=c2+3*((0x0000ff00-c2)/4); + DWORD c3=0x000000ff & clrBkCommandSelect; + c3=c3+2*((0x000000ff-c3)/3); + clrBkCommandSelect =c1|c2|c3, + RectBottom = DLURect(); + clrDividerLight = ::GetSysColor(COLOR_BTNSHADOW); + + if( IS(VersWin().asString().Find(_T("Windows 7"))+1) + OR IS(VersWin().asString().Find(_T("Windows Server 2008"))+1) + ) clrBkBottom = clrBkTop; + else clrBkBottom = ::GetSysColor(COLOR_BTNFACE); + RectBottomContent = DLURect(); + cyBottomGap = yDlu(szChar.cy *1); + + RectButtonRow = DLURect(); + RectExpoRow = DLURect(); + RectExpoBtn = DLURect(); + cxyExpanderIcon = PixSize(20,20); + RectExpoText = DLURect(); + + RectCheck = DLURect(); + cxMaxVerification = xDlu(szChar.cx * 40); + + /*RectExpoRow*/RectBtns= DLURect(); + cxButtonsIndent = xDlu(szChar.cx * 8); + cxMinButton = xDlu(szChar.cx * 8); // + sizeButtonPadding.cx = szChar.cx * 1; //immer ingesamt zu ganzen dlus + sizeButtonPadding.cy = szChar.cy * 1/2; + cxButtonGap = xDlu(szChar.cx * 1); + RectFooter = DLURect(); + cyExpanderGap = yDlu(szChar.cy / 1);//3; + cyButtonLineGap = yDlu(szChar.cy * 1);//2 / 3;//if RectButtonRow.cy + + RectIconFooter = DLURect(); + RectFooterText = DLURect(); + RectExpoOutside = DLURect(); + cyFooterGap = yDlu(szChar.cy / 1);//3; //if footertext.cy + RectExpoOutsideText = DLURect(); + + + } + + void reInitColors() + {bool bIsCommCtrl6 = RunTimeHelper::IsCommCtrl6(); + clrBkTop = ::GetSysColor((true || bIsCommCtrl6) ? COLOR_WINDOW : COLOR_BTNFACE); + //clrTitleText = bIsCommCtrl6 ? RGB(0,51,153) : ::GetSysColor(COLOR_BTNTEXT); + clrTitleText = RGB(0,51,153); + makeTxtColFromBackground(clrTitleText,clrBkTop); + + clrCmdLinkSelect = bIsCommCtrl6 ? RGB(140,232,255) : RGB(140,140,140); + makeTxtColFromBackground(clrCmdLinkSelect,clrBkTop); + + if( IS(VersWin().asString().Find(_T("Windows 7"))+1) + OR IS(VersWin().asString().Find(_T("Windows Server 2008"))+1) + ) clrBkBottom = clrBkTop; + else clrBkBottom = ::GetSysColor(COLOR_BTNFACE); + } + //Dlg + DLUSize szCharTtl; + DLUSize szChar; + DLURect RectDlg; //complete client rect + DLURect RectDlgWork; //working rect: leaving blank a border arround + DLUSize sizeDialogPadding; + DLUSize cxySmallIcon; + DLUSize cxyLargeIcon; + DLUSize cxLargeIconGap; + DLUSize cxSmallIconGap; + PixSize BaseUnit; + CLogFont LFMsgBox; + + DLURect RectTop; //der main bereich + COLORREF clrBkTop; + DLURect RectIconMain; + yDlu cyInstructionsGapTop;//if iconmain.cy + DLURect RectContent; //bereich rechts vom main.icon für alles von oben bis ausschließlich der buttonregion + DLURect RectTextMain; //bereich rechts vom main.icon für alles von oben bis ausschließlich der buttonregion + xDlu cxBestMainInstruction; + COLORREF clrTitleText; + DLURect RectTextSub; //bereich rechts vom main.icon für alles von oben bis ausschließlich der buttonregion + yDlu cyInstructionsGap;//if textmain.cy + xDlu cxBestContent; + + yDlu cyContentGap;//before next section after min or sub if something followes + DLURect RectExpoInside; + DLURect RectProgress; + yDlu cyProgressBar; + xDlu cxBestProgressBar; + DLURect RectRadio; + xDlu cxRadioIndent; + xDlu cxBestRadioButton; + DLUSize sizeRadioButton; + yDlu cyRadioGap; + DLURect RectCommand; + DLUSize cxyArrowIcon; + xDlu cxMinCommandLink; + xDlu cxBestCommandLink; + DLUSize sizeLinkPadding; + COLORREF clrCommandLinkText; + COLORREF clrCommandLinkTextSelected; + COLORREF clrBkCommandSelect; + COLORREF clrCmdLinkSelect; + + DLURect RectBottom; //Bereich für alles was mit den push buttons oder expander titel beginnt + COLORREF clrDividerLight; + COLORREF clrBkBottom; + DLURect RectBottomContent; yDlu cyBottomGap; //if IS(RectContent.cx) ^RectContent.cy>RectIconMain.cy + DLURect RectButtonRow; + DLURect RectExpoRow;/**/ + DLURect RectExpoBtn; DLURect RectExpoText; + DLUSize cxyExpanderIcon; + DLURect RectCheck;/**/ + xDlu cxMaxVerification; + /**/DLURect RectBtns; + xDlu cxButtonsIndent;//separates from left dlg border or from expo row + xDlu cxMinButton; + DLUSize sizeButtonPadding; + xDlu cxButtonGap; + + DLURect RectFooter; + yDlu cyExpanderGap;//if exorow.cy + yDlu cyButtonLineGap;//if buttonrow.cy + DLURect RectIconFooter; + DLURect RectFooterText; + + DLURect RectExpoOutside; yDlu cyFooterGap; + DLURect RectExpoOutsideText; + + }m_Metrics; + #define RectDlg m_Metrics.RectDlg + #define RectDlgWork m_Metrics.RectDlgWork + #define RectIconMain m_Metrics.RectIconMain + #define RectTop m_Metrics.RectTop + #define RectContent m_Metrics.RectContent + #define RectTextMain m_Metrics.RectTextMain + #define RectTextSub m_Metrics.RectTextSub + #define RectBottom m_Metrics.RectBottom + #define RectExpoInside m_Metrics.RectExpoInside + #define RectExpoOutside m_Metrics.RectExpoOutside + #define RectProgress m_Metrics.RectProgress + #define RectRadio m_Metrics.RectRadio + #define RectCommand m_Metrics.RectCommand + #define RectBottomContent m_Metrics.RectBottomContent + #define RectExpoRow m_Metrics.RectExpoRow + #define RectExpoBtn m_Metrics.RectExpoBtn + #define RectExpoText m_Metrics.RectExpoText + #define RectCheck m_Metrics.RectCheck + #define RectBtns m_Metrics.RectBtns + #define RectButtonRow m_Metrics.RectButtonRow + #define RectFooter m_Metrics.RectFooter + #define RectIconFooter m_Metrics.RectIconFooter + #define RectFooterText m_Metrics.RectFooterText + #define RectExpoOutsideText m_Metrics.RectExpoOutsideText + + +public: // Construction + void DoInitTemplate () + { + m_Template.Reset(); + + AtlInitCommonControls(ICC_STANDARD_CLASSES + |ICC_ANIMATE_CLASS + |ICC_BAR_CLASSES + |ICC_COOL_CLASSES + |ICC_DATE_CLASSES + |ICC_HOTKEY_CLASS + |ICC_INTERNET_CLASSES + |ICC_LINK_CLASS + |ICC_LISTVIEW_CLASSES + |ICC_NATIVEFNTCTL_CLASS + |ICC_PAGESCROLLER_CLASS + |ICC_PROGRESS_CLASS + |ICC_TAB_CLASSES + |ICC_TREEVIEW_CLASSES + |ICC_UPDOWN_CLASS + |ICC_USEREX_CLASSES + ); + + bool bIsCommCtrl6 = RunTimeHelper::IsCommCtrl6(); + + CWindowDC dc = HWND_DESKTOP; + if( NOT(m_fontTitle.IsNull()) ) m_fontTitle.DeleteObject(); + if( NOT(m_fontText.IsNull()) ) m_fontText.DeleteObject(); + + m_Metrics.LFMsgBox.SetMessageBoxFont(); + m_fontText.CreateFontIndirect(&m_Metrics.LFMsgBox); + + CLogFont lfTitle = m_Metrics.LFMsgBox; + lfTitle.MakeLarger(bIsCommCtrl6 ? 4 : 2); + lfTitle.MakeBolder(bIsCommCtrl6 ? 0 : 1); + m_fontTitle.CreateFontIndirect(&lfTitle); + + m_Metrics.init(*this,m_fontText,m_cfg.hwndParent); + + if( NOT(m_brWhite.IsNull()) ) m_brWhite.DeleteObject(); + if( NOT(m_brGrey.IsNull()) ) m_brGrey.DeleteObject(); + + m_brWhite.CreateSolidBrush(m_Metrics.clrBkTop); + m_brGrey .CreateSolidBrush(m_Metrics.clrBkBottom); + + // Determine size of dialog. First try to determine the optimal width of + // the dialog. Then calculate the height of the dialog based on that width. + const xDlu CX_MIN_DIALOG(m_Metrics.szChar.cy * 30); + + m_sizeDialog = _LayoutControls(((m_cfg.cxWidth > 0) ?xDlu(m_cfg.cxWidth) + :xDlu(WIDTH_PROBE)) + ,false); + if( m_sizeDialog.cx < CX_MIN_DIALOG.n + ) m_sizeDialog.cx = CX_MIN_DIALOG.n; + + if( m_cfg.cxWidth > 0 + ) m_sizeDialog.cx = m_cfg.cxWidth;//stay in DLU//MapDialogUnitsX(m_cfg.cxWidth); + + xDlu cxWidth = m_sizeDialog; + m_sizeDialog = _LayoutControls(cxWidth, false); + m_sizeDialog.cx = cxWidth.n; + + if( NOT(m_cfg.dwCommonButtons) + AND NOT(m_cfg.cButtons) + AND NOT(m_cfg.SzPushButtons) + ) m_cfg.dwCommonButtons = TDCBF_CLOSE_BUTTON; //at least one Closing Btn should be avail + + if( IS(TDCBF_CANCEL_BUTTON & m_cfg.dwCommonButtons) //cancel button consitsently should also alolow ESC cancelation + ) m_cfg.dwFlags |= TDF_ALLOW_DIALOG_CANCELLATION; + + DWORD dwHelpID = 0; + DWORD dwExStyle = 0; + DWORD dwStyle = WS_POPUP + | WS_CAPTION + | WS_CLIPCHILDREN + | WS_CLIPSIBLINGS + | DS_MODALFRAME + | DS_ABSALIGN //tells the coordinates are screen instead of client coordinates + | WS_POPUP + //| DS_SETFOREGROUND + ; + + if( IS (TDF_CAN_BE_MINIMIZED & m_cfg.dwFlags)) dwStyle |= WS_MINIMIZEBOX; + if( IS (TDF_ALLOW_DIALOG_CANCELLATION & m_cfg.dwFlags)) dwStyle |= WS_SYSMENU; + /*if( NOT(TDF_POSITION_RELATIVE_TO_WINDOW& m_cfg.dwFlags))*/ dwStyle |= DS_CENTER; + if( IS (TDF_RTL_LAYOUT & m_cfg.dwFlags)) dwExStyle|= WS_EX_LAYOUTRTL | WS_EX_RIGHT; + + TCHAR szCaption[120] = { 0 }; + _LoadString(m_cfg.pszWindowTitle, szCaption, sizeof(szCaption) / sizeof(TCHAR)); + + WORD lfHeight = (WORD) m_Metrics.LFMsgBox.lfHeight; + if(m_Metrics.LFMsgBox.lfHeight < 0 + )lfHeight = (WORD) (-MulDiv(72, m_Metrics.LFMsgBox.lfHeight, GetDeviceCaps(dc, LOGPIXELSY))); + + //SIZE dluDialog = MapDialogPixels(m_sizeDialog); + //DLURect rc = _CenterDialog(dluDialog); + DLURect rc = _CenterDialog(m_sizeDialog); + + doCreateTemplate ( true, szCaption + , xDlu(rc.left) + , yDlu(rc.top) + , xDlu(m_sizeDialog.cx) + , yDlu(m_sizeDialog.cy) + , dwStyle + , dwExStyle + , m_Metrics.LFMsgBox.lfFaceName + , lfHeight + , (WORD) m_Metrics.LFMsgBox.lfWeight + , m_Metrics.LFMsgBox.lfItalic + , m_Metrics.LFMsgBox.lfCharSet + , dwHelpID + ); + } + + void doCreateTemplate( bool bDlgEx + , LPCTSTR lpszCaption + , xDlu nX + , yDlu nY + , xDlu nWidth + , yDlu nHeight + , DWORD dwStyle = 0 + , DWORD dwExStyle = 0 + , LPCTSTR lpstrFontName = NULL + , WORD wFontSize = 0 + , WORD wWeight = 0 + , BYTE bItalic = 0 + , BYTE bCharset = 0 + , DWORD dwHelpID = 0 + , ATL::_U_STRINGorID ClassName = 0U + , ATL::_U_STRINGorID Menu = 0U + ){ + m_Template.Create( true + , lpszCaption + , (short) nX.n + , (short) nY.n + , (short) nWidth.n + , (short) nHeight.n + , dwStyle + , dwExStyle + , lpstrFontName + , wFontSize + , wWeight + , bItalic + , bCharset + , dwHelpID + ); + } + void DoInitControls () + {_LayoutControls(m_sizeDialog, true); + } + + // Message handler + LRESULT OnWmInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + ATBD(_T("accept also callbacks. {Not accepting callbacks at this moment...}")); + + m_bCreated = false; + _Reset(); + + // Font assignment + SendMessageToDescendants(WM_SETFONT, (WPARAM) static_cast(m_fontText)); + SendDlgItemMessage(IDC_TASKDLG_INSTRUCTIONSTEXT, WM_SETFONT, (WPARAM) (HFONT) m_fontTitle); + + // Create a timer? + if( m_bHasCustomLinks ) SetTimer(TIMERID_HOVERLINK, 100); + if(IS(TDF_CALLBACK_TIMER & m_cfg.dwFlags)) SetTimer(TIMERID_TIGGER , 200); + + // Set verification checkmark + if(IS(TDF_VERIFICATION_FLAG_CHECKED & m_cfg.dwFlags)) CheckDlgButton(IDC_TASKDLG_VERIFYBUTTON, BST_CHECKED); + + // Set Marquee Progress Bar + if(IS(TDF_SHOW_MARQUEE_PROGRESS_BAR & m_cfg.dwFlags)) SetMarqueeProgressBar(TRUE); + + // Set default radio button (may be first button) + if( NOT(TDF_NO_DEFAULT_RADIO_BUTTON & m_cfg.dwFlags) + AND (m_cfg.cRadioButtons > 0) + ){ + CButton ctrl; + for( UINT n = 0 + ; NOT(ctrl.IsWindow()) + AND(n < m_cfg.cRadioButtons) + ; n++ + ){ + if( m_cfg.nDefaultRadioButton == m_cfg.pRadioButtons[n].nButtonID + ) ctrl = GetDlgItem(IDC_TASKDLG_RADIOBUTTON_FIRST + n); + } + + if( NOT(ctrl.IsWindow()) ) ctrl = GetDlgItem(IDC_TASKDLG_RADIOBUTTON_FIRST); + if( ctrl.IsWindow() ) ctrl.Click(); + } + + // Clear arrow image on lines? + if( NOT(m_bHasCustomLinks) + AND IS (TDF_USE_COMMAND_LINKS_NO_ICON & m_cfg.dwFlags) + ) { + for( UINT n = 0; n < m_cfg.cButtons; n++ + ){ + CButton ctrl = GetDlgItem(IDC_TASKDLG_CUSTOMBUTTON_FIRST + n); + BUTTON_IMAGELIST bil= { (HIMAGELIST) -1, 0 }; + ctrl.SendMessage(BCM_SETIMAGELIST, 0, (LPARAM) &bil); + } + } + + // Set expansion level + if( IS(m_cfg.pszExpandedInformation) + AND NOT(TDF_EXPANDED_BY_DEFAULT & m_cfg.dwFlags) + )SendMessage(WM_COMMAND, MAKEWPARAM(IDC_TASKDLG_EXPANDERICON, STN_CLICKED)); + + // Set default dialog button + if( (m_nDefCtlId > 0) + AND(m_nDefCtlId != (UINT) -1) + ){ + SendMessage(DM_SETDEFID, m_nDefCtlId); + CWindow(GetDlgItem(m_nDefCtlId)).SetFocus(); + } + + // Get icons... + m_iconMain = (HICON) (IS(TDF_USE_HICON_MAIN & m_cfg.dwFlags) + ? m_cfg.hMainIcon + : _LoadIcon(m_cfg.pszMainIcon, m_Metrics.cxyLargeIcon)); + + m_iconFooter = (HICON) (IS(TDF_USE_HICON_FOOTER & m_cfg.dwFlags) + ? m_cfg.hFooterIcon + : _LoadIcon(m_cfg.pszFooterIcon, m_Metrics.cxySmallIcon)); + + m_iconArrowHot = _LoadIcon(makeIntResourceW(IDI_TASKDLG_ARROW_HOT) , 20); + m_iconArrowNormal = _LoadIcon(makeIntResourceW(IDI_TASKDLG_ARROW_NORMAL), 20); + m_iconChevronLess = _LoadIcon(makeIntResourceW(IDI_TASKDLG_CHEVRON_LESS), 20); + m_iconChevronMore = _LoadIcon(makeIntResourceW(IDI_TASKDLG_CHEVRON_MORE), 20); + + if( NOT(m_iconMain.IsNull()) + AND NOT(GetParent()) + ) SetIcon(m_iconMain, FALSE); + + // Play that funky music... + _PlaySound(); + + // Ready to accept user input. + m_bCreated = true; + + // Send inital callback messages. + _DoCallback(TDN_DIALOG_CONSTRUCTED); + _DoCallback(m_bNavigated ? TDN_NAVIGATED : TDN_CREATED); + + m_bNavigated = false; + return 0; + } + + LRESULT OnWmDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + KillTimer(TIMERID_TIGGER); + KillTimer(TIMERID_HOVERLINK); + _DoCallback(TDN_DESTROYED); + m_bVerificationResult = IsDlgButtonChecked(IDC_TASKDLG_VERIFYBUTTON); + bHandled = FALSE; + return 0; + } + + LRESULT OnWmHelp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + _DoCallback(TDN_HELP); + return 0; + } + + LRESULT OnWmTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(TIMERID_TIGGER == wParam + ){ + BOOL bReset = (BOOL) _DoCallback(TDN_TIMER, ::GetTickCount() - m_dwTick); + if( bReset + ) m_dwTick = ::GetTickCount(); + } + + if(TIMERID_HOVERLINK == wParam + ){ + POINT pt = { 0 }; + ::GetCursorPos(&pt); + ScreenToClient(&pt); + + UINT nHoverId = 0; + HWND hWnd = ::ChildWindowFromPoint(m_hWnd, pt); + if( hWnd != NULL + ){ + UINT nCtlId = ::GetDlgCtrlID(hWnd); + if( (nCtlId >= IDC_TASKDLG_CUSTOMBUTTON_FIRST) + AND(nCtlId <= IDC_TASKDLG_CUSTOMBUTTON_LAST) + )nHoverId = nCtlId; + } + if(m_nHoverId != nHoverId + ){ + if(IS(m_nHoverId) + )CWindow(GetDlgItem(m_nHoverId)).Invalidate(); + + m_nHoverId = nHoverId; + if(IS(m_nHoverId) + )CWindow(GetDlgItem(m_nHoverId)).Invalidate(); + } + } + bHandled = FALSE; + return 0; + } + + LRESULT OnWmEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + m_Metrics.reInitColors(); + + DLUSize rcOffset=RectExpoInside.size(); + rcOffset.cx=0; + bool adapt = IS(RectExpoInside.size().cy) + AND NOT(m_bExpanded); + + CClientDC dc = m_hWnd; + + PixRect rcClient; + GetClientRect(&rcClient); + PixRect rDlg;rDlg =RectDlg; + PixRect rcWin;GetWindowRect(&rcWin); + PixSize szWin=rcWin.size(); + PixSize szDlg=rDlg.size(); + PixSize szCli=rcClient.size(); + + PixRect rcTop =rcClient; + rcTop.bottom =RectTop.pix().bottom;//{ 0, 0 , rcClient.right, m_Metrics.iButtonLinePos }; + if(adapt)rcTop.bottom -=(rcOffset.pix().cy +m_Metrics.szChar.pix().cy); + dc.FillSolidRect(&rcTop, m_Metrics.clrBkTop); + + PixRect rcBottom =rcClient; + rcBottom.top =RectBottom.pix().top;//{ 0, m_Metrics.iButtonLinePos, rcClient.right, rcClient.bottom }; + if(adapt)rcBottom.top -=(rcOffset.pix().cy +m_Metrics.szChar.pix().cy); + dc.FillSolidRect(&rcBottom, m_Metrics.clrBkBottom); + +if(false) + {LONG ctop(RGB(0xff,0xff,0x77)); +LONG cbot(RGB(0xbb,0xbb,0xff)); +PixRect rctmp; +rctmp=RectTop; +dc.FillSolidRect(&rctmp, ctop); +rctmp=RectBottom; +dc.FillSolidRect(&rctmp, cbot); +ctop=(RGB(0xff,0xff,0x88)); +cbot=(RGB(0xcc,0xcc,0xff)); +rctmp=RectContent; +dc.FillSolidRect(&rctmp, ctop); +rctmp=RectBottomContent; +dc.FillSolidRect(&rctmp, cbot); + +ctop=(RGB(0xff,0xff,0x99)); +rctmp=RectTextMain; +dc.FillSolidRect(&rctmp, ctop); +ctop=(RGB(0xff,0xfe,0x99)); +rctmp=RectBottomContent; +dc.FillSolidRect(&rctmp, cbot); +ctop=(RGB(0xff,0xfd,0x99)); +rctmp=RectTextSub; +dc.FillSolidRect(&rctmp, cbot); +ctop=(RGB(0xff,0xfc,0x99)); +rctmp=RectExpoInside; +dc.FillSolidRect(&rctmp, cbot); + +cbot=(RGB(0xdd,0xdd,0xff)); + + } +bool doGrid=false; +#ifdef TESTSETCONTEXTTONOTDEFINEATNORMAL + doGrid=true; +#else + doGrid =false; +#endif +if(doGrid) + { +//draw dlu grd: + PixRect pil;PixRect pitrc; +DWORD clrGrid =RGB(0xff,0,0) BIT_XOR ((m_Metrics.clrBkTop BIT_XOR m_Metrics.clrBkBottom)); +dc.SetTextColor(clrGrid); +dc.SetBkMode(TRANSPARENT); +PixSize basU =ActBaseUnit().val(); +CString n=_T("0"); +DLURect clientDlu;clientDlu =rcClient; +DLURect l;l.top =0; +for(int z=0;l.top0xf)z=0; +else z++; +n.Format(_T("%x"),Vx_(z)); +l.top+=8/2; +//_AlignDLU(l.top, HTBOTTOM); +} +l.left =0; +for(int z=0;l.left0xf)z=0; +else z++; +n.Format(_T("%x"),Vx_(z)); +l.left+=4/2; +//_AlignDLU(l.left, HTRIGHT); +} + } + + return 1; + } + + LRESULT OnWmCtlColor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + m_Metrics.reInitColors(); + + LRESULT lRes = DefWindowProc(); + UINT nCtlID = ::GetDlgCtrlID((HWND) lParam); + CDCHandle dc = (HDC) wParam; + + switch( nCtlID ) + { + case IDC_TASKDLG_INSTRUCTIONSICON: {dc.SetBkMode(TRANSPARENT); + dc.SetBkColor(m_Metrics.clrBkTop); + lRes = (LRESULT) static_cast(m_brWhite); + break; + } + case IDC_TASKDLG_INSTRUCTIONSTEXT: {dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(m_Metrics.clrTitleText); + dc.SetBkColor(m_Metrics.clrBkTop); + lRes = (LRESULT) static_cast(m_brWhite); + break; + } + case IDC_TASKDLG_CONTENTTEXT: {dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT)); + dc.SetBkColor(m_Metrics.clrBkTop); + lRes = (LRESULT) static_cast(m_brWhite); + break; + } + case IDC_TASKDLG_FOOTERICON: + case IDC_TASKDLG_FOOTERTEXT: + case IDC_TASKDLG_EXPANDERICON: + case IDC_TASKDLG_EXPANDERTEXT: + case IDC_TASKDLG_VERIFYBUTTON: {dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT)); + dc.SetBkColor(m_Metrics.clrBkBottom); + lRes = (LRESULT) static_cast(m_brGrey); + break; + } + case IDC_TASKDLG_OK: + case IDC_TASKDLG_NO: + case IDC_TASKDLG_YES: + case IDC_TASKDLG_RETRY: + case IDC_TASKDLG_CLOSE: + case IDC_TASKDLG_CANCEL: {dc.SetBkMode(TRANSPARENT); + //dc.SetBkColor(m_Metrics.clrBkBottom); + lRes = (LRESULT) static_cast(m_brGrey); + break; + } + default: {dc.SetBkMode(TRANSPARENT); + COLORREF clrBack; + if( (nCtlID >= IDC_TASKDLG_RADIOBUTTON_FIRST) + AND(nCtlID <= IDC_TASKDLG_RADIOBUTTON_LAST) + ) { + clrBack = m_Metrics.clrBkTop; + lRes = (LRESULT) static_cast(m_brWhite); + } + else if( (nCtlID >= IDC_TASKDLG_CUSTOMBUTTON_FIRST) + AND(nCtlID <= IDC_TASKDLG_CUSTOMBUTTON_LAST) + AND IS((TDF_USE_COMMAND_LINKS + |TDF_USE_COMMAND_LINKS_NO_ICON + )& m_cfg.dwFlags) + ) { + clrBack = m_Metrics.clrBkTop; + lRes = (LRESULT) static_cast(m_brWhite); + } + else if( (IDC_TASKDLG_EXTRATEXT ==nCtlID) + AND NOT(TDF_EXPAND_FOOTER_AREA & m_cfg.dwFlags) + ) { + clrBack = m_Metrics.clrBkTop; + lRes = (LRESULT) static_cast(m_brWhite); + } + else{ + clrBack = m_Metrics.clrBkBottom; + lRes = (LRESULT) static_cast(m_brGrey); + } + + dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT)); + dc.SetBkMode(TRANSPARENT); + dc.SetBkColor(clrBack); + } + } + return lRes; + } + + LRESULT OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if( wParam == SC_CLOSE + ){ + if( NOT(TDF_ALLOW_DIALOG_CANCELLATION & m_cfg.dwFlags) + ) return 0; + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnWmDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + m_Metrics.reInitColors(); + + LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam; + if( m_bHasCustomLinks + AND(lpDIS->CtlID >= IDC_TASKDLG_CUSTOMBUTTON_FIRST) + AND(lpDIS->CtlID <= IDC_TASKDLG_CUSTOMBUTTON_LAST ) + ){ + _CustomDrawCommandLink(lpDIS); + return 0; + } + if(lpDIS->CtlID == IDC_TASKDLG_INSTRUCTIONSICON + ){ + _CustomDrawIcon(lpDIS, m_Metrics.clrBkTop, m_iconMain, m_Metrics.cxyLargeIcon); + return 0; + } + if(lpDIS->CtlID == IDC_TASKDLG_FOOTERICON + ){ + _CustomDrawIcon(lpDIS, m_Metrics.clrBkBottom, m_iconFooter, m_Metrics.cxySmallIcon); + return 0; + } + if(lpDIS->CtlID == IDC_TASKDLG_EXPANDERICON + ){ + if(ShowExpanderIcon + ){ + _CustomDrawIcon(lpDIS, m_Metrics.clrBkBottom + , m_bExpanded ? m_iconChevronLess + : m_iconChevronMore + , m_Metrics.cxyExpanderIcon); + } + return 0; + } + if(lpDIS->CtlID == IDC_TASKDLG_FOOTERDIVIDER + ){ + _CustomDrawDivider(lpDIS); + return 0; + } + + bHandled = FALSE; + return 0; + } + + // TaskDialogEmu API messages + + LRESULT OnMsgClickButton(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + ClickButton((int)wParam); + return 0; + } + + LRESULT OnMsgClickRadioButton(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + ClickRadioButton((int)wParam); + return 0; + } + + LRESULT OnMsgClickVerification(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + ClickVerification((BOOL) wParam, (BOOL) lParam); + return 0; + } + + LRESULT OnMsgEnableButton(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + return (LRESULT) EnableButton((int)wParam, (BOOL) lParam); + } + + LRESULT OnMsgEnableRadioButton(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + return (LRESULT) EnableRadioButton((int)wParam, (BOOL) lParam); + } + + LRESULT OnMsgSetElementText(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + return (LRESULT) SetElementText((TASKDIALOG_ELEMENTS) wParam, (LPCWSTR) lParam); + } + + LRESULT OnMsgUpdateElementText(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + return (LRESULT) UpdateElementText((TASKDIALOG_ELEMENTS) wParam, (LPCWSTR) lParam); + } + + LRESULT OnMsgSetProgressBarPos(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + SetProgressBarPos((UINT)wParam); + return 0; + } + + LRESULT OnMsgSetProgressBarRange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + SetProgressBarRange(LOWORD(lParam), HIWORD(lParam)); + return 0; + } + + LRESULT OnMsgSetMarqueeProgressBar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + SetMarqueeProgressBar((BOOL) wParam); + return 0; + } + + LRESULT OnMsgSetProgressBarState(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT) SetProgressBarState((int) wParam); + } + + LRESULT OnMsgSetProgressBarMarquee(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + return (LRESULT) SetProgressBarMarquee((int)wParam, (UINT)lParam); + } + + // Command message handlers + LRESULT OnMsgCommonButtonClick(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + UINT nBtnID = wID; + if( _DoCallback(TDN_BUTTON_CLICKED, nBtnID) == S_FALSE + ) return 0; + + m_iButtonResult = (int) nBtnID; + EndDialog(wID); + return 0; + } + + LRESULT OnMsgCustomButtonClick(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + UINT idxBtn =wID - IDC_TASKDLG_CUSTOMBUTTON_FIRST; + int nBtnID = -1; + if(idxBtn < m_cfg.cButtons) nBtnID = m_cfg.pButtons[idxBtn].nButtonID; + else {idxBtn = wID - IDC_TASKDLG_CUSTOMBUTTON_FIRST -m_cfg.cButtons; + if(idxBtn < m_cfg.SzPushButtons + )nBtnID = m_cfg.PushButtons[idxBtn].nButtonID; + } + if( S_FALSE ==_DoCallback(TDN_BUTTON_CLICKED, nBtnID) + ) return 0; + + m_iButtonResult = (int) nBtnID; + + EndDialog(wID); + return 0; + } + + LRESULT OnMsgExpandoClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + m_bExpanded = NOT(m_bExpanded); + _DoCallback(TDN_EXPANDO_BUTTON_CLICKED, m_bExpanded); + _DoExpandCollapse(); + return 0; + } + + LRESULT OnMsgVerificationClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + _DoCallback(TDN_VERIFICATION_CLICKED + ,BST_CHECKED ==IsDlgButtonChecked(IDC_TASKDLG_VERIFYBUTTON)); + #ifdef _DEBUG + PixRect rc;rc=(DLURect()=DLUPoint(0,7*8))=DLUSize(5*4,2*8);//_AlignDLU(rc); + CStatic* s=new CStatic; + s->Create(m_hWnd,rc,_T("On the Flow Button"),WS_CHILD | WS_VISIBLE |BS_GROUPBOX ,0); + s->ShowWindow(SW_SHOW); + #endif + return 0; + } + + LRESULT OnMsgRadioClick(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + m_iRadioResult = (int) m_cfg.pRadioButtons[wID - IDC_TASKDLG_RADIOBUTTON_FIRST].nButtonID; + _DoCallback(TDN_RADIO_BUTTON_CLICKED, (WPARAM) m_iRadioResult); + return 0; + } + + LRESULT OnMsgHyperlinkClicked(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + NMLINK* pLink = (NMLINK*) pnmh; + _DoCallback(TDN_HYPERLINK_CLICKED, 0 + ,(LPARAM) static_cast(('\0' !=pLink->item.szID[0] + ) ? pLink->item.szID + : pLink->item.szUrl) + ); + return 0; + } + + // Implementation + + void _Reset() { + m_iRadioResult = 0; + m_iButtonResult = IDCANCEL; + m_bExpanded = true; + m_nHoverId = 0; + m_dwTick = ::GetTickCount(); + } + + DLUSize _LayoutControls(xDlu cxMaxDialog, bool createControls) + {bool isProbe = (cxMaxDialog.n == WIDTH_PROBE); + xDlu cxMaxLineReal= xDlu(cxMaxDialog.n - m_Metrics.sizeDialogPadding.dluX().n); + + m_cfg.dwFlags |= TDF_EXPAND_FOOTER_AREA; //expand in conten yet not supported + + DLUSize sizeEmpty(0,0); + LPTSTR pstrBuffer = (LPTSTR) malloc(MAX_TEXT_LENGTH * sizeof(TCHAR)); AXE(IS(pstrBuffer) + ,_T("pstrBuffer =malloc; {memory low}") + ,return sizeEmpty); + DLUSize sizeText; + ActBaseUnit::val(m_Metrics.BaseUnit); + + xDlu cxMaxText =xDlu(0); + DLUSize sizeTitle =(0,0); + DLUSize sizeTemp =(0,0); + DWORD dwStyle =0; + DWORD dwExStyle =0; + UINT n =0; + m_nDefCtlId =0; + bool bIsCommCtrl6 = RunTimeHelper::IsCommCtrl6(); + bool bIsVista = RunTimeHelper::IsVista(); + + RectDlg =DLURect(); + RectDlgWork =RectDlg; + #define ypos RectDlgWork.bottom//tmp, obsoleting + RectDlgWork =DLUPoint(m_Metrics.sizeDialogPadding);//top left free space of RectDlg +// _AlignDLU(RectDlgWork); + + RectTop =RectDlgWork; + { // Main icon + RectIconMain=DLURect(); + if( IS(m_cfg.pszMainIcon) + OR IS(TDF_USE_HICON_MAIN & m_cfg.dwFlags) + ){ + RectIconMain =RectTop; +// _AlignDLU(RectIconMain); + RectIconMain =DLUSize()=m_Metrics.cxyLargeIcon; + //_AlignDLU(RectIconMain); dont align iconbox + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_OWNERDRAW |WS_EX_TRANSPARENT; + dwExStyle = 0; + +//RectIconMain.top+=100; + _AddControl(CStatic::GetWndClassName() + , IDC_TASKDLG_INSTRUCTIONSICON + , RectIconMain + , dwStyle + , dwExStyle + , _T("") + ); + } + + RectTop.sizeMax(RectTop,RectIconMain); +// _AlignDLU(RectTop); + RectDlgWork.sizeMax(RectDlgWork,RectTop); + } + } + + RectContent =RectTop; + RectContent.left+=RectIconMain.size().cx; + RectContent.left+=m_Metrics.cxLargeIconGap.cx; //content echts von main icon + RectContent.adjust(); + + {// Main Instructions text + RectTextMain=DLURect(); + if(IS(m_cfg.pszMainInstruction) + ){RectTextMain =RectContent; +// _AlignDLU(RectTextMain); + + if( IS(RectIconMain.size().cx) //if we are the frist content start a little under icon top + AND NOT(RectContent.size().cx) + )RectTextMain.top = m_Metrics.cyInstructionsGapTop.n; + RectTextMain.adjust(); + + cxMaxText.n = cxMaxDialog.n - RectTextMain.left + - m_Metrics.sizeDialogPadding.cx; + if(isProbe + )cxMaxText.n = m_Metrics.cxBestMainInstruction.n; + + sizeText = _GetTextSize(m_cfg.pszMainInstruction + ,pstrBuffer + ,MAX_TEXT_LENGTH + ,DT_WORDBREAK | DT_NOPREFIX + ,m_fontTitle + ,cxMaxText + ); + + RectTextMain =sizeText; + + if(NOT(isProbe) + )RectTextMain.right =cxMaxLineReal.n; + RectTextMain.adjust(); + + /*no, we ensure it in the followers + if(RectTextMain.bottom < RectIconMain.bottom //main msg takes at minimum complete con space + )RectTextMain.bottom = RectIconMain.bottom; + *///so: it should represent the real text size +// _AlignDLU(RectTextMain); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX; + dwExStyle = 0; +//RectTextMain.left+=100; + _AddControl(CStatic::GetWndClassName() + ,IDC_TASKDLG_INSTRUCTIONSTEXT + ,RectTextMain + ,dwStyle + ,dwExStyle + ,pstrBuffer); + } + + RectContent.sizeMax(RectContent,RectTextMain); + RectTop .sizeMax(RectTop ,RectContent); + RectDlgWork .sizeMax(RectDlgWork ,RectTop); + } + } + + {// Content text + RectTextSub=DLURect(); + if(IS(m_cfg.pszContent) + ){RectTextSub =RectContent; + RectTextSub.top=RectContent.bottom; + RectTextSub.adjust(); + + if( IS(RectIconMain.size().cx) //if we are the frist content start a little under icon top + AND NOT(RectContent.size().cx) + )RectTextSub.top = m_Metrics.cyInstructionsGapTop.n; + RectTextSub.adjust(); + + bool gapAvail =m_Metrics.cyContentGap.n + < (RectTextMain.size().cy -sizeText.cy); + if( NOT(gapAvail) + AND IS(RectIconMain.size().cx) //separate main text from sub text if they touch + AND IS(RectContent.size().cx) + AND(RectContent.bottom >= RectIconMain.bottom) + )RectTextSub.top+=m_Metrics.cyContentGap.n; + RectTextSub.adjust(); + + cxMaxText.n = cxMaxDialog.n - RectTextSub.left + - m_Metrics.sizeDialogPadding.cx; + if(isProbe + )cxMaxText.n = m_Metrics.cxBestContent.n; + + sizeText = _GetTextSizeHREF( m_cfg.pszContent + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK | DT_NOPREFIX + , m_fontText + , cxMaxText + ); + + RectTextSub =sizeText; + + if(NOT(isProbe) + )RectTextSub.right =cxMaxLineReal.n; + RectTextSub.adjust(); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX; + dwExStyle = 0; + LPCTSTR pstrClassName = bIsCommCtrl6 ? CStatic/*CLinkCtrl*/::GetWndClassName() + : CStatic::GetWndClassName(); + if(NOT(bIsCommCtrl6) + )_RemoveHREF(pstrBuffer); +//RectTextSub.left+=100; + _AddControl( pstrClassName + , IDC_TASKDLG_CONTENTTEXT + , RectTextSub + , dwStyle + , dwExStyle + , pstrBuffer + ); + } + + RectContent.sizeMax(RectContent,RectTextSub); + RectContent.bottom+=m_Metrics.cyContentGap.n; + RectContent.adjust(); + RectTop .sizeMax(RectTop ,RectContent); + RectDlgWork .sizeMax(RectDlgWork ,RectTop); + } + } + + + {// Expando in Content area + RectExpoInside = DLURect(); + if( IS(m_cfg.pszExpandedInformation) + AND NOT(TDF_EXPAND_FOOTER_AREA & m_cfg.dwFlags) + ){RectExpoInside =RectContent; + RectExpoInside.top=RectContent.bottom; + RectExpoInside.adjust(); + + if( IS(RectIconMain.size().cx) //if we are the frist content start a little under icon top + AND NOT(RectContent.size().cx) + )RectExpoInside.top = m_Metrics.cyInstructionsGapTop.n; + RectExpoInside.adjust(); + + if( IS(RectIconMain.size().cx) //separate it from sub text if they touch + AND IS(RectContent.size().cx) + AND(RectContent.bottom >= RectIconMain.bottom) + )RectExpoInside.top+=2*m_Metrics.cyContentGap.n; + RectExpoInside.adjust(); + + cxMaxText.n = cxMaxDialog.n- RectExpoInside.left + - m_Metrics.sizeDialogPadding.cx; + if(isProbe + )cxMaxText.n = m_Metrics.cxBestContent.n; + + sizeText = _GetTextSizeHREF( m_cfg.pszExpandedInformation + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK | DT_NOPREFIX + , m_fontText + , cxMaxText + ); + RectExpoInside =sizeText; + + if(NOT(isProbe) + )RectExpoInside.right =cxMaxLineReal.n; + RectExpoInside.adjust(); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX; + dwExStyle = 0; + LPCTSTR pstrClassName = bIsCommCtrl6 ? CLinkCtrl::GetWndClassName() + : CStatic::GetWndClassName(); + if(NOT(bIsCommCtrl6) + )_RemoveHREF(pstrBuffer); + + _AddControl(pstrClassName + , IDC_TASKDLG_EXTRATEXT + , RectExpoInside, dwStyle, dwExStyle, pstrBuffer); + } + + RectContent.sizeMax(RectContent,RectExpoInside); //inside must reduced from drawtop background if not to show + RectTop .sizeMax(RectTop ,RectContent); + RectDlgWork .sizeMax(RectDlgWork ,RectTop); + } + } + + {// Progress Bar + RectProgress =DLURect(); + if(IS((TDF_SHOW_PROGRESS_BAR + |TDF_SHOW_MARQUEE_PROGRESS_BAR) & m_cfg.dwFlags) + ){RectProgress =RectContent; + RectProgress.top=RectContent.bottom; + + RectProgress.top = max(RectProgress.top //no prgress in icon line + ,RectIconMain.bottom); + RectProgress.top+=m_Metrics.cyContentGap.n; //progress allways needs the gap, at least from the icon + RectProgress.adjust(); + + cxMaxText.n = max(RectContent.size().cy + ,m_Metrics.cxBestProgressBar.n); + if(NOT(isProbe) + )cxMaxText.n = RectDlgWork.right - RectContent.left;//footer or expanderoutside must be sized !! + + RectProgress =DLUSize(cxMaxText.n,m_Metrics.cyProgressBar.n); +// _AlignDLU(RectProgress); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | PBS_SMOOTH; + dwExStyle = 0; + + _AddControl(CProgressBarCtrl::GetWndClassName(), IDC_TASKDLG_PROGRESSBAR, RectProgress, dwStyle, dwExStyle, pstrBuffer); + } + + RectContent.sizeMax(RectContent,RectProgress); + RectContent.bottom+= m_Metrics.cyContentGap.n; //progress allways needs the gap, at least from the icon + RectContent.adjust(); + RectTop .sizeMax(RectTop ,RectContent); + RectDlgWork .sizeMax(RectDlgWork ,RectTop); + } + } + + + {// Radio buttons + RectRadio =DLURect(); + if(m_cfg.cRadioButtons > 0 + ){RectRadio =RectContent; + RectRadio .top =RectContent.bottom; + + RectRadio.top = max(RectRadio.top //no radio in icon line + ,RectIconMain.bottom); + RectRadio.adjust(); + + if(IS(RectContent.size().cx) + )RectRadio.top+=m_Metrics.cyContentGap.n; + if( IS(RectExpoInside.size().cy) //separate it from sub text if they touch + AND NOT(RectProgress.size().cy) + )RectRadio.top+= m_Metrics.cyContentGap.n; + + RectRadio.left += m_Metrics.cxRadioIndent.n; + RectRadio.adjust(); + + for(n = 0; n < m_cfg.cRadioButtons; n++ + ){ + cxMaxText.n = cxMaxDialog.n - RectRadio.left + - m_Metrics.sizeDialogPadding.cx + - m_Metrics.sizeRadioButton.cx; + if(isProbe + )cxMaxText.n = m_Metrics.cxBestRadioButton.n; + + sizeText = _GetTextSize( m_cfg.pRadioButtons[n].pszButtonText + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK + , m_fontText + , cxMaxText + ); + sizeText.cx += m_Metrics.sizeRadioButton.cx; + if( sizeText.cy < m_Metrics.sizeRadioButton.cy + ) sizeText.cy = m_Metrics.sizeRadioButton.cy; + + DLURect RectOneRadio =RectRadio; + RectOneRadio.top =RectOneRadio.bottom; + if(IS(RectRadio.size().cy) + )RectOneRadio.top+=m_Metrics.cyRadioGap.n; + RectOneRadio=sizeText; + + if(NOT(isProbe) + )RectOneRadio.right =cxMaxLineReal.n; + RectOneRadio.adjust(); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTORADIOBUTTON | BS_TOP | BS_MULTILINE; + dwExStyle = 0; + if(n == 0) dwStyle |= WS_GROUP; + + _AddControl( CButton::GetWndClassName() + , (WORD) (IDC_TASKDLG_RADIOBUTTON_FIRST + n) + , RectOneRadio + , dwStyle + , dwExStyle + , pstrBuffer + ); + } + + RectRadio.sizeMax(RectRadio,RectOneRadio); + RectContent.sizeMax(RectContent,RectRadio); + RectTop .sizeMax(RectTop ,RectContent); + RectDlgWork .sizeMax(RectDlgWork ,RectTop); + } + } + } + + {// Command Links + RectCommand =DLURect(); + m_bHasCustomLinks = false; + if( (m_cfg.cButtons > 0) + AND IS((TDF_USE_COMMAND_LINKS + |TDF_USE_COMMAND_LINKS_NO_ICON) & m_cfg.dwFlags + ) + ){ + //if(NOT(elementsAdded)) ypos -= m_Metrics.sizeDialogPadding.cy/2; + RectCommand =RectContent; + RectCommand .top=RectContent.bottom; + + if( IS((DLUSize()=RectIconMain).cx) + AND NOT(RectContent.size().cx) + )RectCommand.top += m_Metrics.cyInstructionsGapTop.n; //start a little under icon top + RectCommand.adjust(); + + if(IS(RectRadio.size().cx) + )RectCommand.top += m_Metrics.cyContentGap.n; + RectCommand.adjust(); + + for( n = 0; n < m_cfg.cButtons; n++ + ){ + DLURect rectCommandBtn=RectCommand; + rectCommandBtn.top=RectCommand.bottom; + rectCommandBtn.adjust(); + + _LoadString(m_cfg.pButtons[n].pszButtonText, pstrBuffer, MAX_TEXT_LENGTH); + + LPCTSTR pstrTitle = NULL; + LPCTSTR pstrText = NULL; + SIZE_T cchTitle = 0; + SIZE_T cchText = 0; + + _SplitCommandText(pstrBuffer, pstrTitle, cchTitle, pstrText, cchText); + DLUSize cxPadding;cxPadding = (m_Metrics.sizeLinkPadding * 2); + + if((m_cfg.dwFlags & TDF_USE_COMMAND_LINKS_NO_ICON) == 0 + )cxPadding += m_Metrics.cxyArrowIcon + m_Metrics.cxSmallIconGap; + + cxMaxText.n = cxMaxDialog.n - RectCommand.left - m_Metrics.sizeDialogPadding.cx - cxPadding.cx; + if(cxMaxDialog.n == WIDTH_PROBE + )cxMaxText.n = m_Metrics.cxBestCommandLink.n - cxPadding.cx; + + sizeTitle =PixSize()= _GetTextSize(pstrTitle, cchTitle, DT_WORDBREAK, m_fontTitle, cxMaxText); + DLUSize sizeSub;sizeSub =PixSize()= _GetTextSize(pstrText, cchText, DT_NOPREFIX | DT_WORDBREAK, m_fontText, cxMaxText); + DLUSize sizeText; + sizeText.cx=max(sizeTitle.cx,sizeSub.cx); + sizeText.cy=sizeTitle.cy +sizeSub.cy; + + if(IS(sizeText.cx)) sizeText.cx += cxPadding.cx; + if(sizeText.cx < m_Metrics.cxMinCommandLink.n + )sizeText.cx = m_Metrics.cxMinCommandLink.n; + + rectCommandBtn =sizeText; + + if(NOT(isProbe) + )rectCommandBtn.right =cxMaxLineReal.n; + rectCommandBtn.adjust(); + + rectCommandBtn.bottom+=(m_Metrics.sizeLinkPadding.cy * 4); + rectCommandBtn.adjust(); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CENTER|BS_VCENTER/*BS_TOP*/ | BS_MULTILINE; + dwExStyle = 0; + if(n == 0 + )dwStyle |= WS_GROUP; + + if(bIsVista AND bIsCommCtrl6 + ) { + if(m_cfg.pButtons[n].nButtonID == m_cfg.nDefaultButton + ) { + dwStyle |= BS_DEFCOMMANDLINK; + m_nDefCtlId = (UINT) -1; + } + else{ + dwStyle |= BS_COMMANDLINK;//??dwStyle |= BS_OWNERDRAW; + } + } + else{m_bHasCustomLinks = true; + + if(m_cfg.pButtons[n].nButtonID == m_cfg.nDefaultButton + )m_nDefCtlId = IDC_TASKDLG_CUSTOMBUTTON_FIRST + n; + + dwStyle |= BS_OWNERDRAW; + } + + _AddControl(CButton::GetWndClassName() + , (WORD) (IDC_TASKDLG_CUSTOMBUTTON_FIRST + n) + , rectCommandBtn + , dwStyle, dwExStyle + , pstrBuffer); + } + RectCommand.sizeMax(RectCommand,rectCommandBtn); + //RectCommand.bottom +=m_Metrics.cyButtonLineGap.n; + RectContent.sizeMax(RectContent,RectCommand); + RectTop .sizeMax(RectTop ,RectContent); + RectDlgWork .sizeMax(RectDlgWork ,RectTop); + } + } + } + + RectDlgWork.top +=m_Metrics.cyContentGap.n; + RectDlgWork.adjust(); + + RectBottom=RectDlgWork; + RectBottom.top =RectTop.bottom; + RectBottom.adjust(); + + RectBottomContent =RectBottom; + RectBottomContent.right =RectBottomContent.left; + //RectBottomContent.left =RectContent.left; + RectBottomContent.top +=m_Metrics.cyButtonLineGap.n; + RectBottomContent.adjust(); + + if(false AND createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE |WS_EX_CLIENTEDGE | BS_PUSHBUTTON |BS_GROUPBOX | SS_CENTER | SS_NOPREFIX; + dwExStyle = 0; + DLURect rcDivider =RectBottom; + rcDivider.bottom+=1; + _AddControl(CStatic::GetWndClassName() + ,IDC_TASKDLG_FOOTERDIVIDER, rcDivider , dwStyle, dwExStyle, _T("")); + } + + RectButtonRow=RectBottomContent; + RectExpoRow =RectButtonRow; + + {// Expander area + if(IS(m_cfg.pszExpandedInformation) + ){ + RectExpoBtn =RectExpoRow; + if(ShowExpanderIcon + )RectExpoBtn =(DLUSize()=m_Metrics.cxyExpanderIcon); +// _AlignDLU(RectExpoBtn); + + if(createControls AND ShowExpanderIcon + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_OWNERDRAW | SS_NOTIFY |WS_EX_TRANSPARENT; + dwExStyle = 0; + _AddControl(CStatic::GetWndClassName() + ,IDC_TASKDLG_EXPANDERICON, RectExpoBtn, dwStyle, dwExStyle + ,_T("") + ); + } + RectExpoRow.sizeMax(RectExpoRow,RectExpoBtn); + + xDlu xoffset; + if(ShowExpanderIcon + ) xoffset.n = m_Metrics.cxyExpanderIcon.cx + m_Metrics.cxSmallIconGap.cx; + + sizeTemp = _GetTextSize( m_cfg.pszCollapsedControlText + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK + , m_fontText + , m_Metrics.cxMaxVerification + ); + sizeText = _GetTextSize( m_cfg.pszExpandedControlText + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK + , m_fontText + , m_Metrics.cxMaxVerification + ); + if(sizeTemp.cx > sizeText.cx) sizeText.cx = sizeTemp.cx; + if(sizeTemp.cy > sizeText.cy) sizeText.cy = sizeTemp.cy; + + sizeText.cx += xoffset.n; + + RectExpoText =RectExpoBtn; + RectExpoText.left +=xoffset.n; + RectExpoText =sizeText; + //_AlignDLU(RectExpoText.bottom,HTBOTTOM); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX | SS_NOTIFY; + dwExStyle = 0; + _AddControl(CStatic::GetWndClassName(), IDC_TASKDLG_EXPANDERTEXT, RectExpoText, dwStyle, dwExStyle, pstrBuffer); + } + + RectExpoRow .sizeMax(RectExpoRow,RectExpoBtn); + RectExpoRow .sizeMax(RectExpoRow,RectExpoText); + + RectButtonRow .sizeMax(RectButtonRow,RectExpoRow); + RectBottomContent .sizeMax(RectBottomContent,RectButtonRow); + RectBottom .sizeMax(RectBottom,RectBottomContent); + RectDlgWork .sizeMax(RectDlgWork ,RectBottom); + } + } + + {// Verification text + RectCheck =DLURect(); + if(IS(m_cfg.pszVerificationText) + ){ + RectCheck =RectButtonRow; + RectCheck.top =RectButtonRow.bottom; + if(IS(RectExpoRow.size().cy) + )RectCheck.top+=m_Metrics.cyContentGap.n; + RectCheck.adjust(); + + sizeText = _GetTextSize( m_cfg.pszVerificationText + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK + , m_fontText + , m_Metrics.cxMaxVerification + ); + const LONG cxIndent = 2; + RectCheck.left+=cxIndent; + RectCheck=sizeText; + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX | BS_TOP | BS_LEFT | BS_MULTILINE; + dwExStyle = 0; + _AddControl(CButton::GetWndClassName(), IDC_TASKDLG_VERIFYBUTTON, RectCheck, dwStyle, dwExStyle, pstrBuffer); + } + + RectButtonRow .sizeMax(RectButtonRow,RectCheck); + RectBottomContent .sizeMax(RectBottomContent,RectButtonRow); + RectBottom .sizeMax(RectBottom,RectBottomContent); + RectDlgWork .sizeMax(RectDlgWork ,RectBottom); + } + } + + + {// Buttons: mutateable + RectBtns =RectButtonRow; + RectBtns.left=RectButtonRow.right; + RectButtonRow.adjust(); + + if(IS(RectButtonRow.size().cx)) RectBtns.left +=m_Metrics.cxMinButton.n+(m_Metrics.sizeButtonPadding.cx * 2); + else RectBtns.left =RectContent.left;//2*m_Metrics.cxButtonsIndent.n; + RectBtns.adjust(); + + if( (m_cfg.cButtons > 0) + AND NOT((TDF_USE_COMMAND_LINKS + |TDF_USE_COMMAND_LINKS_NO_ICON) & m_cfg.dwFlags) + ){ + for(n = 0; n < m_cfg.cButtons; n++ + ){ + sizeText = _GetTextSize( m_cfg.pButtons[n].pszButtonText + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK + , m_fontText + , xDlu(9999) + ); + if(sizeText.cx < m_Metrics.cxMinButton.n + )sizeText.cx = m_Metrics.cxMinButton.n; + + DLURect rcButton =RectBtns; + rcButton.left =RectBtns.right; + rcButton.bottom=RectBtns.top; + rcButton.adjust(); + + rcButton =DLUSize(sizeText.cx + (m_Metrics.sizeButtonPadding.cx * 2) + ,sizeText.cy + (m_Metrics.sizeButtonPadding.cy * 2)); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_MULTILINE; + dwExStyle = 0; + + _AddControl( CButton::GetWndClassName() + , (WORD) (IDC_TASKDLG_CUSTOMBUTTON_FIRST + n) + , rcButton + , dwStyle, dwExStyle + , pstrBuffer); + } + + RectBtns.sizeMax(RectBtns,rcButton); + RectBtns.right+= m_Metrics.cxButtonGap.n; + RectBtns.adjust(); + + if(NOT(m_nDefCtlId) + )m_nDefCtlId = IDC_TASKDLG_CUSTOMBUTTON_FIRST + n; + + if(m_cfg.nDefaultButton == m_cfg.pButtons[n].nButtonID + )m_nDefCtlId = IDC_TASKDLG_CUSTOMBUTTON_FIRST + n; + } + } + } + + {// Buttons: none mutateable + if(m_cfg.SzPushButtons > 0 + ){ + for(n = 0; n < m_cfg.SzPushButtons; n++ + ){ + sizeText = _GetTextSize( m_cfg.PushButtons[n].pszButtonText + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK + , m_fontText + , xDlu(9999) + ); + if(sizeText.cx < m_Metrics.cxMinButton.n + )sizeText.cx = m_Metrics.cxMinButton.n; + + DLURect rcButton =RectBtns; + rcButton.left =RectBtns.right; + rcButton.bottom=RectBtns.top; + rcButton.adjust(); + + rcButton =DLUSize(sizeText.cx + (m_Metrics.sizeButtonPadding.cx * 2) + ,sizeText.cy + (m_Metrics.sizeButtonPadding.cy * 2)); +// _AlignDLU(rcButton); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_MULTILINE; + dwExStyle = 0; + _AddControl( CButton::GetWndClassName() + , (WORD) (IDC_TASKDLG_CUSTOMBUTTON_FIRST + n +m_cfg.cButtons) + , rcButton + , dwStyle, dwExStyle + , pstrBuffer); + } + RectBtns.sizeMax(RectBtns,rcButton); + RectBtns.right+= m_Metrics.cxButtonGap.n; + RectBtns.adjust(); + + if(NOT(m_nDefCtlId) + )m_nDefCtlId = IDC_TASKDLG_CUSTOMBUTTON_FIRST + n +m_cfg.cButtons; + + if(m_cfg.nDefaultButton == m_cfg.PushButtons[n].nButtonID + )m_nDefCtlId = IDC_TASKDLG_CUSTOMBUTTON_FIRST + n +m_cfg.cButtons; + } + } + + + // common buttons + if(IS(m_cfg.dwCommonButtons) + ){ + + int commonButtonsSupported[] ={TDCBF_OK_BUTTON ,IDOK ,IDS_TASKDLG_OK + ,TDCBF_YES_BUTTON ,IDYES ,IDS_TASKDLG_YES + ,TDCBF_NO_BUTTON ,IDNO ,IDS_TASKDLG_NO + ,TDCBF_RETRY_BUTTON ,IDRETRY ,IDS_TASKDLG_RETRY + ,TDCBF_CANCEL_BUTTON ,IDCANCEL ,IDS_TASKDLG_CANCEL + ,TDCBF_CLOSE_BUTTON ,IDCLOSE ,IDS_TASKDLG_CLOSE + }; + const UINT szCommonButtonsSupported =sizeof(commonButtonsSupported) + /sizeof(commonButtonsSupported[0]); + for(n = 0 + ;n < szCommonButtonsSupported + ;n += 3 + ){ + if( NOT(m_cfg.dwCommonButtons & commonButtonsSupported[n]) + ) continue; + + DLUSize sizeText;sizeText=PixSize() = _GetTextSize( makeIntResourceW(commonButtonsSupported[n + 2]) + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK + , m_fontText + , xDlu(9999) + ); + if(sizeText.cx < m_Metrics.cxMinButton.n + )sizeText.cx = m_Metrics.cxMinButton.n; + + DLURect rcButton =RectBtns; + rcButton.left =RectBtns.right; + rcButton.bottom=RectBtns.top; + rcButton.adjust(); + + rcButton =DLUSize(sizeText.cx + (m_Metrics.sizeButtonPadding.cx * 2) + ,sizeText.cy + (m_Metrics.sizeButtonPadding.cy * 2)); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_MULTILINE; + dwExStyle = 0; + _AddControl( CButton::GetWndClassName() + , (WORD) commonButtonsSupported[n + 1] + , rcButton + , dwStyle + , dwExStyle + , pstrBuffer + ); + } + + RectBtns.sizeMax(RectBtns,rcButton); + RectBtns.right+= m_Metrics.cxButtonGap.n; + RectBtns.adjust(); + + if(NOT(m_nDefCtlId) + )m_nDefCtlId = (UINT) commonButtonsSupported[n + 1]; + + if(m_cfg.nDefaultButton == commonButtonsSupported[n + 1] + )m_nDefCtlId = (UINT) commonButtonsSupported[n + 1]; + } + } + }//END: Buttons: none mutateable, END: all push buttons + + + //RectButtonRow=RectExpoRow; + RectButtonRow.sizeMax(RectButtonRow,RectBtns); + + RectBottomContent .sizeMax(RectBottomContent,RectButtonRow); + RectBottom .sizeMax(RectBottom,RectBottomContent); + RectDlgWork .sizeMax(RectDlgWork ,RectBottom); + + {// Footer text + RectFooter =RectButtonRow; + RectFooter.top =RectButtonRow.bottom; + RectFooter.adjust(); + + if(IS(m_cfg.pszFooter) + ){if(IS(RectButtonRow.size().cy) + )RectFooter.top+=m_Metrics.cyButtonLineGap.n; + RectFooter.adjust(); + + RectIconFooter =RectFooter; + + if( IS(m_cfg.pszFooterIcon) + OR IS(TDF_USE_HICON_FOOTER & m_cfg.dwFlags) + ){ + RectIconFooter=DLUSize()=m_Metrics.cxySmallIcon; + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_OWNERDRAW |WS_EX_TRANSPARENT; + dwExStyle = 0; + _AddControl(CStatic::GetWndClassName() + ,IDC_TASKDLG_FOOTERICON, RectIconFooter, dwStyle, dwExStyle + , _T("")); + } + + RectFooterText =RectIconFooter; + RectFooterText.left=RectIconFooter.right; + RectFooterText.left+=m_Metrics.cxSmallIconGap.cx; + RectFooterText.adjust(); + } + + cxMaxText.n = cxMaxDialog.n - RectFooterText.left - m_Metrics.sizeDialogPadding.cx; + + if(isProbe + )cxMaxText = m_Metrics.cxBestContent; + + sizeText = _GetTextSizeHREF( m_cfg.pszFooter + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK | DT_NOPREFIX + , m_fontText + , cxMaxText + ); + if(sizeText.cy < m_Metrics.cxySmallIcon.cy + )sizeText.cy = m_Metrics.cxySmallIcon.cy; + + RectFooterText=sizeText; + if(NOT(isProbe) + )RectFooterText.right =cxMaxLineReal.n; + RectFooterText.adjust(); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX; + dwExStyle = 0; + LPCTSTR pstrClassName = bIsCommCtrl6 ? CLinkCtrl::GetWndClassName() + : CStatic::GetWndClassName(); + if(NOT(bIsCommCtrl6) + )_RemoveHREF(pstrBuffer); + + _AddControl(pstrClassName, IDC_TASKDLG_FOOTERTEXT, RectFooterText, dwStyle, dwExStyle, pstrBuffer); + } + } + RectFooter .sizeMax(RectFooter,RectIconFooter); + RectFooter .sizeMax(RectFooter,RectFooterText); +// _AlignDLU(RectFooter); + + RectBottomContent .sizeMax(RectBottomContent,RectFooter); + RectBottom .sizeMax(RectBottom,RectBottomContent); + RectDlgWork .sizeMax(RectDlgWork ,RectBottom); + } + + {// Expando in Footer area + RectExpoOutside =RectFooter; + RectExpoOutside.top=RectFooter.bottom; + RectExpoOutside.adjust(); + + if( IS(m_cfg.pszExpandedInformation) + AND IS(TDF_EXPAND_FOOTER_AREA & m_cfg.dwFlags) + ){ + RectExpoOutside.top+=m_Metrics.cyContentGap.n; + RectExpoOutside.adjust(); + + RectExpoOutsideText=RectExpoOutside; + + cxMaxText.n = cxMaxDialog.n - RectExpoOutsideText.left + - m_Metrics.sizeDialogPadding.cx; + if(isProbe + )cxMaxText = m_Metrics.cxBestContent; + + sizeText = _GetTextSizeHREF( m_cfg.pszExpandedInformation + , pstrBuffer + , MAX_TEXT_LENGTH + , DT_WORDBREAK | DT_NOPREFIX + , m_fontText + , cxMaxText + ); + RectExpoOutsideText=sizeText; + + if(NOT(isProbe) + )RectExpoOutsideText.right =cxMaxLineReal.n; + RectExpoOutsideText.adjust(); + + if(createControls + ){ + dwStyle = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX; + dwExStyle = 0; + LPCTSTR pstrClassName = bIsCommCtrl6 ? CLinkCtrl::GetWndClassName() + : CStatic::GetWndClassName(); + if(NOT(bIsCommCtrl6) + )_RemoveHREF(pstrBuffer); + + _AddControl( pstrClassName + , IDC_TASKDLG_EXTRATEXT + , RectExpoOutsideText, dwStyle, dwExStyle + , pstrBuffer); + } + } + } + + RectExpoOutside.sizeMax(RectExpoOutside,RectExpoOutsideText); + //RectFooter.sizeMax(RectFooter,RectExpoOutside); + RectBottomContent .sizeMax(RectBottomContent,RectExpoOutside); + RectBottom .sizeMax(RectBottom,RectBottomContent); + RectDlgWork .sizeMax(RectDlgWork ,RectBottom); + + RectDlg .sizeMax(RectDlg ,RectDlgWork); + RectDlg =RectDlg.size() +m_Metrics.sizeDialogPadding; + + free(pstrBuffer); + + return RectDlg.size(); + } + + void _CustomDrawIcon(LPDRAWITEMSTRUCT lpDIS, COLORREF clrBack, HICON hIcon, DLUSize cxyIcon) + {CDCHandle dc = lpDIS->hDC; + PixRect rc = lpDIS->rcItem; + //_AlignDLU(rc); + + dc.FillSolidRect(&rc, clrBack); + + PixSize szp;szp=cxyIcon; + dc.DrawIconEx (rc.left, rc.top, hIcon, szp.cx, szp.cy); + } + + void _CustomDrawCommandLink(LPDRAWITEMSTRUCT lpDIS) + { + m_Metrics.reInitColors(); + + CButton ctrl = lpDIS->hwndItem; + CDCHandle dc = lpDIS->hDC; + PixRect rcPix = lpDIS->rcItem; + HBRUSH hOldBrush = dc.GetCurrentBrush(); + HFONT hOldFont = dc.GetCurrentFont(); + HPEN hOldPen = dc.GetCurrentPen(); + + if(lpDIS->CtlID == m_nHoverId + ) { + dc.DrawFrameControl(&rcPix, DFC_BUTTON, DFCS_BUTTONPUSH); + + PixRect rcInteriour = rcPix; + ::InflateRect(&rcInteriour, -2, -2); + + dc.FillSolidRect(&rcInteriour, m_Metrics.clrBkCommandSelect); + } + else if( IS(ODA_DRAWENTIRE & lpDIS->itemAction) + ) { + dc.FillSolidRect(&rcPix, m_Metrics.clrBkTop); + } + + COLORREF clrBorder = CLR_INVALID; + if( m_nDefCtlId == lpDIS->CtlID + ) clrBorder = m_Metrics.clrCmdLinkSelect; + + if( IS(ODS_SELECTED & lpDIS->itemState) + ) clrBorder = ::GetSysColor(COLOR_3DSHADOW); + + if(NOT(CLR_INVALID == clrBorder) + ){ + CPen penBorder; + penBorder.CreatePen(PS_SOLID, 1, clrBorder); + + dc.SelectPen (penBorder); + dc.SelectBrush((HBRUSH) ::GetStockObject(HOLLOW_BRUSH)); + + PixPoint ptArc( 6, 6 ); + dc.RoundRect(&rcPix, ptArc); + } + + ::InflateRect(&rcPix, -m_Metrics.sizeLinkPadding.pix().cx, -m_Metrics.sizeLinkPadding.pix().cy); + xPix cxPix = xPix((rcPix.right - (rcPix.left + m_Metrics.cxyArrowIcon.pix().cx + m_Metrics.cxSmallIconGap.pix().cx))); + + TCHAR szWindowText[300] = { 0 }; + ctrl.GetWindowText(szWindowText, sizeof(szWindowText) / sizeof(TCHAR)); + + LPCTSTR pstrTitle = NULL; + LPCTSTR pstrText = NULL; + SIZE_T cchTitle = 0;//strlen + SIZE_T cchText = 0;//strlen + + _SplitCommandText(szWindowText, pstrTitle, cchTitle, pstrText, cchText); + + DLUSize sizeTitleDlu = _GetTextSize(pstrTitle, cchTitle, DT_WORDBREAK, m_fontTitle, xDlu()=cxPix); + DLUSize sizeTextDlu = _GetTextSize(pstrText , cchTitle, DT_WORDBREAK, m_fontTitle, xDlu()=cxPix); + + {// vert center in command + yPix szRcYPix;szRcYPix =yPix(rcPix.bottom -rcPix.top); AE_(szRcYPix.n < sizeTitleDlu.cy +sizeTextDlu.cy + 1); + yPix topOffsetPix; + if(szRcYPix.n > sizeTitleDlu.pix().cy+sizeTextDlu.pix().cy+ yDlu(1).pix().n + ){topOffsetPix.n =(szRcYPix.n -(sizeTitleDlu.pix().cy +sizeTextDlu.pix().cy + yDlu(1).pix().n))/2; + } + rcPix.top+=topOffsetPix.n; //center + } + + if(NOT(TDF_USE_COMMAND_LINKS_NO_ICON & m_cfg.dwFlags) + ){ + dc.DrawIconEx( rcPix.left, rcPix.top + 2 + , lpDIS->CtlID == m_nHoverId ? m_iconArrowHot + : m_iconArrowNormal + , 20, 20); + rcPix.left += m_Metrics.cxyArrowIcon.pix().cx + m_Metrics.cxSmallIconGap.pix().cx; + } + + + dc.SetTextColor((lpDIS->CtlID == m_nHoverId + ) ?m_Metrics.clrCommandLinkTextSelected + :m_Metrics.clrCommandLinkText); + dc.SetBkMode (TRANSPARENT); + dc.SelectFont (m_fontTitle); + + PixRect rcTitle( rcPix.left, rcPix.top, rcPix.right, rcPix.bottom ); + + dc.DrawText(pstrTitle, (int)cchTitle, &rcTitle, DT_WORDBREAK); + + PixRect rcText( rcPix.left, rcPix.top + sizeTitleDlu.pix().cy + yDlu(1).pix().n + , rcPix.right,rcPix.bottom ); + dc.SelectFont(m_fontText); + dc.DrawText (pstrText, (int)cchText, &rcText, DT_NOPREFIX | DT_WORDBREAK); + + dc.SelectPen (hOldPen); + dc.SelectFont (hOldFont); + dc.SelectBrush(hOldBrush); + } + + + void _CustomDrawDivider(LPDRAWITEMSTRUCT lpDIS) + { + m_Metrics.reInitColors(); + + CButton ctrl = lpDIS->hwndItem; + CDCHandle dc = lpDIS->hDC; + PixRect rc = lpDIS->rcItem; + rc.bottom-=10; + //rc.bottom=rc.top+10; + + dc.FillSolidRect(&rc, m_Metrics.clrDividerLight); + } + + void _PlaySound() {if(TD_ERROR_ICON == m_cfg.pszMainIcon) ::MessageBeep(MB_ICONHAND); + if(TD_WARNING_ICON == m_cfg.pszMainIcon) ::MessageBeep(MB_ICONEXCLAMATION); + if(TD_INFORMATION_ICON == m_cfg.pszMainIcon) ::MessageBeep(MB_ICONASTERISK); + } + + void _RemoveHREF(LPTSTR pstr) const + { + if(NOT(TDF_ENABLE_HYPERLINKS & m_cfg.dwFlags)) return; + + LPTSTR p = pstr; + while(*p != '\0' + ){ + if(*p == '<' + ) {LOGG(_T("W_ W_ W_ Will remove hyperlinks from TaskDialogEmu; no support on this platform")); + + while( (*p != '\0') + AND(*p != '>' ) + ) p = ::CharNext(p); + + if(*p == '>') p = ::CharNext(p); + } + else{*pstr = *p; + + #ifdef _MBCS + if(::IsDBCSLeadByte(*p) + ) pstr[1] = p[1]; + #endif // _MBCS + + p = ::CharNext(p); + pstr = ::CharNext(pstr); + } + } + *pstr = '\0'; + } + + DLURect _CenterDialog(DLUSize dluDialog) const + { + PixRect pixArea; + if( ::IsWindow(m_cfg.hwndParent) + AND IS(TDF_POSITION_RELATIVE_TO_WINDOW & m_cfg.dwFlags) + ) ::GetWindowRect (m_cfg.hwndParent, &pixArea); + else ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &pixArea, NULL); + + //pixArea = MapDialogPixels(pixArea); + DLURect dluArea;dluArea= pixArea; + DLURect rc; + rc.left = dluArea.left +((dluArea.right - dluArea.left)/ 2 - dluDialog.cx / 2); + rc.top = dluArea.top +((dluArea.bottom - dluArea.top) / 2 - dluDialog.cy / 2); + rc.right = rc.left + dluDialog.cx; + rc.bottom = rc.top + dluDialog.cy; + return rc; + } + + HRESULT _DoCallback(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0) + { + if(NOT(m_bCreated)) return S_OK; + if(NOT(m_cfg.pfCallback)) return S_OK; + + return m_cfg.pfCallback(m_hWnd, uMsg, wParam, lParam, m_cfg.lpCallbackData); + } + + void _DoExpandCollapse() + { + /*if(NOT(TDF_EXPAND_FOOTER_AREA & m_cfg.dwFlags) + ) { + CWindow wndText = GetDlgItem(IDC_TASKDLG_EXTRATEXT); + PixRect rcText; + wndText.GetWindowRect(&rcText); + + yDlu cy = yDlu( (DLUSize()=rcText.size()).cy + + m_Metrics.cyButtonLineGap.n); + if(NOT(m_bExpanded) + ) cy.n = -cy.n; + + HWND hWndFirst=NULL; + CWindow wndChild = hWndFirst = GetWindow(GW_CHILD); + + while(IS(wndChild) + ){ + PixRect rcWin; + wndChild.GetWindowRect(&rcWin); + + if( (wndChild != wndText) + AND(rcWin.top >= rcText.top) + ){ + ::OffsetRect (&rcWin, 0, cy.pix().n); + ::MapWindowPoints (HWND_DESKTOP, m_hWnd, (LPPOINT) &rcWin, 2); + + wndChild.MoveWindow(&rcWin); + } + wndChild = wndChild.GetWindow(GW_HWNDNEXT); + if(wndChild == hWndFirst + )break; + } + + wndText.ShowWindow(m_bExpanded ? SW_SHOWNOACTIVATE: SW_HIDE); + + ResizeClient(-1, m_bExpanded ? m_sizeDialog.pixY().n + : m_sizeDialog.pixY().n + +cy.pix().n); + } + else*/ResizeClient(-1, m_bExpanded ? m_sizeDialog.pix().cy + : m_sizeDialog.pix().cy + -RectExpoOutside.size().pix().cy + -m_Metrics.sizeDialogPadding.pix().cy + /*yDlu(RectExpoOutside.top + + 5*m_Metrics.szChar.cy + ).pix().n + */ + ); + + // Change text in Expander label + LPTSTR pstrBuffer = (LPTSTR) malloc(MAX_TEXT_LENGTH * sizeof(TCHAR)); AXE(IS(pstrBuffer) + ,_T("pstrBuffer =malloc; {memory low}") + ,return); + _LoadString(m_bExpanded ? m_cfg.pszExpandedControlText + : m_cfg.pszCollapsedControlText + , pstrBuffer, MAX_TEXT_LENGTH); + + SetDlgItemText(IDC_TASKDLG_EXPANDERTEXT, pstrBuffer); + free(pstrBuffer); + + // Make sure we redraw stuff + CWindow(GetDlgItem(IDC_TASKDLG_EXPANDERICON) + ).Invalidate(); + CWindow(GetDlgItem(IDC_TASKDLG_EXPANDERTEXT) + ).Invalidate(); + + this ->Invalidate(); + } + + void _AddControl(ATL::_U_STRINGorID ClassName, WORD wId, DLURect rc, DWORD dwStyle, DWORD dwExStyle, ATL::_U_STRINGorID Text) + { + PixRect pix;pix=rc; + //RECT dlurc = MapDialogPixels(pix); + m_Template.AddControl(ClassName, wId, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle, Text); + } + + HICON _LoadIcon(LPCWSTR pstr, DLUSize cxy) const + { if(NOT(pstr)) return NULL; + + USES_CONVERSION; + + // Determine icon identifier and resource dll + HINSTANCE hInst = m_cfg.hInstance; + if(pstr == TD_ERROR_ICON + )pstr = (LPWSTR)(IDI_ERROR),hInst =NULL; + + //#if _WIN32_WINNT >= 0x0600 + else if( pstr == TD_SHIELD_ICON + ){pstr = makeIntResourceW(32518)/*makeIntResourceW(IDI_SHIELD)*/, hInst = NULL; + #ifdef IDI_SHIELD + if(!(pstr)){pstr = (LPWSTR)(IDI_SHIELD), hInst = NULL;} + #endif + if(!(pstr)){pstr = makeIntResourceW(32515)/*warning instead than */,hInst = NULL;} + } + //#endif // _WIN_WINNT + else if( pstr == TD_WARNING_ICON ) pstr = (LPWSTR)(IDI_EXCLAMATION), hInst = NULL; + else if( pstr == TD_INFORMATION_ICON ) pstr = (LPWSTR)(IDI_ASTERISK), hInst = NULL; + else if( pstr == makeIntResourceW(IDI_TASKDLG_ARROW_HOT) ) hInst = ModuleHelper::GetResourceInstance(); + else if( pstr == makeIntResourceW(IDI_TASKDLG_ARROW_NORMAL) ) hInst = ModuleHelper::GetResourceInstance(); + else if( pstr == makeIntResourceW(IDI_TASKDLG_CHEVRON_LESS) ) hInst = ModuleHelper::GetResourceInstance(); + else if( pstr == makeIntResourceW(IDI_TASKDLG_CHEVRON_MORE) ) hInst = ModuleHelper::GetResourceInstance(); + + // Load icon... + UINT fuLoad = LR_DEFAULTCOLOR | LR_LOADTRANSPARENT; + if(NOT(hInst) + ) fuLoad |= LR_SHARED; + + LPCTSTR pstrIcon = IS_INTRESOURCE(pstr) ? (LPCTSTR) pstr + : W2CT(pstr); + + PixSize sz;sz=cxy; + HICON hIcon = (HICON) ::LoadImage(hInst, pstrIcon, IMAGE_ICON, sz.cx, sz.cy, fuLoad); + if(NOT(hIcon) + ) hIcon = (HICON) ::LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, sz.cx, sz.cy, LR_DEFAULTCOLOR | LR_SHARED | LR_LOADTRANSPARENT); + + cxy =sz; + return hIcon; + } + + void _LoadString(LPCWSTR pstr, LPTSTR pszBuffer, SIZE_T cchMax) const + { AXE_(IS(pstr) ,return); + AXE_(IS(pszBuffer) ,return); + + ::ZeroMemory(pszBuffer, cchMax * sizeof(TCHAR)); + + USES_CONVERSION; + + if(IS_INTRESOURCE(pstr)) ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(pstr), pszBuffer, (int)cchMax); + else ::lstrcpyn (pszBuffer, W2CT(pstr), (int)cchMax); + } + + void _SplitCommandText(LPTSTR pstrBuffer, LPCTSTR& pstrTitle, SIZE_T& cchTitle, LPCTSTR& pstrText, SIZE_T& cchText) const + { + LPTSTR pstrSel = pstrBuffer; + while( (*pstrSel != '\0') + AND(*pstrSel != '\n') + ) pstrSel = ::CharNext(pstrSel); + + if(*pstrSel == '\0' + ) { + pstrTitle = pstrBuffer; + pstrText = NULL; + cchTitle = lstrlen(pstrTitle); + cchText = 0; + } + else{pstrTitle = pstrBuffer; + pstrText = pstrSel + 1; + cchText = lstrlen(pstrText); + cchTitle = lstrlen(pstrBuffer) - cchText - 1; + } + } + + DLUSize _GetTextSize(LPCWSTR pstr, LPTSTR pszBuffer, SIZE_T cchMax, UINT uStyle, HFONT hFont, xDlu cxMax) const + { + _LoadString(pstr, pszBuffer, cchMax); + return _GetTextSize(pszBuffer, (UINT) -1, uStyle, hFont, cxMax); + } + + DLUSize _GetTextSizeHREF(LPCWSTR pstr, LPTSTR pszBuffer, SIZE_T cchMax, UINT uStyle, HFONT hFont, xDlu cxMax) const + { + _LoadString(pstr, pszBuffer, cchMax); + _RemoveHREF(pszBuffer); + DLUSize sizeText = _GetTextSize(pszBuffer, (UINT) -1, uStyle, hFont, cxMax); + _LoadString(pstr, pszBuffer, cchMax); + return sizeText; + } + + DLUSize _GetTextSize(LPCTSTR pstr, SIZE_T cchMax, UINT uStyle, HFONT hFont, xDlu cxMax) const + { + CClientDC dc = m_cfg.hwndParent; + PixSize sizeText; + + if( pstr == NULL ) return DLUSize(); + if( pstr[0] == '\0' ) return DLUSize(); + + HFONT hOldFont = dc.SelectFont(hFont); + PixRect rc( 0, 0, cxMax.pix().n, 9999 ); + + if( cchMax == MAX_TEXT_LENGTH + ) cchMax = (SIZE_T) -1; + + dc.DrawText (pstr, (int)cchMax, &rc, DT_CALCRECT | uStyle); + dc.SelectFont(hOldFont); + + PixSize size( rc.right - rc.left + 1, rc.bottom - rc.top + 1 ); + DLUSize erg;erg=size; + erg.cy+=erg.cy/3; + return DLUSize()=size; + } + +public: + +}; + + +class CTask98Dialog : public CTask98DialogImpl +{ +}; + + +///////////////////////////////////////////////////////////////////////// +// TaskDialog 98 helpers +// + +HRESULT Task98DialogIndirect(const TASKDIALOGCONFIG* pTaskConfig, int* pnButton, int* pnRadioButton, BOOL* pfVerificationFlagChecked,bool iconExpanderShow=false) +{ AXE_(IS(pTaskConfig) ,return E_INVALIDARG); + AXE_(pTaskConfig->cbSize==sizeof(TASKDIALOGCONFIG) ,return E_INVALIDARG); + + + if(IS(pnButton)) *pnButton = 0; + + CTask98Dialog dlg; + dlg.ShowExpanderIcon =iconExpanderShow; AXE_(IS( + dlg.SetConfig(pTaskConfig)) ,return E_FAIL); + do{dlg.DoModal(pTaskConfig->hwndParent); + }while( dlg.IsNavigated() ); + + dlg.GetDialogResult(pnButton, pnRadioButton, pfVerificationFlagChecked); + return S_OK; +} + +inline HRESULT Task98DialogIndirect(const TASKDIALOGCONFIG_X* pTaskConfig, int* pnButton, int* pnRadioButton, BOOL* pfVerificationFlagChecked,bool iconExpanderShow=false) +{ AXE_(IS(pTaskConfig) ,return E_INVALIDARG); + AXE_(pTaskConfig->cbSize ==sizeof(TASKDIALOGCONFIG) ,return E_INVALIDARG); + AXE_(pTaskConfig->cbSize_X==sizeof(TASKDIALOGCONFIG_X) ,return E_INVALIDARG); + + if(IS(pnButton)) *pnButton = 0; + + CTask98Dialog dlg; + dlg.ShowExpanderIcon =iconExpanderShow; AXE_(IS( + dlg.SetConfig(pTaskConfig)) ,return E_FAIL); + + do{dlg.DoModal(pTaskConfig->hwndParent); + }while( dlg.IsNavigated() ); + + dlg.GetDialogResult(pnButton, pnRadioButton, pfVerificationFlagChecked); + return S_OK; +} + +inline HRESULT Task98Dialog(HWND hwndParent, HINSTANCE hInstance, LPCTSTR pszWindowTitle, LPCTSTR pszMainInstruction, LPCTSTR pszContent, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons, LPCTSTR pszIcon, int* pnButton,bool iconExpanderShow=false) +{ + TASKDIALOGCONFIG cfg = { 0 }; + cfg.cbSize = sizeof(cfg); + cfg.hInstance = hInstance; + cfg.hwndParent = hwndParent; + cfg.dwCommonButtons = dwCommonButtons; + + USES_CONVERSION; + cfg.pszWindowTitle = IS_INTRESOURCE(pszWindowTitle) ? (LPCWSTR) pszWindowTitle : T2CW(pszWindowTitle); + cfg.pszMainInstruction = IS_INTRESOURCE(pszMainInstruction) ? (LPCWSTR) pszMainInstruction : T2CW(pszMainInstruction); + cfg.pszContent = IS_INTRESOURCE(pszContent) ? (LPCWSTR) pszContent : T2CW(pszContent); + cfg.pszMainIcon = IS_INTRESOURCE(pszIcon) ? (LPCWSTR) pszIcon : T2CW(pszIcon); + + return Task98DialogIndirect(&cfg, pnButton, NULL, NULL,iconExpanderShow); +} + + +#endif // !defined(AFX_TASKDIALOGEMU_H__20073232_5AA0_1E88_3A6D_0080AD509054__INCLUDED_) + diff --git a/TaskDialogEmu.h.DLURect.incl b/TaskDialogEmu.h.DLURect.incl new file mode 100644 index 0000000..e79c007 --- /dev/null +++ b/TaskDialogEmu.h.DLURect.incl @@ -0,0 +1,913 @@ +//DLU ist definiert als: +//DLUx := 4/CharBreite, also 4/BaseUnit.cx +//DLUy := 8/CharHöhe; also (/BaseUnit.cy + + +/* + +bu/4 = pix/dlu==> +4/bu = dlu/pix +pix*4/bu =dlu + +*/ + +#define TBU PixSize +struct ActBaseUnit +{static TBU& val(){static TBU x(0,0); + return x; + } + static void val(const PixSize& s){val().cx=s.cx; + val().cy=s.cy; + PixSize tst=val(); + } +}; + +typedef struct tagDLURECT +{ + LONG left; + LONG top; + LONG right; + LONG bottom; +} DLURECT, *PDLURECT, NEAR *NPDLURECT, FAR *LPDLURECT; + +typedef const DLURECT FAR* LPCDLURECT; + +typedef struct _DLURECTL /* rcl */ +{ + LONG left; + LONG top; + LONG right; + LONG bottom; +} DLURECTL, *PDLURECTL, *LPDLURECTL; + +typedef const DLURECTL FAR* LPCDLURECTL; + +typedef struct tagDLUPOINT +{ + LONG x; + LONG y; +} DLUPOINT, *PDLUPOINT, NEAR *NPDLUPOINT, FAR *LPDLUPOINT; + +typedef struct _DLUPOINTL /* ptl */ +{ + LONG x; + LONG y; +} DLUPOINTL, *PDLUPOINTL; + +typedef struct tagDLUSIZE +{ + LONG cx; + LONG cy; +} DLUSIZE, *PDLUSIZE, *LPDLUSIZE; + +typedef DLUSIZE DLUSIZEL; +typedef DLUSIZE *PDLUSIZEL, *LPDLUSIZEL; + +typedef struct tagDLUPOINTS +{ +#ifndef _MAC + SHORT x; + SHORT y; +#else + SHORT y; + SHORT x; +#endif +} DLUPOINTS, *PDLUPOINTS, *LPDLUPOINTS; + +class DLUSize; +class DLUPoint; +class DLURect; + +struct xDlu +{LONG n; + operator xPix(){xPix erg;erg.n= MulDiv(n, ActBaseUnit().val().cx, 4);return erg;} + xPix pix(){return xPix(MulDiv(n, ActBaseUnit().val().cx, 4));} + xDlu& operator=(const xPix& x){n=MulDiv(x.n, 4,ActBaseUnit().val().cx);return *this;} + xDlu():n(0){} + explicit xDlu(LONG x):n(x){} +}; +struct yDlu +{LONG n; + operator yPix(){yPix erg;erg.n= MulDiv(n, ActBaseUnit().val().cx, 8);return erg;} + yPix pix(){return yPix(MulDiv(n, ActBaseUnit().val().cx, 8));} + yDlu& operator=(const yPix& x){n=MulDiv(x.n, 8,ActBaseUnit().val().cx);return *this;} + yDlu():n(0){} + explicit yDlu(LONG x):n(x){} +}; +class DLUSize : public DLUSIZE +{ +public:typedef DLUSize Tp; + operator xDlu(){return xDlu(cx);} + xDlu dluX(){return xDlu(cx);} + + operator yDlu(){return yDlu(cy);} + yDlu dluY(){return yDlu(cy);} + + operator xPix(){return xDlu(cx);} + xPix pixX(){return xPix(pix().cx);} + + operator yPix(){return yDlu(cy);} + yPix pixY(){return yPix(pix().cy);} + + PixSize pix(){return *this;} + + operator PixSize(){PixSize erg;erg.cx=MulDiv(cx, ActBaseUnit().val().cx, 4); + erg.cy=MulDiv(cy, ActBaseUnit().val().cy, 8); + return erg; + } + DLUSize& operator=(const PixSize& x){DLUSize erg;erg.cx=MulDiv(x.cx, 4,ActBaseUnit().val().cx); + erg.cy=MulDiv(x.cy, 8, ActBaseUnit().val().cy); + *this=erg; + return *this; + } +// Constructors + DLUSize& operator+=(const DLUSize& x){cx+=x.cx; + cy+=x.cy; + return *this; + } + DLUSize() + { + cx = 0; + cy = 0; + } + + DLUSize(int initCX, int initCY) + { + cx = initCX; + cy = initCY; + } + + DLUSize(DLUSIZE initSize) + { + *(DLUSIZE*)this = initSize; + } + + DLUSize(DLUPOINT initPt) + { + *(DLUPOINT*)this = initPt; + } + + DLUSize(DWORD dwSize) + { + cx = (short)LOWORD(dwSize); + cy = (short)HIWORD(dwSize); + } + +// Operations + DLUSize& operator=(const DLURECT& r) {cx =r.right-r.left;return *this;} + DLUSize& operator=(LONG sz) {cx =sz;cy=sz ;return *this;} + + BOOL operator ==(DLUSIZE size) const + { + return (cx == size.cx && cy == size.cy); + } + + BOOL operator !=(DLUSIZE size) const + { + return (cx != size.cx || cy != size.cy); + } + + void operator +=(DLUSIZE size) + { + cx += size.cx; + cy += size.cy; + } + + void operator -=(DLUSIZE size) + { + cx -= size.cx; + cy -= size.cy; + } + + void SetSize(int CX, int CY) + { + cx = CX; + cy = CY; + } + +// Operators returning DLUSize values + DLUSize operator +(DLUSIZE size) const + { + return DLUSize(cx + size.cx, cy + size.cy); + } + + DLUSize operator -(DLUSIZE size) const + { + return DLUSize(cx - size.cx, cy - size.cy); + } + + DLUSize operator -() const + { + return DLUSize(-cx, -cy); + } + +// Operators returning DLUPoint values + DLUPoint operator +(DLUPOINT point) const; + DLUPoint operator -(DLUPOINT point) const; + +// Operators returning DLURect values + DLURect operator +(const DLURECT* lpRect) const; + DLURect operator -(const DLURECT* lpRect) const; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// DLUPoint - Wrapper for Windows DLUPOINT structure. + +class DLUPoint : public DLUPOINT +{ +public: + PixPoint pix(){return *this;} + + operator PixPoint(){PixPoint erg;erg.x=MulDiv(x, ActBaseUnit().val().cx, 4); + erg.y=MulDiv(y, ActBaseUnit().val().cy, 8); + return erg; +} + DLUPoint& operator=(const PixPoint& x){DLUPoint erg;erg.x=MulDiv(x.x, 4,ActBaseUnit().val().cx); + erg.y=MulDiv(x.y, 8, ActBaseUnit().val().cy); + *this=erg; + return *this; + } +// Constructors + DLUPoint& operator+=(const DLUSize& x){this->x+=x.cx; + this->y+=x.cy; + return *this; + } +// Constructors + DLUPoint(const DLUSize& a){x =a.cx;y=a.cy;} + + DLUPoint() + { + x = 0; + y = 0; + } + + DLUPoint(int initX, int initY) + { + x = initX; + y = initY; + } + + DLUPoint(DLUPOINT initPt) + { + *(DLUPOINT*)this = initPt; + } + + DLUPoint(DLUSIZE initSize) + { + *(DLUSIZE*)this = initSize; + } + + DLUPoint(DWORD dwPoint) + { + x = (short)LOWORD(dwPoint); + y = (short)HIWORD(dwPoint); + } + +// Operations + DLUPoint& operator=(const DLURECT& b) {x =b.left;y=b.top;return *this;} + + void Offset(int xOffset, int yOffset) + { + x += xOffset; + y += yOffset; + } + + void Offset(DLUPOINT point) + { + x += point.x; + y += point.y; + } + + void Offset(DLUSIZE size) + { + x += size.cx; + y += size.cy; + } + + BOOL operator ==(DLUPOINT point) const + { + return (x == point.x && y == point.y); + } + + BOOL operator !=(DLUPOINT point) const + { + return (x != point.x || y != point.y); + } + + void operator +=(DLUSIZE size) + { + x += size.cx; + y += size.cy; + } + + void operator -=(DLUSIZE size) + { + x -= size.cx; + y -= size.cy; + } + + void operator +=(DLUPOINT point) + { + x += point.x; + y += point.y; + } + + void operator -=(DLUPOINT point) + { + x -= point.x; + y -= point.y; + } + + void SetPoint(int X, int Y) + { + x = X; + y = Y; + } + +// Operators returning DLUPoint values + DLUPoint operator +(DLUSIZE size) const + { + return DLUPoint(x + size.cx, y + size.cy); + } + + DLUPoint operator -(DLUSIZE size) const + { + return DLUPoint(x - size.cx, y - size.cy); + } + + DLUPoint operator -() const + { + return DLUPoint(-x, -y); + } + + DLUPoint operator +(DLUPOINT point) const + { + return DLUPoint(x + point.x, y + point.y); + } + +// Operators returning DLUSize values + DLUSize operator -(DLUPOINT point) const + { + return DLUSize(x - point.x, y - point.y); + } + +// Operators returning DLURect values + DLURect operator +(const DLURECT* lpRect) const; + DLURect operator -(const DLURECT* lpRect) const; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// DLURect - Wrapper for Windows DLURECT structure. + +class DLURect : public DLURECT +{ +public: + DLURect& adjust()const{const_cast(this)->right =max(left,right); + const_cast(this)->bottom=max(top ,bottom); + return *const_cast(this); + } + PixRect pix(){adjust();return *this;} + + operator PixRect(){adjust(); + PixRect erg;erg.left=::MulDiv(left, ActBaseUnit().val().cx, 4); + erg.right=::MulDiv(right, ActBaseUnit().val().cx, 4); + erg.top=::MulDiv(top, ActBaseUnit().val().cy, 8); + erg.bottom=::MulDiv(bottom, ActBaseUnit().val().cy, 8); + return erg; + } + DLURect& operator=(const PixRect& x){DLURect erg;erg.left =::MulDiv(x.left, 4,ActBaseUnit().val().cx); + erg.right =::MulDiv(x.right, 4,ActBaseUnit().val().cx); + erg.top =::MulDiv(x.top, 8, ActBaseUnit().val().cy); + erg.bottom=::MulDiv(x.bottom, 8, ActBaseUnit().val().cy); + *this=erg; + return *this; + } +public: +// Constructors + DLUSize size(){adjust(); + if(right < left) right=left; + if(bottom < top) bottom=top; + + DLUSize s; + s.cx=right-left; + s.cy=bottom-top; + return s; + } + DLURect(const DLUSize& s){adjust(); + *this =s;} + DLURect(const DLUPoint& x){*this =x;} + DLURect& sizeMax(const DLURect& plt ,const DLURect& prb) + {adjust(); + plt.adjust(); + prb.adjust(); + DLUSize nsz=DLURect(plt.left,plt.top,prb.right,prb.bottom).size(); + DLUSize sz =size(); + DLUSize mx(max(nsz.cx,sz.cx) + ,max(nsz.cy,sz.cy) + ); + *this =mx; + return *this; + } + + DLURect() + { + left = 0; + top = 0; + right = 0; + bottom = 0; + } + + DLURect(int l, int t, int r, int b) + { + left = l; + top = t; + right = r; + bottom = b; + } + + DLURect(DLURect& srDLURect) + { + srDLURect.adjust(); + *this =srDLURect;//::CopyRect(this, (LPDLURECT)&srDLURect); + } + + DLURect(const DLURECT& srDLURect) + { + *this =srDLURect;//::CopyRect(this, (LPDLURECT)&srDLURect); + adjust(); + } + + DLURect(LPCDLURECT lpSrDLURect) + { + *this=lpSrDLURect;//::CopyRect(this, lpSrDLURect); + adjust(); + } + + DLURect(DLUPOINT point, DLUSIZE size) + { + right = (left = point.x) + size.cx; + bottom = (top = point.y) + size.cy; + } + + DLURect(DLUPOINT topLeft, DLUPOINT bottomRight) + { + left = topLeft.x; + top = topLeft.y; + right = bottomRight.x; + bottom = bottomRight.y; + } + +// Attributes (in addition to DLURECT members) + int Width() const + { adjust(); + return right - left; + } + + int Height() const + { + adjust(); + return bottom - top; + } + + DLUSize Size() const + { + adjust(); + return DLUSize(right - left, bottom - top); + } + + DLUPoint& TopLeft() + { + return *((DLUPoint*)this); + } + DLUPoint& point() + { + return *((DLUPoint*)this); + } + + DLUPoint& BottomRight() + { + return *((DLUPoint*)this + 1); + } + + const DLUPoint& TopLeft() const + { + return *((DLUPoint*)this); + } + + const DLUPoint& BottomRight() const + { + adjust(); + return *((DLUPoint*)this + 1); + } + + DLUPoint CenterPoint() const + { + adjust(); + return DLUPoint((left + right) / 2, (top + bottom) / 2); + } + + // convert between DLURect and LPRECT/LPCRECT (no need for &) + operator LPDLURECT() + { + adjust(); + return this; + } + + operator LPCDLURECT() const + { + adjust(); + return this; + } + + BOOL IsRectEmpty() const + { + adjust(); + return ::IsRectEmpty((RECT*)this); + } + + BOOL IsRectNull() const + { + return (left == 0 && right == 0 && top == 0 && bottom == 0); + } + + BOOL PtInRect(DLUPOINT point) const + { + adjust(); + return ::PtInRect((RECT*)this, *((POINT*)&point)); + } + +// Operations + void SetRect(int x1, int y1, int x2, int y2) + { + ::SetRect((RECT*)this, x1, y1, x2, y2); + } + + void SetRect(DLUPOINT topLeft, DLUPOINT bottomRight) + { + ::SetRect((RECT*)this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); + } + + void SetRectEmpty() + { + ::SetRectEmpty((RECT*)this); + } + + void CopyRect(LPCRECT lpSrDLURect) + { + adjust(); + ::CopyRect((RECT*)this, (RECT*)lpSrDLURect); + } + + BOOL EqualRect(LPCRECT lpRect) const + { + adjust(); + return ::EqualRect((RECT*)this, (RECT*)lpRect); + } + + void InflateRect(int x, int y) + { + adjust(); + ::InflateRect((RECT*)this, x, y); + } + + void InflateRect(DLUSIZE size) + { + adjust(); + ::InflateRect((RECT*)this, size.cx, size.cy); + } + + void InflatDLURect(LPCRECT lpRect) + { + adjust(); + left -= lpRect->left; + top -= lpRect->top; + right += lpRect->right; + bottom += lpRect->bottom; + } + + void InflatDLURect(int l, int t, int r, int b) + { + adjust(); + left -= l; + top -= t; + right += r; + bottom += b; + } + + void DeflateRect(int x, int y) + { + adjust(); + ::InflateRect((RECT*)this, -x, -y); + } + + void Deflateect(DLUSIZE size) + { + adjust(); + ::InflateRect((RECT*)this, -size.cx, -size.cy); + } + + void DeflateRect(LPCRECT lpRect) + { + adjust(); + left += lpRect->left; + top += lpRect->top; + right -= lpRect->right; + bottom -= lpRect->bottom; + } + + void DeflateRect(int l, int t, int r, int b) + { + adjust(); + left += l; + top += t; + right -= r; + bottom -= b; + } + + void OffsetRect(int x, int y) + { + adjust(); + ::OffsetRect((RECT*)this, x, y); + } + void OffsetRect(DLUSIZE size) + { + adjust(); + ::OffsetRect((RECT*)this, size.cx, size.cy); + } + + void OffsetRect(DLUPOINT point) + { + adjust(); + ::OffsetRect((RECT*)this, point.x, point.y); + } + + void NormalizDLURect() + { + adjust(); + int nTemp; + if (left > right) + { + nTemp = left; + left = right; + right = nTemp; + } + if (top > bottom) + { + nTemp = top; + top = bottom; + bottom = nTemp; + } + } + + // absolute position of rectangle + void MoveToY(int y) + { + adjust(); + bottom = Height() + y; + top = y; + } + + void MoveToX(int x) + { + adjust(); + right = Width() + x; + left = x; + } + + void MoveToXY(int x, int y) + { + adjust(); + MoveToX(x); + MoveToY(y); + } + + void MoveToXY(DLUPOINT pt) + { + adjust(); + MoveToX(pt.x); + MoveToY(pt.y); + } + + // operations that fill '*this' with result + BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2) + { + adjust(); + return ::IntersectRect((RECT*)this, (RECT*)lpRect1, (RECT*)lpRect2); + } + + BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) + { + adjust(); + return ::UnionRect((RECT*)this, (RECT*)lpRect1, (RECT*)lpRect2); + } + + BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) + { + adjust(); + return ::SubtractRect((RECT*)this, (RECT*)lpRectSrc1, (RECT*)lpRectSrc2); + } + +// Additional Operations + DLURect& operator=(const DLUPOINT& p){left =p.x;top=p.y;return *this;} + DLURect& operator=(const DLUSIZE& s){right =left+s.cx; bottom=top+s.cy;return *this;} + + void operator =(const DLURECT& srDLURect) + { + ::CopyRect((RECT*)this, (RECT*)&srDLURect); + } + + BOOL operator ==(const DLURECT& rect) const + { + adjust(); + return ::EqualRect((RECT*)this, (RECT*)&rect); + } + + BOOL operator !=(const DLURECT& rect) const + { + adjust(); + return !::EqualRect((RECT*)this, (RECT*)&rect); + } + + void operator +=(DLUPOINT point) + { + adjust(); + ::OffsetRect((RECT*)this, point.x, point.y); + } + + void operator +=(DLUSIZE size) + { + adjust(); + ::OffsetRect((RECT*)this, size.cx, size.cy); + } + + void operator +=(LPCRECT lpRect) + { + adjust(); + InflatDLURect(lpRect); + } + + void operator -=(DLUPOINT point) + { + adjust(); + ::OffsetRect((RECT*)this, -point.x, -point.y); + } + + void operator -=(DLUSIZE size) + { + adjust(); + ::OffsetRect((RECT*)this, -size.cx, -size.cy); + } + + void operator -=(LPCRECT lpRect) + { + adjust(); + DeflateRect(lpRect); + } + + void operator &=(const DLURECT& rect) + { + adjust(); + ::IntersectRect((RECT*)this, (RECT*)this, (RECT*)&rect); + } + + void operator |=(const DLURECT& rect) + { + adjust(); + ::UnionRect((RECT*)this, (RECT*)this, (RECT*)&rect); + } + +// Operators returning DLURect values + DLURect operator +(DLUPOINT pt) const + { + adjust(); + DLURect rect(*this); + ::OffsetRect((RECT*)&rect, pt.x, pt.y); + return rect; + } + + DLURect operator -(DLUPOINT pt) const + { + adjust(); + DLURect rect(*this); + ::OffsetRect((RECT*)&rect, -pt.x, -pt.y); + return rect; + } + + DLURect operator +(LPCRECT lpRect) const + { + adjust(); + DLURect rect(this); + rect.InflatDLURect(lpRect); + return rect; + } + + DLURect operator +(DLUSIZE size) const + { + adjust(); + DLURect rect(*this); + ::OffsetRect((RECT*)&rect, size.cx, size.cy); + return rect; + } + + DLURect operator -(DLUSIZE size) const + { + adjust(); + DLURect rect(*this); + ::OffsetRect((RECT*)&rect, -size.cx, -size.cy); + return rect; + } + + DLURect operator -(LPCRECT lpRect) const + { + adjust(); + DLURect rect(this); + rect.DeflateRect(lpRect); + return rect; + } + + DLURect operator &(const DLURECT& rect2) const + { + adjust(); + DLURect rect; + ::IntersectRect((RECT*)&rect, (RECT*)this, (RECT*)&rect2); + return rect; + } + + DLURect operator |(const DLURECT& rect2) const + { + adjust(); + DLURect rect; + ::UnionRect((RECT*)&rect, (RECT*)this, (RECT*)&rect2); + return rect; + } + + DLURect MulDiv(int nMultiplier, int nDivisor) const + { + adjust(); + return DLURect( + ::MulDiv(left, nMultiplier, nDivisor), + ::MulDiv(top, nMultiplier, nDivisor), + ::MulDiv(right, nMultiplier, nDivisor), + ::MulDiv(bottom, nMultiplier, nDivisor)); + } +}; + + +// DLUSize implementation + +inline DLUPoint DLUSize::operator +(DLUPOINT point) const +{ return DLUPoint(cx + point.x, cy + point.y); } + +inline DLUPoint DLUSize::operator -(DLUPOINT point) const +{ return DLUPoint(cx - point.x, cy - point.y); } + +inline DLURect DLUSize::operator +(const DLURECT* lpRect) const +{ return DLURect(lpRect) + *this; } + +inline DLURect DLUSize::operator -(const DLURECT* lpRect) const +{ return DLURect(lpRect) - *this; } + + +// DLUPoint implementation + +inline DLURect DLUPoint::operator +(const DLURECT* lpRect) const +{ return DLURect(lpRect) + *this; } + +inline DLURect DLUPoint::operator -(const DLURECT* lpRect) const +{ return DLURect(lpRect) - *this; } + + + +#if !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) +#ifndef __ATLMISC_H__ + +template +inline DLUSize operator *(DLUSIZE s, Num n) +{ + return DLUSize((int)(s.cx * n), (int)(s.cy * n)); +}; + +template +inline void operator *=(DLUSIZE & s, Num n) +{ + s = s * n; +}; + +template +inline DLUSize operator /(DLUSIZE s, Num n) +{ + return DLUSize((int)(s.cx / n), (int)(s.cy / n)); +}; + +template +inline void operator /=(DLUSIZE & s, Num n) +{ + s = s / n; +}; +#endif +#endif + + DLUSize size(const DLURect& plt ,const DLURect& prb) {return DLUSize()=DLURect(plt.left,plt.top,prb.right,prb.bottom);} + diff --git a/TaskDialogEmu.h.PixelRect.incl b/TaskDialogEmu.h.PixelRect.incl new file mode 100644 index 0000000..756fbb2 --- /dev/null +++ b/TaskDialogEmu.h.PixelRect.incl @@ -0,0 +1,775 @@ +class PixSize; +class PixPoint; +class PixRect; + + +struct xPix +{LONG n; + xPix():n(0){} + explicit xPix(LONG x):n(x){} +}; +struct yPix +{LONG n; + yPix():n(0){} + explicit yPix(LONG x):n(x){} +}; + + +class PixSize : public SIZE +{ +public: + operator xPix(){return xPix(cx);} + operator yPix(){return yPix(cy);} + +// Constructors + PixSize& operator+=(const PixSize& x){cx+=x.cx; + cy+=x.cy; + return *this; + } + PixSize() + { + cx = 0; + cy = 0; + } + + PixSize(int initCX, int initCY) + { + cx = initCX; + cy = initCY; + } + + PixSize(SIZE initSize) + { + *(SIZE*)this = initSize; + } + + PixSize(POINT initPt) + { + *(POINT*)this = initPt; + } + + PixSize(DWORD dwSize) + { + cx = (short)LOWORD(dwSize); + cy = (short)HIWORD(dwSize); + } + +// Operations + PixSize& operator=(const RECT& r) {cx =r.right-r.left;return *this;} + PixSize& operator=(LONG sz) {cx =sz;cy=sz ;return *this;} + + BOOL operator ==(SIZE size) const + { + return (cx == size.cx && cy == size.cy); + } + + BOOL operator !=(SIZE size) const + { + return (cx != size.cx || cy != size.cy); + } + + void operator +=(SIZE size) + { + cx += size.cx; + cy += size.cy; + } + + void operator -=(SIZE size) + { + cx -= size.cx; + cy -= size.cy; + } + + void SetSize(int CX, int CY) + { + cx = CX; + cy = CY; + } + +// Operators returning PixSize values + PixSize operator +(SIZE size) const + { + return PixSize(cx + size.cx, cy + size.cy); + } + + PixSize operator -(SIZE size) const + { + return PixSize(cx - size.cx, cy - size.cy); + } + + PixSize operator -() const + { + return PixSize(-cx, -cy); + } + +// Operators returning PixPoint values + PixPoint operator +(POINT point) const; + PixPoint operator -(POINT point) const; + +// Operators returning PixRect values + PixRect operator +(const RECT* lpRect) const; + PixRect operator -(const RECT* lpRect) const; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// PixPoint - Wrapper for Windows POINT structure. + +class PixPoint : public POINT +{ +public: +// Constructors + PixPoint(const PixSize& a){x =a.cx;y=a.cy;} + + PixPoint() + { + x = 0; + y = 0; + } + + PixPoint(int initX, int initY) + { + x = initX; + y = initY; + } + + PixPoint(POINT initPt) + { + *(POINT*)this = initPt; + } + + PixPoint(SIZE initSize) + { + *(SIZE*)this = initSize; + } + + PixPoint(DWORD dwPoint) + { + x = (short)LOWORD(dwPoint); + y = (short)HIWORD(dwPoint); + } + +// Operations + PixPoint& operator=(const RECT& b) {x =b.left;y=b.top;return *this;} + + void Offset(int xOffset, int yOffset) + { + x += xOffset; + y += yOffset; + } + + void Offset(POINT point) + { + x += point.x; + y += point.y; + } + + void Offset(SIZE size) + { + x += size.cx; + y += size.cy; + } + + BOOL operator ==(POINT point) const + { + return (x == point.x && y == point.y); + } + + BOOL operator !=(POINT point) const + { + return (x != point.x || y != point.y); + } + + void operator +=(SIZE size) + { + x += size.cx; + y += size.cy; + } + + void operator -=(SIZE size) + { + x -= size.cx; + y -= size.cy; + } + + void operator +=(POINT point) + { + x += point.x; + y += point.y; + } + + void operator -=(POINT point) + { + x -= point.x; + y -= point.y; + } + + void SetPoint(int X, int Y) + { + x = X; + y = Y; + } + +// Operators returning PixPoint values + PixPoint operator +(SIZE size) const + { + return PixPoint(x + size.cx, y + size.cy); + } + + PixPoint operator -(SIZE size) const + { + return PixPoint(x - size.cx, y - size.cy); + } + + PixPoint operator -() const + { + return PixPoint(-x, -y); + } + + PixPoint operator +(POINT point) const + { + return PixPoint(x + point.x, y + point.y); + } + +// Operators returning PixSize values + PixSize operator -(POINT point) const + { + return PixSize(x - point.x, y - point.y); + } + +// Operators returning PixRect values + PixRect operator +(const RECT* lpRect) const; + PixRect operator -(const RECT* lpRect) const; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// PixRect - Wrapper for Windows RECT structure. + +class PixRect : public RECT +{ +public: + PixRect& adjust()const{const_cast(this)->right =max(left,right); + const_cast(this)->bottom=max(top ,bottom); + return *const_cast(this); + } +// Constructors + PixSize size(){adjust(); + if(right < left) right=left; + if(bottom < top) bottom=top; + + PixSize s; + s.cx=right-left; + s.cy=bottom-top; + return s; + } + PixRect(const PixSize& s){*this =s;} + PixRect(const PixPoint& x){*this =x;} + PixRect& sizeMax(const PixRect& plt ,const PixRect& prb) + {adjust(); + const_cast(plt).adjust(); + const_cast(prb).adjust(); + + PixSize nsz=PixRect(plt.left,plt.top,prb.right,prb.bottom).size(); + PixSize sz =size(); + PixSize mx(max(nsz.cx,sz.cx) + ,max(nsz.cy,sz.cy) + ); + *this =mx; + return *this; + } + + PixRect() + { + left = 0; + top = 0; + right = 0; + bottom = 0; + } + + PixRect(int l, int t, int r, int b) + { + left = l; + top = t; + right = r; + bottom = b; + } + + PixRect(const RECT& srERect) + { + ::CopyRect(this, &srERect); + } + + PixRect(LPCRECT lpSrERect) + { + ::CopyRect(this, lpSrERect); + } + + PixRect(POINT point, SIZE size) + { + right = (left = point.x) + size.cx; + bottom = (top = point.y) + size.cy; + } + + PixRect(POINT topLeft, POINT bottomRight) + { + left = topLeft.x; + top = topLeft.y; + right = bottomRight.x; + bottom = bottomRight.y; + } + +// Attributes (in addition to RECT members) + int Width() const + { + adjust(); + return right - left; + } + + int Height() const + { + adjust(); + return bottom - top; + } + + PixSize Size() const + { + adjust(); + return PixSize(right - left, bottom - top); + } + + PixPoint& TopLeft() + { + return *((PixPoint*)this); + } + PixPoint& point() + { + return *((PixPoint*)this); + } + + PixPoint& BottomRight() + { + adjust(); + return *((PixPoint*)this + 1); + } + + const PixPoint& TopLeft() const + { + return *((PixPoint*)this); + } + + const PixPoint& BottomRight() const + { + adjust(); + return *((PixPoint*)this + 1); + } + + PixPoint CenterPoint() const + { + adjust(); + return PixPoint((left + right) / 2, (top + bottom) / 2); + } + + // convert between PixRect and LPRECT/LPCRECT (no need for &) + operator LPRECT() + { + adjust(); + return this; + } + + operator LPCRECT() const + { + adjust(); + return this; + } + + BOOL IsRectEmpty() const + { + adjust(); + return ::IsRectEmpty(this); + } + + BOOL IsRectNull() const + { + return (left == 0 && right == 0 && top == 0 && bottom == 0); + } + + BOOL PtInRect(POINT point) const + { + adjust(); + return ::PtInRect(this, point); + } + +// Operations + void SetRect(int x1, int y1, int x2, int y2) + { + ::SetRect(this, x1, y1, x2, y2); + } + + void SetRect(POINT topLeft, POINT bottomRight) + { + ::SetRect(this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); + } + + void SetRectEmpty() + { + ::SetRectEmpty(this); + } + + void CopyRect(LPCRECT lpSrERect) + { + adjust(); + ::CopyRect(this, lpSrERect); + } + + BOOL EqualRect(LPCRECT lpRect) const + { + adjust(); + return ::EqualRect(this, lpRect); + } + + void InflateRect(int x, int y) + { + adjust(); + ::InflateRect(this, x, y); + } + + void InflateRect(SIZE size) + { + adjust(); + ::InflateRect(this, size.cx, size.cy); + } + + void InflateRect(LPCRECT lpRect) + { + adjust(); + left -= lpRect->left; + top -= lpRect->top; + right += lpRect->right; + bottom += lpRect->bottom; + } + + void InflateRect(int l, int t, int r, int b) + { + adjust(); + left -= l; + top -= t; + right += r; + bottom += b; + } + + void DeflateRect(int x, int y) + { + adjust(); + ::InflateRect(this, -x, -y); + } + + void DeflateRect(SIZE size) + { + adjust(); + ::InflateRect(this, -size.cx, -size.cy); + } + + void DeflateRect(LPCRECT lpRect) + { + adjust(); + left += lpRect->left; + top += lpRect->top; + right -= lpRect->right; + bottom -= lpRect->bottom; + } + + void DeflateRect(int l, int t, int r, int b) + { + adjust(); + left += l; + top += t; + right -= r; + bottom -= b; + } + + void OffsetRect(int x, int y) + { + adjust(); + ::OffsetRect(this, x, y); + } + void OffsetRect(SIZE size) + { + adjust(); + ::OffsetRect(this, size.cx, size.cy); + } + + void OffsetRect(POINT point) + { + adjust(); + ::OffsetRect(this, point.x, point.y); + } + + void NormalizeRect() + { + adjust(); + int nTemp; + if (left > right) + { + nTemp = left; + left = right; + right = nTemp; + } + if (top > bottom) + { + nTemp = top; + top = bottom; + bottom = nTemp; + } + } + + // absolute position of rectangle + void MoveToY(int y) + { + adjust(); + bottom = Height() + y; + top = y; + } + + void MoveToX(int x) + { + adjust(); + right = Width() + x; + left = x; + } + + void MoveToXY(int x, int y) + { + adjust(); + MoveToX(x); + MoveToY(y); + } + + void MoveToXY(POINT pt) + { + adjust(); + MoveToX(pt.x); + MoveToY(pt.y); + } + + // operations that fill '*this' with result + BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2) + { + adjust(); + return ::IntersectRect(this, lpRect1, lpRect2); + } + + BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) + { + adjust(); + return ::UnionRect(this, lpRect1, lpRect2); + } + + BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) + { + adjust(); + return ::SubtractRect(this, lpRectSrc1, lpRectSrc2); + } + +// Additional Operations + PixRect& operator=(const POINT& p){left =p.x;top=p.y;return *this;} + PixRect& operator=(const SIZE& s){right =left+s.cx; bottom=top+s.cy;return *this;} + + void operator =(const RECT& srERect) + { + ::CopyRect(this, &srERect); + } + + BOOL operator ==(const RECT& rect) const + { + adjust(); + return ::EqualRect(this, &rect); + } + + BOOL operator !=(const RECT& rect) const + { + adjust(); + return !::EqualRect(this, &rect); + } + + void operator +=(POINT point) + { + adjust(); + ::OffsetRect(this, point.x, point.y); + } + + void operator +=(SIZE size) + { + adjust(); + ::OffsetRect(this, size.cx, size.cy); + } + + void operator +=(LPCRECT lpRect) + { + adjust(); + InflateRect(lpRect); + } + + void operator -=(POINT point) + { + adjust(); + ::OffsetRect(this, -point.x, -point.y); + } + + void operator -=(SIZE size) + { + adjust(); + ::OffsetRect(this, -size.cx, -size.cy); + } + + void operator -=(LPCRECT lpRect) + { + adjust(); + DeflateRect(lpRect); + } + + void operator &=(const RECT& rect) + { + adjust(); + ::IntersectRect(this, this, &rect); + } + + void operator |=(const RECT& rect) + { + adjust(); + ::UnionRect(this, this, &rect); + } + +// Operators returning PixRect values + PixRect operator +(POINT pt) const + { + adjust(); + PixRect rect(*this); + ::OffsetRect(&rect, pt.x, pt.y); + return rect; + } + + PixRect operator -(POINT pt) const + { + adjust(); + PixRect rect(*this); + ::OffsetRect(&rect, -pt.x, -pt.y); + return rect; + } + + PixRect operator +(LPCRECT lpRect) const + { + adjust(); + PixRect rect(this); + rect.InflateRect(lpRect); + return rect; + } + + PixRect operator +(SIZE size) const + { + adjust(); + PixRect rect(*this); + ::OffsetRect(&rect, size.cx, size.cy); + return rect; + } + + PixRect operator -(SIZE size) const + { + adjust(); + PixRect rect(*this); + ::OffsetRect(&rect, -size.cx, -size.cy); + return rect; + } + + PixRect operator -(LPCRECT lpRect) const + { + adjust(); + PixRect rect(this); + rect.DeflateRect(lpRect); + return rect; + } + + PixRect operator &(const RECT& rect2) const + { + adjust(); + PixRect rect; + ::IntersectRect(&rect, this, &rect2); + return rect; + } + + PixRect operator |(const RECT& rect2) const + { + adjust(); + PixRect rect; + ::UnionRect(&rect, this, &rect2); + return rect; + } + + PixRect MulDiv(int nMultiplier, int nDivisor) const + { + adjust(); + return PixRect( + ::MulDiv(left, nMultiplier, nDivisor), + ::MulDiv(top, nMultiplier, nDivisor), + ::MulDiv(right, nMultiplier, nDivisor), + ::MulDiv(bottom, nMultiplier, nDivisor)); + } +}; + + +// PixSize implementation + +inline PixPoint PixSize::operator +(POINT point) const +{ return PixPoint(cx + point.x, cy + point.y); } + +inline PixPoint PixSize::operator -(POINT point) const +{ return PixPoint(cx - point.x, cy - point.y); } + +inline PixRect PixSize::operator +(const RECT* lpRect) const +{ return PixRect(lpRect) + *this; } + +inline PixRect PixSize::operator -(const RECT* lpRect) const +{ return PixRect(lpRect) - *this; } + + +// PixPoint implementation + +inline PixRect PixPoint::operator +(const RECT* lpRect) const +{ return PixRect(lpRect) + *this; } + +inline PixRect PixPoint::operator -(const RECT* lpRect) const +{ return PixRect(lpRect) - *this; } + + + +#if !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) +#ifndef __ATLMISC_H__ + +template +inline PixSize operator *(SIZE s, Num n) +{ + return PixSize((int)(s.cx * n), (int)(s.cy * n)); +}; + +template +inline void operator *=(SIZE & s, Num n) +{ + s = s * n; +}; + +template +inline PixSize operator /(SIZE s, Num n) +{ + return PixSize((int)(s.cx / n), (int)(s.cy / n)); +}; + +template +inline void operator /=(SIZE & s, Num n) +{ + s = s / n; +}; +#endif +#endif + + PixSize size(const PixRect& plt ,const PixRect& prb) {return PixSize()=PixRect(plt.left,plt.top,prb.right,prb.bottom);} + diff --git a/TaskDialogEmu.h.PreVistaDeclarations.incl b/TaskDialogEmu.h.PreVistaDeclarations.incl new file mode 100644 index 0000000..c38d97e --- /dev/null +++ b/TaskDialogEmu.h.PreVistaDeclarations.incl @@ -0,0 +1,148 @@ +#if _WIN32_WINNT < 0x0600 && !defined(TD_WARNING_ICON) +///////////////////////////////////////////////////////////////////////// +// /// _WIN32_WINNT < 0x0600 && !defined(TD_WARNING_ICON) +// + + #ifdef _WIN32 + #include + #endif // _WIN32 + + typedef HRESULT (CALLBACK *PFTASKDIALOGCALLBACK)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData); + + enum _TASKDIALOG_FLAGS + { + TDF_ENABLE_HYPERLINKS = 0x0001, + TDF_USE_HICON_MAIN = 0x0002, + TDF_USE_HICON_FOOTER = 0x0004, + TDF_ALLOW_DIALOG_CANCELLATION = 0x0008, + TDF_USE_COMMAND_LINKS = 0x0010, + TDF_USE_COMMAND_LINKS_NO_ICON = 0x0020, + TDF_EXPAND_FOOTER_AREA = 0x0040, + TDF_EXPANDED_BY_DEFAULT = 0x0080, + TDF_VERIFICATION_FLAG_CHECKED = 0x0100, + TDF_SHOW_PROGRESS_BAR = 0x0200, + TDF_SHOW_MARQUEE_PROGRESS_BAR = 0x0400, + TDF_CALLBACK_TIMER = 0x0800, + TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000, + TDF_RTL_LAYOUT = 0x2000, + TDF_NO_DEFAULT_RADIO_BUTTON = 0x4000, + TDF_CAN_BE_MINIMIZED = 0x8000 + }; + typedef int TASKDIALOG_FLAGS; + + typedef enum _TASKDIALOG_MESSAGES + { + TDM_NAVIGATE_PAGE = WM_USER + 101, + TDM_CLICK_BUTTON = WM_USER + 102, + TDM_SET_MARQUEE_PROGRESS_BAR = WM_USER + 103, + TDM_SET_PROGRESS_BAR_STATE = WM_USER + 104, + TDM_SET_PROGRESS_BAR_RANGE = WM_USER + 105, + TDM_SET_PROGRESS_BAR_POS = WM_USER + 106, + TDM_SET_PROGRESS_BAR_MARQUEE = WM_USER + 107, + TDM_SET_ELEMENT_TEXT = WM_USER + 108, + TDM_CLICK_RADIO_BUTTON = WM_USER + 110, + TDM_ENABLE_BUTTON = WM_USER + 111, + TDM_ENABLE_RADIO_BUTTON = WM_USER + 112, + TDM_CLICK_VERIFICATION = WM_USER + 113, + TDM_UPDATE_ELEMENT_TEXT = WM_USER + 114, + TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = WM_USER + 115, + TDM_UPDATE_ICON = WM_USER + 116 + } TASKDIALOG_MESSAGES; + + typedef enum _TASKDIALOG_NOTIFICATIONS + { + TDN_CREATED = 0, + TDN_NAVIGATED = 1, + TDN_BUTTON_CLICKED = 2, + TDN_HYPERLINK_CLICKED = 3, + TDN_TIMER = 4, + TDN_DESTROYED = 5, + TDN_RADIO_BUTTON_CLICKED = 6, + TDN_DIALOG_CONSTRUCTED = 7, + TDN_VERIFICATION_CLICKED = 8, + TDN_HELP = 9, + TDN_EXPANDO_BUTTON_CLICKED = 10 + } TASKDIALOG_NOTIFICATIONS; + + typedef struct _TASKDIALOG_BUTTON + { + int nButtonID; + PCWSTR pszButtonText; + }TASKDIALOG_BUTTON + ;// ////////////////////////////////////////////////////// + + typedef enum _TASKDIALOG_ELEMENTS + { + TDE_CONTENT, + TDE_EXPANDED_INFORMATION, + TDE_FOOTER, + TDE_MAIN_INSTRUCTION + } TASKDIALOG_ELEMENTS; + + typedef enum _TASKDIALOG_ICON_ELEMENTS + { + TDIE_ICON_MAIN, + TDIE_ICON_FOOTER + } TASKDIALOG_ICON_ELEMENTS; + + #define TD_WARNING_ICON MAKEINTRESOURCEW(-1) + #define TD_ERROR_ICON MAKEINTRESOURCEW(-2) + #define TD_INFORMATION_ICON MAKEINTRESOURCEW(-3) + #define TD_SHIELD_ICON MAKEINTRESOURCEW(-4) + + enum _TASKDIALOG_COMMON_BUTTON_FLAGS + { + TDCBF_OK_BUTTON = 0x0001, // selected control return value IDOK + TDCBF_YES_BUTTON = 0x0002, // selected control return value IDYES + TDCBF_NO_BUTTON = 0x0004, // selected control return value IDNO + TDCBF_CANCEL_BUTTON = 0x0008, // selected control return value IDCANCEL + TDCBF_RETRY_BUTTON = 0x0010, // selected control return value IDRETRY + TDCBF_CLOSE_BUTTON = 0x0020 // selected control return value IDCLOSE + }; + typedef int TASKDIALOG_COMMON_BUTTON_FLAGS; + + struct TASKDIALOGCONFIG + { + UINT cbSize; + HWND hwndParent; + HINSTANCE hInstance; // used for MAKEINTRESOURCE() strings + TASKDIALOG_FLAGS dwFlags; // TASKDIALOG_FLAGS (TDF_XXX) flags + TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons; // TASKDIALOG_COMMON_BUTTON (TDCBF_XXX) flags + PCWSTR pszWindowTitle; // string or MAKEINTRESOURCE() + union + { + HICON hMainIcon; + PCWSTR pszMainIcon; + }; + PCWSTR pszMainInstruction; + PCWSTR pszContent; + UINT cButtons; + const TASKDIALOG_BUTTON *pButtons; + int nDefaultButton; + UINT cRadioButtons; + const TASKDIALOG_BUTTON *pRadioButtons; + int nDefaultRadioButton; + PCWSTR pszVerificationText; + PCWSTR pszExpandedInformation; + PCWSTR pszExpandedControlText; + PCWSTR pszCollapsedControlText; + union + { + HICON hFooterIcon; + PCWSTR pszFooterIcon; + }; + PCWSTR pszFooter; + PFTASKDIALOGCALLBACK pfCallback; + LONG_PTR lpCallbackData; + UINT cxWidth; + } + ;// ////////////////////////////////////////////////////// + + #ifdef _WIN32 + #include + #endif // _WIN32 + +// +// /// _WIN32_WINNT < 0x0600 && !defined(TD_WARNING_ICON) +///////////////////////////////////////////////////////////////////////// +#endif diff --git a/TaskDialogEmu.h.TaskDialogConfig_X.incl b/TaskDialogEmu.h.TaskDialogConfig_X.incl new file mode 100644 index 0000000..b43572d --- /dev/null +++ b/TaskDialogEmu.h.TaskDialogConfig_X.incl @@ -0,0 +1,172 @@ +#if !defined(TASKDIALOGCONFIG_X_52DD9F63_F838_11D4_B292_444553540000) +#define TASKDIALOGCONFIG_X_52DD9F63_F838_11D4_B292_444553540000 + +/**Added by Erich Willems to support mixed pushnuttons(commandbuttons not only for common but also for cunstom pushbuttons*/ +struct TASKDIALOGCONFIG_X : public TASKDIALOGCONFIG +{ typedef TASKDIALOGCONFIG_X Tp; + typedef TASKDIALOGCONFIG TpCtx; + + UINT cbSize_X; + UINT SzPushButtons; //explicit pushbuttons also if command_link is set + const TASKDIALOG_BUTTON* PushButtons; + + + TASKDIALOGCONFIG_X() { + cbSize =sizeof(TASKDIALOGCONFIG); + hwndParent =0; + hInstance =0; + dwFlags =0; + dwCommonButtons =0; + pszWindowTitle =0; + hMainIcon =0; + pszMainInstruction =0; + pszContent =0; + cButtons =0; + pButtons =0; + nDefaultButton =0; + cRadioButtons =0; + pRadioButtons =0; + nDefaultRadioButton =0; + pszVerificationText =0; + pszExpandedInformation =0; + pszExpandedControlText =0; + pszCollapsedControlText =0; + hFooterIcon =0; + pszFooter =0; + pfCallback =0; + lpCallbackData =0; + cxWidth =0; + + cbSize_X =sizeof(TASKDIALOGCONFIG_X); + SzPushButtons =0; + PushButtons =0; + } + + TASKDIALOGCONFIG_X(const Tp& src) { + cbSize =(src.cbSize ); + hwndParent =(src.hwndParent ); + hInstance =(src.hInstance ); + dwFlags =(src.dwFlags ); + dwCommonButtons =(src.dwCommonButtons ); + pszWindowTitle =(src.pszWindowTitle ); + hMainIcon =(src.hMainIcon ); + pszMainInstruction =(src.pszMainInstruction ); + pszContent =(src.pszContent ); + cButtons =(src.cButtons ); + pButtons =(src.pButtons ); + nDefaultButton =(src.nDefaultButton ); + cRadioButtons =(src.cRadioButtons ); + pRadioButtons =(src.pRadioButtons ); + nDefaultRadioButton =(src.nDefaultRadioButton ); + pszVerificationText =(src.pszVerificationText ); + pszExpandedInformation =(src.pszExpandedInformation ); + pszExpandedControlText =(src.pszExpandedControlText ); + pszCollapsedControlText =(src.pszCollapsedControlText); + hFooterIcon =(src.hFooterIcon ); + pszFooter =(src.pszFooter ); + pfCallback =(src.pfCallback ); + lpCallbackData =(src.lpCallbackData ); + cxWidth =(src.cxWidth ); + + cbSize_X =(src.cbSize_X ); + SzPushButtons =(src.SzPushButtons ); + PushButtons =(src.PushButtons ); + }; + TASKDIALOGCONFIG_X(const TpCtx& src){ + cbSize =(src.cbSize ); + hwndParent =(src.hwndParent ); + hInstance =(src.hInstance ); + dwFlags =(src.dwFlags ); + dwCommonButtons =(src.dwCommonButtons ); + pszWindowTitle =(src.pszWindowTitle ); + hMainIcon =(src.hMainIcon ); + pszMainInstruction =(src.pszMainInstruction ); + pszContent =(src.pszContent ); + cButtons =(src.cButtons ); + pButtons =(src.pButtons ); + nDefaultButton =(src.nDefaultButton ); + cRadioButtons =(src.cRadioButtons ); + pRadioButtons =(src.pRadioButtons ); + nDefaultRadioButton =(src.nDefaultRadioButton ); + pszVerificationText =(src.pszVerificationText ); + pszExpandedInformation =(src.pszExpandedInformation ); + pszExpandedControlText =(src.pszExpandedControlText ); + pszCollapsedControlText =(src.pszCollapsedControlText); + hFooterIcon =(src.hFooterIcon ); + pszFooter =(src.pszFooter ); + pfCallback =(src.pfCallback ); + lpCallbackData =(src.lpCallbackData ); + cxWidth =(src.cxWidth ); + + cbSize_X =(sizeof(Tp) ); + SzPushButtons =(0 ); + PushButtons =(NULL ); + }; + + Tp& operator=(const Tp& src) { + cbSize =(src.cbSize ); + hwndParent =(src.hwndParent ); + hInstance =(src.hInstance ); + dwFlags =(src.dwFlags ); + dwCommonButtons =(src.dwCommonButtons ); + pszWindowTitle =(src.pszWindowTitle ); + hMainIcon =(src.hMainIcon ); + pszMainInstruction =(src.pszMainInstruction ); + pszContent =(src.pszContent ); + cButtons =(src.cButtons ); + pButtons =(src.pButtons ); + nDefaultButton =(src.nDefaultButton ); + cRadioButtons =(src.cRadioButtons ); + pRadioButtons =(src.pRadioButtons ); + nDefaultRadioButton =(src.nDefaultRadioButton ); + pszVerificationText =(src.pszVerificationText ); + pszExpandedInformation =(src.pszExpandedInformation ); + pszExpandedControlText =(src.pszExpandedControlText ); + pszCollapsedControlText =(src.pszCollapsedControlText); + hFooterIcon =(src.hFooterIcon ); + pszFooter =(src.pszFooter ); + pfCallback =(src.pfCallback ); + lpCallbackData =(src.lpCallbackData ); + cxWidth =(src.cxWidth ); + + cbSize_X =(src.cbSize_X ); + SzPushButtons =(src.SzPushButtons ); + PushButtons =(src.PushButtons ); + return *this; + }; + Tp& operator=(const TpCtx& src) { + cbSize =(src.cbSize ); + hwndParent =(src.hwndParent ); + hInstance =(src.hInstance ); + dwFlags =(src.dwFlags ); + dwCommonButtons =(src.dwCommonButtons ); + pszWindowTitle =(src.pszWindowTitle ); + hMainIcon =(src.hMainIcon ); + pszMainInstruction =(src.pszMainInstruction ); + pszContent =(src.pszContent ); + cButtons =(src.cButtons ); + pButtons =(src.pButtons ); + nDefaultButton =(src.nDefaultButton ); + cRadioButtons =(src.cRadioButtons ); + pRadioButtons =(src.pRadioButtons ); + nDefaultRadioButton =(src.nDefaultRadioButton ); + pszVerificationText =(src.pszVerificationText ); + pszExpandedInformation =(src.pszExpandedInformation ); + pszExpandedControlText =(src.pszExpandedControlText ); + pszCollapsedControlText =(src.pszCollapsedControlText); + hFooterIcon =(src.hFooterIcon ); + pszFooter =(src.pszFooter ); + pfCallback =(src.pfCallback ); + lpCallbackData =(src.lpCallbackData ); + cxWidth =(src.cxWidth ); + + cbSize_X =(sizeof(Tp) ); + SzPushButtons =(0 ); + PushButtons =(NULL ); + return *this; + }; +}; + + + +#endif // !defined(TASKDIALOGCONFIG_X_52DD9F63_F838_11D4_B292_444553540000) diff --git a/TaskDialogEmu.h.WTLPreBaseUnitsHelper.incl b/TaskDialogEmu.h.WTLPreBaseUnitsHelper.incl new file mode 100644 index 0000000..2486efd --- /dev/null +++ b/TaskDialogEmu.h.WTLPreBaseUnitsHelper.incl @@ -0,0 +1,140 @@ +///////////////////////////////////////////////////////////////////////// +// CDialogBaseUnits - Dialog helper +// + +#if _WTL_VER < 0x0810 + class CDialogBaseUnits + { + public: + SIZE m_sizeUnits; + + // Constructors + + CDialogBaseUnits() + { + // The base units of the out-dated System Font + LONG nDlgBaseUnits= ::GetDialogBaseUnits(); + m_sizeUnits.cx = LOWORD(nDlgBaseUnits); + m_sizeUnits.cy = HIWORD(nDlgBaseUnits); + } + + CDialogBaseUnits(HWND hWnd) + { + m_sizeUnits.cx = 0; + m_sizeUnits.cy = 0; + InitDialogBaseUnits(hWnd); + } + + CDialogBaseUnits(HFONT hFont, HWND hWnd = NULL) + { + m_sizeUnits.cx = 0; + m_sizeUnits.cy = 0; + InitDialogBaseUnits(hFont, hWnd); + } + + CDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL) + { + m_sizeUnits.cx = 0; + m_sizeUnits.cy = 0; + InitDialogBaseUnits(lf, hWnd); + } + + // Operations + + BOOL InitDialogBaseUnits(HWND hWnd) + { + ATLASSERT(::IsWindow(hWnd)); + RECT rc = { 0, 0, 4, 8 }; + if( !::MapDialogRect(hWnd, &rc) ) return FALSE; + m_sizeUnits.cx = rc.right; + m_sizeUnits.cy = rc.bottom; + return TRUE; + } + + BOOL InitDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL) + { + CFont font; + font.CreateFontIndirect(&lf); + if( font.IsNull() ) return FALSE; + return InitDialogBaseUnits(font, hWnd); + } + + BOOL InitDialogBaseUnits(HFONT hFont, HWND hWnd = NULL) + { AE_(hFont != NULL); + + CWindowDC dc = hWnd; + HFONT hFontOld = dc.SelectFont(hFont); + TEXTMETRIC tmText = { 0 }; + dc.GetTextMetrics(&tmText); + + m_sizeUnits.cy = tmText.tmHeight + tmText.tmExternalLeading; + SIZE sizeText = { 0 }; + dc.GetTextExtent(_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &sizeText); + m_sizeUnits.cx = (sizeText.cx + 26) / 52; + dc.SelectFont(hFontOld); + + return TRUE; + } + + SIZE GetDialogBaseUnits() const + { + return m_sizeUnits; + } + + INT MapDialogPixelsX(INT x) const + { + return MulDiv(x, 4, m_sizeUnits.cx); // Pixels X to DLU + } + + INT MapDialogPixelsY(INT y) const + { + return MulDiv(y, 8, m_sizeUnits.cy); // Pixels Y to DLU + } + + POINT MapDialogPixels(POINT pt) const + { + POINT out = { MapDialogPixelsX(pt.x), MapDialogPixelsY(pt.y) }; + return out; + } + + SIZE MapDialogPixels(SIZE input) const + { + SIZE out = { MapDialogPixelsX(input.cx), MapDialogPixelsY(input.cy) }; + return out; + } + + RECT MapDialogPixels(RECT input) const + { + RECT out = { MapDialogPixelsX(input.left), MapDialogPixelsY(input.top), MapDialogPixelsX(input.right), MapDialogPixelsY(input.bottom) }; + return out; + } + + INT MapDialogUnitsX(INT x) const + { + return MulDiv(x, m_sizeUnits.cx, 4); // DLU to Pixels X + } + + INT MapDialogUnitsY(INT y) const + { + return MulDiv(y, m_sizeUnits.cy, 8); // DLU to Pixels Y + } + + POINT MapDialogUnits(POINT pt) const + { + POINT out = { MapDialogUnitsX(pt.x), MapDialogUnitsY(pt.y) }; + return out; + } + + SIZE MapDialogUnits(SIZE input) const + { + SIZE out = { MapDialogUnitsX(input.cx), MapDialogUnitsY(input.cy) }; + return out; + } + + RECT MapDialogUnits(RECT input) const + { + RECT out = { MapDialogUnitsX(input.left), MapDialogUnitsY(input.top), MapDialogUnitsX(input.right), MapDialogUnitsY(input.bottom) }; + return out; + } + }; +#endif // _WTL_VER diff --git a/TaskDialogEmu.h.WinXPDeclarations.incl b/TaskDialogEmu.h.WinXPDeclarations.incl new file mode 100644 index 0000000..3bbb098 --- /dev/null +++ b/TaskDialogEmu.h.WinXPDeclarations.incl @@ -0,0 +1,59 @@ +#if _WIN32_WINNT < 0x0501 //WinXP +///////////////////////////////////////////////////////////////////////// +// /// _WIN32_WINNT < 0x0501 +// + + #ifdef _WIN32 + #include + #endif // _WIN32 + + #define MAX_LINKID_TEXT 48 + #define L_MAX_URL_LENGTH (2048 + 32 + sizeof("://")) + + typedef struct tagLITEM + { + UINT mask; + int iLink; + UINT state; + UINT stateMask; + WCHAR szID[MAX_LINKID_TEXT]; + WCHAR szUrl[L_MAX_URL_LENGTH]; + } LITEM + ,*PLITEM + ; // ////////////////////////////////////////////////////// + + typedef struct tagNMLINK + { + NMHDR hdr; + LITEM item; + } NMLINK + ,*PNMLINK + ; // ////////////////////////////////////////////////////// + + class CLinkCtrl + { + public: + static LPCTSTR GetWndClassName() {return _T("SysLink");} + };// ////////////////////////////////////////////////////// + + #define BCM_FIRST 0x1600 // Button control messages + #define BCM_SETIMAGELIST (BCM_FIRST + 0x0002) + + typedef struct + { + HIMAGELIST himl; + RECT margin; + UINT uAlign; + } BUTTON_IMAGELIST + ,*PBUTTON_IMAGELIST + ; // ////////////////////////////////////////////////////// + + + #ifdef _WIN32 + #include + #endif // _WIN32 + +// +// ///END: _WIN32_WINNT < 0x0501 +///////////////////////////////////////////////////////////////////////// +#endif diff --git a/res/Error.png b/res/Error.png new file mode 100644 index 0000000000000000000000000000000000000000..04ae4f758df5afc73276b34fb3c9a472b80a6fb0 GIT binary patch literal 2423 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 vVT{s%a@~-tRI_s3wH+Qq5S0K%pge5V zzbar*kyyeb(FBc3i9~1w8U#U$7#pOeBtD`TAu%vKEH5okXaQ-VQ`(u%blOgD@66nL z=ic)^doTaErBv)#T20)^%04GKdwswC?W~i%2q!pJ+f0uvA>Ra^>y*{{&#g&9}^)J7><79Ua}@OZ;H| zRR3RiVN0`|ea0EEG8sI6!4wXJ2QV}-1T|pkYkHQG4&%X{yLR5Uckk#QSFO6Md|Uvx z-?p-&wYBwvT(0R1FwQ%ZhiJj6y`rnP7b=s1uGjJB^CmGFPofl+ zFjgBwbyw9aPG8KQpTCsSb~@a?{k>O%Ab6#Cu()+{a^m?r?)dTev;a5UaHIOd(l6}@ zyr9S1H)?pi1TlUPnR-o}+|xrH3l<>P-3?L-x?V?8so=5Cl~GA5D92@#<1#8?1=Yza z;$m!i?Nhn0r4I{R7NM`uCx&(n?Retx$4|fiXZPt3G}Vy+Gn$&Z(&_BH;vasm3zB4W zp@62-PeW5j2U4xA5RL=Z8rpS{cpehpN1y|QIzXf&Xstm+u$yg&CLwl)?_;MK z2D6M~nRp(;N(DkGfCylQNfMYSg7JMMz7Oqr@L~_X_Tg(Ek%^#LLz09b0RRnf!|>P> z%*^?GK0PgfF`5CuXiZVA1}Ftms^Ne!V69=|2-@?J)a%fmhjJ7lF$oMC5C{%Au!IFg z3IsxELd1wcAkxOL)*90SOqR>_*0wH+wb4 z01i1LAW6a|8!3^3BON%xff5RghW!c(&8nG$Fn}?pG%dj1y?aN_Ip=&f*&HI*g-#Nf zB!LbBfEjEIhzKMENJ@}W5Uk(`2WgQ;N~VyOX*kk>MHVz`#1uoYK)clr*Y&tksqC2+ zz;(R|&+`saTU%Q=GzhBIprh#U5r7CnsYVC^DJ2|gh-YL5Y1x=lG6g9l5|f}#b-)0H zQ~{%-qopKCrvDQHz$5D(?H?JHmp=V$N`|2T(TATYMQ|L6R7xU~R>))&?z!=92$h3S zGY-u;kjwxi!P-OY?nX5AE~@Ek^_KVZe_g)(nk7f-iH`yVLGV)Vq88Na6$T8L4VX0m z4Ivm(GAspHHefphAO%nc5E(#b0ht5I97trqEMRnm!1o}sXJcYw;^mL({Tsl@$ncYM z=X8jUlS0F605swQaisud0hUFuZGg!EC=G}VNMu1G*MK1lMkh!j7xiS8Hk22`!^2M= z6JUJ2^lq_u;NA1ioe6LZ9D)$UkfISvqTzxffE<7v5T!sO4H793*^SDHYe<3$xM?xA zZri%ub?aM?3GndRht1&N&WD#=_6c(ADP!9WF)0rL$V1PEAOIU6`!EQ|1~Vgx>WIB@ zRI4>3n=hk*fq}K_*RM0j1OR~H;oXVeqx+b5uk;^GK4nZj#c0x#i zS%4wI5HQ9-#~vcDh_E(-a(T*N<}!Ny^-cG#S@X-I-kOgJ006sp?|xunqWJz5m(S)I zO^lWn8#9`$!w`ZPLNJ&K#sEeq&`}+cS42=5f;%~cr1hKp-j3m&#o~bnrqh}BR=jD` zYe{Ek=UZ1^@x`l0_Us`kbHZ^1q$Eg1uxtU#68O~oZH<~Y33OORSla`?vI}K%rjBw; z%!UomUHQ;MYjzzs003;<`1jF{j!yUb>y|Cqyk$Gjn9)p@B_JiBlz@_ivwGeEn*>Q% zMO5F1pt>6qe!G!{?}(@R`+u~0_5Hv3Pa4PU3+Bz6ziDb}s_h$BFa6AxEd$)zGLtMz z0$?yR`U-DAM>Ry=L4>t^nDE<;ns+O`@Z!sB$HvBPdHd}*`M(0#vSl-RdwZWPl}hbb ze|_nv2L=XBHk%dMY@^(IJKt=azh+c$y0&J2TfFe%%j<`R25)@y(RKP*`9D@?v~lA` z?(Uw|KQuJxEnBwuq9CZFTJ=yUv{6r26*V_8Zt6mlG+oF~Kl98TV`F3AU%&p?;=l>? zhBw{x-SZb;e979Lx$_qc3>3LAa}dZZpdC9$MmBGLaefy3`m$rPBBd`}gnr#kzIBuAfN0|LgcC7^M>VS>)W&00000NkvXXu0mjft7zzK literal 0 HcmV?d00001 diff --git a/res/ShieldError.png b/res/ShieldError.png new file mode 100644 index 0000000000000000000000000000000000000000..5798ec0ad8eb26208ba3b11a715178f925ae0db1 GIT binary patch literal 2454 zcmV;H32F9;P)B|L2_Bw{LGu&&CWeOAjhAFf6i&7|lc@3W$`- z7AmDijY+EVm^|bqFYzTWRvz+@m!Nq_l@{evE;ynL${0z-2sn(xG}6;O`%LfCbNlZ1 zoRfzJ6j_AIsXA5n;oR^4`|kIh`+Xn5ZLWAcjwhdZ63vSj$J&;)-A^f1W@l$VE685Gc+|ey|8xe-LGa(_J{egqtZKfRvMfKS8n^!-fS*AvvTFCv!!AY zg+k%~2Oxx?rKJUrY<~m~J@`|tE7A3*6)U>`JoEMuvRq$aE4sVsvc=6*9ZS?~51iikY)u)O2ZokR_3&dA8fzirz-mCa>`O2y)d z!E=L!ci(;Iil*{ifVQ@FW#h)pr)T`sv3uIMS7j1d;QN)%m1yL06 zY8BjZz+D%@_aOmjnufb4&QbJf3l~T%hJRS-LwQB){ z5a66k01%uLSJ!LaT=K|iZ%3lH7X-kxqQH9ZJqW`9cU^d#13PwL{hmFLQey1zVTkkR zYv7Ipcpg9q;X+8?_aTJ%_Ud1Lux%UVa=A(=C7ux6(RDcGGMrKgcBuqz+qD==iI#ir z0e#>BIF18{b71FAtl6^%j4?3Apd}Ju(I{9n3K9+jfdGW63MnMX=ktbTS=W96+qS_u zF9cN;A`pP9>kyoSFa{|E{QiDiq!i0{?*^q5o!hq~BLqy(!tcF(YJBU~`=p3O;Ti_G??d=LxNQSc!g}pBT(E7d z*t-{uF)ZJ)10V#H5J&*UWD?b5$3O!CkZ>51a}dviq!fYXW*AjN&R6CqZ2LL@Qc4(x zQM4>GN1B?OoOB9A*TG#EAOw&SAOzm)uj2xM?tS|}DZP^MrDPKNM<0O(0$`d3${2+2 z1Jx=70IjVZlT%Z9&+`hd>t34!0ALsf&*gJx)uqc|R;#cp6?nD{&$8gzHn``(lM>b? zn9G|G0#DaL6a_32xw46>LJ|VbIkc`WjE;_;H4KAGDX$NZ&ZObk*2((rHJGnfB?rKz z1eX#5fX^6$`}SeOCGUY+F(HIt>DH}?_4a~AB2dC%P)!3E1NS^wmW62dY7`2EfmAB> zUCFBf#>U1lK0bc5HIblBOREria5IxT$PzY5@*j;K{-A5MZ>l=rI4poQ6LKilqM#i z&&;6M*9S-mrfE<@At<2`gs#K$eK@5O%v1`->?|td<51T0i1}z;WoT&dxq*R`wrLtS z2XGt*4fXX-Fc>8F?|I_k^uGpVBorc4QQ+lru*b$gC)hO#=&sz=A;t(}Y_r z!YmX}86QV6mlLgreoj6aIQdd4b@BLDU!D2B-1U3Hd_IpvXX12QXXpM!9UTqs^jGIPRIId20ZU z<3I@R3&GFs+JErr$%zRPWsI_5um+(hHHbg}OjSV`gWw#lu0x-jLuFzDej>pmTkaM8 z{l^as4}YDya3Og;sT+62*=!bVZS9lUT+Vpv#b56jIsIQ5U$ltOKmdfXDkNMQp)DM}zwb9Hl41Dv=1;k>pQ^UiFKhUv$Lt~*(6gE?2 zbnON*R<2B(IC1>Y?A+`teSJq|HhXi=FR$AgP8nlZyLKHmZrl`VZC&!)B}Z2??f(P#{vot>zQ$3Y2&uIreZnn1Bwylq?m0~qWJ U`C_f?{{R3007*qoM6N<$f}s9^7ytkO literal 0 HcmV?d00001 diff --git a/res/ShieldOK.png b/res/ShieldOK.png new file mode 100644 index 0000000000000000000000000000000000000000..38a80926009878955918fab778eb6a7c64fb1caa GIT binary patch literal 2477 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 literal 0 HcmV?d00001 diff --git a/res/TaskDlgArrowHot.ico b/res/TaskDlgArrowHot.ico new file mode 100644 index 0000000000000000000000000000000000000000..15840c054eb20e09964ae99b207f229b949c62ea GIT binary patch literal 2902 zcmeHHOHWf<6#meAm7r*ps$B0?s~|Bk;vm0+S{r#E}z> zBNGNhd@zt3($E0mc>xU|uK?v)NOURnM}UXqT@xN3+0!T|>+K)gTf!@vdPO3U)Q2fgs1*u@eA_D!2yAU_ zr4&s(pkgo>TwhSWoaB3BVg??7?(QBP9i^$C zsym&|rKKgMPLCZO9c^uGv@kL1&Ns}9!i0>9+3WRA zPfyd%gT4njmYf*rE&8mMEWC#z)Bh$dpiN9ntgNiWE}9m2p{xegxtItG&R{$tPtk`W zyaLJ8Vbc8C*w`3voTn^N?3$P|Yehb5NEG$=_j`Pvd++YyIY_4eekd~9ctvG_90s6r zr>V-8N|-@1z5R(|EC3Zhb)U98)j!iee*M@V@G~BkXitwZMSjpbOF?u|Ql-ytR)cLA zFP7??Dpco1u%wHNi@Zt&gH-an`3zpI-Idub{A-+q;q@DS66a+4wnbao-iGt@^HESx zfWpE;6c-nxq@)C;rKPB-s6bU!6{@SN<+24S0<&$H3SfDUAa+3@LqI6~Agv?aCrv0# zEOS7bN_txG#)}u!2;?9zA{@YW5bT1$hl~z3BshCeTU(3z`g$}pG@!Au5lu}^uvjc$ z+k(w0{VgLxrVKc!z>x)Z9SCp?3=Cj!a1g`8!x$eQ$IQ$Oq-!}JKq!Fl0Z{>>0jsO4 zU}u4o4)%Z@9*+lZ%?(15y literal 0 HcmV?d00001 diff --git a/res/TaskDlgArrowNormal.ico b/res/TaskDlgArrowNormal.ico new file mode 100644 index 0000000000000000000000000000000000000000..9aa79f847bbe4aa33845487e6d014f941be7d47c GIT binary patch literal 2902 zcmeHHNl#Nz6#j64$^s;S;7AoDBrL27gc!gkG;V4nO}a3!k`1t7!Nwne3lP(lXhM+0 zg$qImCM?_l0f8_}F(FI|w2Wnbl=hV}w0@U|SjuDqOK#4a&O7Ixd%p9X0|ej_A|k*Q zjfAT}Jl~XW6;y%1E9w%2j+b}_&`zxHS9TuN9Sy?&NeQ9ZF zW@d(#bZ6YQwzlTxX6`_Dp5!=pMr4AMlap&}YgOK=TyJirx03d)t*s}!Ge=@#v)Ouj zdKMQKvp2ILgJN=w9hMqD_y9$W^+t!wF)}hjJQYWtnJ-M1XwaRDxUo_^jD5qN`Y{!6K{0+aI%LPt z&=5JszrF-x%5!sb)Dxx7&Q7Ae?p)7&pNTi17(XBDsBA*Cc>pDMZdFiTfR~^cON~yK z^T>$4(UtR)kn}AoFH*l&=e*02T`~(tviTj=&yk->t%(MaWbR}db0HdhIc$7bLl>5B zdU|?zc$nqjJJCCAcAQ4Zo#}J&{W!BT>JJRBbNDzoCsn&US^|#VSfkM(IXM|ADJe)# zPe(>ZhA6IJhM*N#FKD$|-5R@V{AVvop5}Z9KEiFY^Ss5xSDo|ZrjhdPo)YjIbv9S?N zO-*3?f=w#=T#O1aZNPyAjxMnKz-d^km#~i0ONMR4VnpYS&tSJ1FR$pXxzi;GKgi=wq+l^-}?QgJJI&XMA|Q l5_~Vua|zoqyh0^-f+ScjOK1+@1?4HegJQ3fnPVC7n1*Bz>=Qx)d} jcMo};nlvzJZ8ocx-n%^)F_MUM%E(ccpHIJlf8bSabUu~3 literal 0 HcmV?d00001 diff --git a/res/TaskDlgChevronMore.ico b/res/TaskDlgChevronMore.ico new file mode 100644 index 0000000000000000000000000000000000000000..bce2ec9d677babdd3822ba26952eaa587091ca96 GIT binary patch literal 766 zcmc&v$qj%o3^RxU`r_RuV=!7q>o`2SL9u&C6)z5nrgiKjijn{mpZAV_!7&3XfQ|6P zPAD%k)|$B{G8>B&W`*b}5kerVkn%@LQUsq;ivPFB6|&XQ@dc}=?|T;K4Le-P$i0@_Cq2OMNvM43R;2EHc68-s#y$}MIm5pETHg8f^owV zAl_!~(hu*&g;H8DAy@j(ojK>+bN>3zopVR<5aapHn=62TF=pS3FTJEklfxQq@y*XY z_nI;0pfRQm*frWb_GlJudghs`^z`&spLqOn5e|pB+}m3;v$(jk{lJ0l2hBAq1*DWO zFIl`ubam~gr#a;@)U9FEg}>n3w%&nnPb z|LBntShsGS-x#yCuC|8ueLJXMP|m{o1sv(vPE}B>Sa{0L$5 zX;(kD2FCN*xj!?jcm`v~j$OZ^xw-HgBj9=7ua`A0@}D?yn9>;vpW~pEx&v2lKz(%z z9fv-map@wT>v>zh5d!rK7F18p&G}xz)O;d6f1vC;lL-3Uy9lHtK*8j3^k4ayNx9if z%E?~2u%V&)p$Jr0RS7BO%imqGTpVowkcH*(1Z|hBG=-G%4&;Ocjv1n93(L)35|6}2xMoZ5YHu$gV=hI z<@3`xw09>fnwO!q-da&!e$N(tZv}*CZD^Q3S!>Oh;Wj2u2!b~N-T=ZIAU{(gJrC)5 z_QBm<MgWZFaz&mG3|JPNa1v^N;_xdUjopQND2wA2&)v+pvEOBYQLf=%~DpuD_1 zKNL#eIKQ@rPxigZf|4;PZwToQBRv=CNu(zUrC2y(0H0%#7T-T&kH!q6+##xG#?#&L z7K<0wlbDdWsj{*n^nVEm*t&MjD*x&3lgu1{lB76=mM&UJv{Er>1Q1G=q@~8A-Ro$j zV^C7k53X^@&|tkNhYnKRYT`D1TTRb5GDM#hHPnwo;!Yu<4fSo&*<$@7lz!<=2&<3LwHj;qpqpL56 zlG1X!Q+}(R#s$WX7c&*ZOoWtqqRY6&|094g)uf72aUtwu0fuE z^)k=?<{Sq*-4VMnHriNdBhVU@HWW;>={>oP=`*HLR9Mi`&`@7_hXM@^4St``x4ZS} zr&2ri{)w`b4@e*D2N3|_2jPp&QJjvrJoU;KobNS6`V=1>8=`D_3hBvqR0R!ajnNvT z6heC>J6AXwNuzebQn7zud*R>DpMP^i0o%4WE?K-VFBk}Lqvv&ULpI7dx50)oZ&6!t1ecj?x+F_#8$~LajA(rsseihq2;f zu>rL3q48ma4`DgfPVHmQ2isY_`Y~+F+S;^inPV4Bo%*YlEh`s~8<)z3wx2RLPa~Wl zSbl`?fpDUTZAOD2H91K2tW<_|9NAeRTAwJTYU)>LH4I8(loy4LK}n33#QP