#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_)