commit 733fadd44d1d58c1e1707d06b9cbe6b223c301a6 Author: Erich Willems Date: Thu Jul 18 23:23:31 2019 +0200 fill 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 0000000..04ae4f7 Binary files /dev/null and b/res/Error.png differ diff --git a/res/Information.png b/res/Information.png new file mode 100644 index 0000000..5e5e03f Binary files /dev/null and b/res/Information.png differ diff --git a/res/Question.png b/res/Question.png new file mode 100644 index 0000000..9e04bfe Binary files /dev/null and b/res/Question.png differ diff --git a/res/Shield.png b/res/Shield.png new file mode 100644 index 0000000..857136e Binary files /dev/null and b/res/Shield.png differ diff --git a/res/ShieldError.png b/res/ShieldError.png new file mode 100644 index 0000000..5798ec0 Binary files /dev/null and b/res/ShieldError.png differ diff --git a/res/ShieldOK.png b/res/ShieldOK.png new file mode 100644 index 0000000..38a8092 Binary files /dev/null and b/res/ShieldOK.png differ diff --git a/res/ShieldQuestion.png b/res/ShieldQuestion.png new file mode 100644 index 0000000..53307e0 Binary files /dev/null and b/res/ShieldQuestion.png differ diff --git a/res/ShieldWarning.png b/res/ShieldWarning.png new file mode 100644 index 0000000..2bc61f8 Binary files /dev/null and b/res/ShieldWarning.png differ diff --git a/res/TaskDlgArrowHot.ico b/res/TaskDlgArrowHot.ico new file mode 100644 index 0000000..15840c0 Binary files /dev/null and b/res/TaskDlgArrowHot.ico differ diff --git a/res/TaskDlgArrowNormal.ico b/res/TaskDlgArrowNormal.ico new file mode 100644 index 0000000..9aa79f8 Binary files /dev/null and b/res/TaskDlgArrowNormal.ico differ diff --git a/res/TaskDlgChevronLess.ico b/res/TaskDlgChevronLess.ico new file mode 100644 index 0000000..737faed Binary files /dev/null and b/res/TaskDlgChevronLess.ico differ diff --git a/res/TaskDlgChevronMore.ico b/res/TaskDlgChevronMore.ico new file mode 100644 index 0000000..bce2ec9 Binary files /dev/null and b/res/TaskDlgChevronMore.ico differ diff --git a/res/Warning.png b/res/Warning.png new file mode 100644 index 0000000..ee2a354 Binary files /dev/null and b/res/Warning.png differ