2848 lines
148 KiB
C++
2848 lines
148 KiB
C++
#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<const DERIVED*>(this) ///<In context of template virtualization. Declares the method-local dThis pointer
|
|
#endif
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// TaskDialogEmu dialog implementation
|
|
//
|
|
|
|
|
|
void aligneByBaseUnitsSlope(LONG& what,double unitPre, double unitNow,int sign=1)
|
|
{//*if(unitPre == unitNow) */ return;
|
|
if(true) return;//as pragma warning disable will not work on unreachable code
|
|
|
|
double f =unitPre/unitNow;
|
|
double lns =what/unitNow;
|
|
if(f>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<DERIVED>, public CDialogBaseUnits
|
|
#else
|
|
class CTask98DialogImpl : public CIndirectDialogImpl<DERIVED>, public WTL::CDialogBaseUnits
|
|
#endif
|
|
{
|
|
public: typedef CTask98DialogImpl Tp;
|
|
typedef CIndirectDialogImpl<DERIVED> 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"));
|
|
LOGVALDWD(_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<HFONT>(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.top<clientDlu.bottom;)
|
|
{
|
|
l.bottom=l.top+1;
|
|
l.left=0;l.right =rcClient.right;
|
|
PixRect pil;pil=l;
|
|
dc.FillSolidRect(&pil, clrGrid);
|
|
|
|
DLURect trc;trc.left=0;
|
|
trc.right =l.right;
|
|
trc.top=l.top;
|
|
trc.bottom=trc.top+1;
|
|
// _AlignDLU(trc.bottom, HTBOTTOM);
|
|
PixRect pitrc;pitrc=trc;
|
|
dc.DrawText(n, 1, &pitrc, DT_WORDBREAK);
|
|
trc.left=l.right -basU.cx;
|
|
pitrc=trc;
|
|
// _AlignDLU(trc.left, HTRIGHT);
|
|
dc.DrawText(n, 1, &pitrc, DT_WORDBREAK);
|
|
|
|
if(z>0xf)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.left<rcClient.right;)
|
|
{
|
|
l.right=l.left+1;
|
|
l.top=0;l.bottom =rcClient.bottom;
|
|
pil=l;
|
|
dc.FillSolidRect(&pil, clrGrid);
|
|
|
|
RECT trc;trc.top=0;
|
|
trc.bottom =l.bottom;
|
|
trc.left=l.left;
|
|
trc.right=trc.left+1;
|
|
pitrc=trc;
|
|
//_AlignDLU(trc.right, HTRIGHT);
|
|
dc.DrawText(n, 1, &pitrc, DT_WORDBREAK);
|
|
trc.top=l.bottom -8;
|
|
//_AlignDLU(trc.top, HTBOTTOM);
|
|
dc.DrawText(n, 1, &pitrc, DT_WORDBREAK);
|
|
|
|
if(z>0xf)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<HBRUSH>(m_brWhite);
|
|
break;
|
|
}
|
|
case IDC_TASKDLG_INSTRUCTIONSTEXT: {dc.SetBkMode(TRANSPARENT);
|
|
dc.SetTextColor(m_Metrics.clrTitleText);
|
|
dc.SetBkColor(m_Metrics.clrBkTop);
|
|
lRes = (LRESULT) static_cast<HBRUSH>(m_brWhite);
|
|
break;
|
|
}
|
|
case IDC_TASKDLG_CONTENTTEXT: {dc.SetBkMode(TRANSPARENT);
|
|
dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT));
|
|
dc.SetBkColor(m_Metrics.clrBkTop);
|
|
lRes = (LRESULT) static_cast<HBRUSH>(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<HBRUSH>(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<HBRUSH>(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<HBRUSH>(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<HBRUSH>(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<HBRUSH>(m_brWhite);
|
|
}
|
|
else{
|
|
clrBack = m_Metrics.clrBkBottom;
|
|
lRes = (LRESULT) static_cast<HBRUSH>(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<LPCWSTR>(('\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<CTask98Dialog>
|
|
{
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// 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_)
|
|
|