XTPTaskDialogClient.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:51k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPTaskDialogClient.cpp: implementation of the CXTPTaskDialogClient class.
  2. //
  3. // This file is a part of the XTREME CONTROLS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPImageManager.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPSystemHelpers.h"
  25. #include "Common/XTPResourceManager.h"
  26. #include "Common/XTPMarkupRender.h"
  27. #include "Controls/XTThemeManager.h"
  28. #include "Controls/XTButtonTheme.h"
  29. #include "Controls/XTButton.h"
  30. #ifdef _XTP_INCLUDE_MARKUP
  31. #include "Markup/XTPMarkupContext.h"
  32. #include "Markup/XTPMarkupInline.h"
  33. #endif
  34. #include "XTPTaskDialogAPI.h"
  35. #include "XTPTaskDialogClient.h"
  36. #ifdef _DEBUG
  37. #define new DEBUG_NEW
  38. #undef THIS_FILE
  39. static char THIS_FILE[] = __FILE__;
  40. #endif
  41. //---------------------------------------------------------------------------
  42. // dialog units used for dynamic layout.
  43. //---------------------------------------------------------------------------
  44. enum XTPDluMetrics
  45. {
  46. xtpDluMinClient        = 180, // minimum client width.
  47. xtpDluMaxClient        = 265, // maximum client width when using command links.
  48. xtpDluMaxVerify        = 146, // maximum width for verify and expando buttons.
  49. xtpDluPadding          = 2,   // padding used for button and content.
  50. xtpDluBtnSpacing       = 3,   // spacing between common buttons.
  51. xtpDluMargin           = 5,   // non-client margin.
  52. };
  53. #ifndef LAYOUT_BITMAPORIENTATIONPRESERVED
  54. #define LAYOUT_BITMAPORIENTATIONPRESERVED 0x00000008
  55. #endif
  56. CXTPTaskDialogClient::CStringMarkup::CStringMarkup()
  57. {
  58. m_pUIElement = NULL;
  59. m_pClient = NULL;
  60. }
  61. CXTPTaskDialogClient::CStringMarkup::~CStringMarkup()
  62. {
  63. XTPMarkupReleaseElement(m_pUIElement);
  64. }
  65. void CXTPTaskDialogClient::CStringMarkup::SetCaption(const CString& strCaption)
  66. {
  67. m_strCaption = strCaption;
  68. XTPMarkupReleaseElement(m_pUIElement);
  69. if (!m_strCaption.IsEmpty() && m_pClient && m_pClient->m_pMarkupContext)
  70. {
  71. m_pUIElement = XTPMarkupParseText(m_pClient->m_pMarkupContext, m_strCaption);
  72. }
  73. }
  74. void CXTPTaskDialogClient::CStringMarkup::SetFinalRect(const CRect& rcFinalRect)
  75. {
  76. m_rcFinalRect = rcFinalRect;
  77. }
  78. //===========================================================================
  79. // CXTPTaskDialogClient
  80. //===========================================================================
  81. CXTPTaskDialogClient::CXTPTaskDialogClient()
  82. : m_nSection(xtpNone)
  83. , m_nMaxClientWidth(0)
  84. , m_nMinClientWidth(0)
  85. , m_nPadding(2)
  86. , m_bExpanded(FALSE)
  87. , m_bVerification(FALSE)
  88. , m_bUseSysIcons(FALSE)
  89. , m_bThemeReady(FALSE)
  90. , m_hIconFooter(NULL)
  91. , m_hIconMain(NULL)
  92. , m_crContext(COLORREF_NULL)
  93. , m_crContextText(COLORREF_NULL)
  94. , m_crFooter(COLORREF_NULL)
  95. , m_crFooterText(COLORREF_NULL)
  96. , m_crMainText(COLORREF_NULL)
  97. , m_cr3DLight(COLORREF_NULL)
  98. , m_cr3DShadow(COLORREF_NULL)
  99. , m_cr3DHighLight(COLORREF_NULL)
  100. , m_ptMargin(0,0)
  101. , m_ptPadding(0,0)
  102. , m_ptBtnSpacing(0,0)
  103. , m_ptBorder(0,0)
  104. , m_pBtnVerify(NULL)
  105. , m_pBtnExpando(NULL)
  106. , m_pConfig(NULL)
  107. {
  108. m_rcMainInstruction.SetRectEmpty();
  109. m_rcContent.SetRectEmpty();
  110. m_rcCommandButtons.SetRectEmpty();
  111. m_rcFooter.SetRectEmpty();
  112. m_rcExpandedInformation.SetRectEmpty();
  113. m_rcLinkButtons.SetRectEmpty();
  114. m_rcRadioButtons.SetRectEmpty();
  115. m_sizeCommandButton = CSize(0, 0);
  116. m_sizeIconFooter = CSize(0, 0);
  117. m_sizeIconMain = CSize(0, 0);
  118. m_nSelRadioButtonID = 0;
  119. m_pMarkupContext = NULL;
  120. m_pIconLinkGlyph = NULL;
  121. m_bMessageBoxStyle = FALSE;
  122. m_strMainInstruction.m_pClient = this;
  123. m_strContent.m_pClient = this;
  124. m_strFooter.m_pClient = this;
  125. m_strVerificationText.m_pClient = this;
  126. m_strExpandedInformation.m_pClient = this;
  127. m_strExpandedControlText.m_pClient = this;
  128. m_strCollapsedControlText.m_pClient = this;
  129. m_bEnableMarkup = FALSE;
  130. }
  131. #define SAFE_DELETE_WINDOW(ptr) if (ptr) { ptr->DestroyWindow(); delete ptr; ptr = NULL; }
  132. void CXTPTaskDialogClient::DeleteControls()
  133. {
  134. SAFE_DELETE_WINDOW(m_pBtnVerify);
  135. SAFE_DELETE_WINDOW(m_pBtnExpando);
  136. CMDTARGET_RELEASE(m_pIconLinkGlyph);
  137. int i;
  138. for (i = 0; i < m_arrLinkButtons.GetSize(); ++i)
  139. {
  140. CButton* pButton = m_arrLinkButtons[i];
  141. SAFE_DELETE_WINDOW(pButton);
  142. }
  143. m_arrLinkButtons.RemoveAll();
  144. for (i = 0; i < m_arrRadioButtons.GetSize(); ++i)
  145. {
  146. CButton* pButton = m_arrRadioButtons[i];
  147. SAFE_DELETE_WINDOW(pButton);
  148. }
  149. m_arrRadioButtons.RemoveAll();
  150. for (i = 0; i < m_arrCommandButtons.GetSize(); ++i)
  151. {
  152. CButton* pButton = m_arrCommandButtons[i];
  153. SAFE_DELETE_WINDOW(pButton);
  154. }
  155. m_arrCommandButtons.RemoveAll();
  156. SAFE_DELETE_HICON(m_hIconFooter);
  157. SAFE_DELETE_HICON(m_hIconMain);
  158. CMDTARGET_RELEASE(m_pIconLinkGlyph);
  159. m_wndProgressBar.DestroyWindow();
  160. m_wndFooter.DestroyWindow();
  161. m_wndExpandedInformation.DestroyWindow();
  162. m_wndContent.DestroyWindow();
  163. m_strMainInstruction.SetCaption(_T(""));
  164. m_strContent.SetCaption(_T(""));
  165. m_strFooter.SetCaption(_T(""));
  166. m_strVerificationText.SetCaption(_T(""));
  167. m_strExpandedInformation.SetCaption(_T(""));
  168. m_strExpandedControlText.SetCaption(_T(""));
  169. m_strCollapsedControlText.SetCaption(_T(""));
  170. XTPMarkupReleaseContext(m_pMarkupContext);
  171. m_mapWndSize.RemoveAll();
  172. }
  173. CXTPTaskDialogClient::~CXTPTaskDialogClient()
  174. {
  175. DeleteControls();
  176. DestroyWindow();
  177. }
  178. BEGIN_MESSAGE_MAP(CXTPTaskDialogClient, CWnd)
  179. //{{AFX_MSG_MAP(CXTPTaskDialogClient)
  180. ON_WM_SETTINGCHANGE()
  181. ON_WM_SYSCOLORCHANGE()
  182. ON_WM_ERASEBKGND()
  183. ON_WM_PAINT()
  184. ON_WM_CTLCOLOR()
  185. //}}AFX_MSG_MAP
  186. END_MESSAGE_MAP()
  187. //---------------------------------------------------------------------------
  188. // CXTPTaskDialogClient message handlers
  189. //---------------------------------------------------------------------------
  190. void CXTPTaskDialogClient::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
  191. {
  192. CDialog::OnSettingChange(uFlags, lpszSection);
  193. RefreshMetrics();
  194. }
  195. void CXTPTaskDialogClient::OnSysColorChange()
  196. {
  197. CDialog::OnSysColorChange();
  198. RefreshColors();
  199. }
  200. BOOL CXTPTaskDialogClient::OnEraseBkgnd(CDC* pDC)
  201. {
  202. UNREFERENCED_PARAMETER(pDC);
  203. return TRUE;
  204. }
  205. void CXTPTaskDialogClient::OnPaint()
  206. {
  207. CPaintDC dc(this); // device context for painting
  208. CXTPBufferDC memDC(dc);
  209. CXTPClientRect rcClient(this);
  210. if (!memDC.GetSafeHdc())
  211. return;
  212. DrawBackground(&memDC, rcClient);
  213. memDC.SetBkMode(TRANSPARENT);
  214. DrawMainInstruction(&memDC);
  215. DrawContent(&memDC);
  216. DrawExpandedInfo(&memDC);
  217. DrawFootNote(&memDC);
  218. }
  219. HBRUSH CXTPTaskDialogClient::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
  220. {
  221. int i;
  222. for (i = 0; i < m_arrRadioButtons.GetSize(); i++)
  223. {
  224. if (m_arrRadioButtons[i] == pWnd)
  225. {
  226. pDC->SetBkColor(m_crContext);
  227. return GetSysColorBrush(m_bThemeReady ? COLOR_WINDOW : COLOR_3DFACE);
  228. }
  229. }
  230. for (i = 0; i < m_arrLinkButtons.GetSize(); i++)
  231. {
  232. if (m_arrLinkButtons[i] == pWnd)
  233. {
  234. pDC->SetBkColor(m_crContext);
  235. return GetSysColorBrush(m_bThemeReady ? COLOR_WINDOW : COLOR_3DFACE);
  236. }
  237. }
  238. return CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
  239. }
  240. HRESULT CXTPTaskDialogClient::SendNotify(UINT uNotify, WPARAM wParam /*=0*/, LPARAM lParam /*=0*/)
  241. {
  242. if (m_pConfig->pfCallback)
  243. {
  244. return m_pConfig->pfCallback(m_hWnd, uNotify,
  245. wParam, lParam, m_pConfig->lpCallbackData);
  246. }
  247. return E_FAIL;
  248. }
  249. BOOL CXTPTaskDialogClient::CanCancel() const
  250. {
  251. if (GetDlgItem(IDCANCEL))
  252. return TRUE;
  253. return ((m_pConfig->dwFlags & TDF_ALLOW_DIALOG_CANCELLATION) != 0);
  254. }
  255. void CXTPTaskDialogClient::OnMarkupHyperlinkClick(CXTPMarkupObject* pSender, CXTPMarkupRoutedEventArgs* pArgs)
  256. {
  257. pSender;
  258. pArgs;
  259. #ifdef _XTP_INCLUDE_MARKUP
  260. if (pSender->IsKindOf(MARKUP_TYPE(CXTPMarkupHyperlink)))
  261. {
  262. CXTPMarkupString* pTag = MARKUP_STATICCAST(CXTPMarkupString, ((CXTPMarkupHyperlink*)pSender)->GetTag());
  263. SendNotify(TDN_HYPERLINK_CLICKED, (WPARAM)0, (LPARAM)(pTag ? (LPCWSTR)*pTag : (LPCWSTR)NULL));
  264. pArgs->SetHandled();
  265. }
  266. #endif
  267. }
  268. BOOL CXTPTaskDialogClient::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  269. {
  270. // To Handle Hyperlinks:
  271. if (m_pMarkupContext)
  272. {
  273. if (XTPMarkupRelayMessage(m_strMainInstruction.m_pUIElement, message, wParam, lParam, pResult))
  274. return TRUE;
  275. if (XTPMarkupRelayMessage(m_strContent.m_pUIElement, message, wParam, lParam, pResult))
  276. return TRUE;
  277. if (XTPMarkupRelayMessage(m_strFooter.m_pUIElement, message, wParam, lParam, pResult))
  278. return TRUE;
  279. if (XTPMarkupRelayMessage(m_strVerificationText.m_pUIElement, message, wParam, lParam, pResult))
  280. return TRUE;
  281. if (XTPMarkupRelayMessage(m_strExpandedInformation.m_pUIElement, message, wParam, lParam, pResult))
  282. return TRUE;
  283. if (XTPMarkupRelayMessage(m_strExpandedControlText.m_pUIElement, message, wParam, lParam, pResult))
  284. return TRUE;
  285. if (XTPMarkupRelayMessage(m_strCollapsedControlText.m_pUIElement, message, wParam, lParam, pResult))
  286. return TRUE;
  287. }
  288. return CDialog::OnWndMsg(message, wParam, lParam, pResult);
  289. }
  290. LRESULT CXTPTaskDialogClient::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  291. {
  292. switch (message)
  293. {
  294. case WM_COMMAND:
  295. {
  296. if (HIWORD(wParam) == BN_CLICKED)
  297. {
  298. int nID = (int)LOWORD(wParam);
  299. HWND hWnd = (HWND)lParam;
  300. if (hWnd && m_arrRadioButtons.GetSize() > 0)
  301. {
  302. for (int i = 0; i < m_arrRadioButtons.GetSize(); i++)
  303. {
  304. if (m_arrRadioButtons[i]->GetSafeHwnd() == hWnd )
  305. {
  306. if (m_arrRadioButtons[i]->GetCheck())
  307. {
  308. m_nSelRadioButtonID = nID;
  309. SendNotify(TDN_RADIO_BUTTON_CLICKED, (WPARAM)m_nSelRadioButtonID);
  310. }
  311. return TRUE;
  312. }
  313. }
  314. }
  315. if (hWnd && (hWnd == m_wndFooter.GetSafeHwnd()
  316. || hWnd == m_wndContent.GetSafeHwnd()
  317. || hWnd == m_wndExpandedInformation.GetSafeHwnd()))
  318. {
  319. CXTPTaskDialogLinkCtrl* pWnd = (CXTPTaskDialogLinkCtrl*)CWnd::FromHandle(hWnd);
  320. CXTPTaskDialogLinkCtrl::LINKITEM* pItem = pWnd->GetFocusedLink();
  321. if (pItem)
  322. {
  323. SendNotify(TDN_HYPERLINK_CLICKED, (WPARAM)0, (LPARAM)XTP_CT2CW(pItem->strUrl));
  324. return 1;
  325. }
  326. }
  327. switch (nID)
  328. {
  329. case XTP_IDC_VERIFY:
  330. if (m_pBtnVerify && m_pBtnVerify->GetSafeHwnd() == hWnd)
  331. {
  332. m_bVerification = !m_bVerification;
  333. SendNotify(TDN_VERIFICATION_CLICKED, m_bVerification);
  334. return 0;
  335. }
  336. case XTP_IDC_EXPANDO:
  337. if (m_pBtnExpando && m_pBtnExpando->GetSafeHwnd() == hWnd)
  338. {
  339. m_bExpanded = !m_bExpanded;
  340. SendNotify(TDN_EXPANDO_BUTTON_CLICKED, m_bExpanded);
  341. OnExpandExpandoClicked();
  342. return 0;
  343. }
  344. case IDCANCEL:
  345. if (!CanCancel())
  346. return FALSE;
  347. // Fall thru
  348. default:
  349. if (SendNotify(TDN_BUTTON_CLICKED, (WPARAM)nID) == 0)
  350. {
  351. if (nID == IDCANCEL)
  352. {
  353. OnCancel();
  354. }
  355. else if (nID == IDOK)
  356. {
  357. OnOK();
  358. }
  359. else
  360. {
  361. EndDialog(nID);
  362. }
  363. }
  364. return 0;
  365. }
  366. }
  367. break;
  368. }
  369. }
  370. return CDialog::WindowProc(message, wParam, lParam);
  371. }
  372. //---------------------------------------------------------------------------
  373. // Initialization
  374. //---------------------------------------------------------------------------
  375. void CXTPTaskDialogClient::RefreshMetrics()
  376. {
  377. CXTPWinThemeWrapper themeApi;
  378. m_bThemeReady = m_bMessageBoxStyle || themeApi.IsAppThemeReady();
  379. m_ptBorder.x      = ::GetSystemMetrics(SM_CXEDGE) + ::GetSystemMetrics(SM_CXBORDER);
  380. m_ptBorder.y      = ::GetSystemMetrics(SM_CYEDGE) + ::GetSystemMetrics(SM_CYBORDER);
  381. m_sizeIconFooter.cx     = ::GetSystemMetrics(SM_CXSMICON);
  382. m_sizeIconFooter.cy     = ::GetSystemMetrics(SM_CYSMICON);
  383. m_sizeIconMain.cx = ::GetSystemMetrics(SM_CXICON);
  384. m_sizeIconMain.cy = ::GetSystemMetrics(SM_CYICON);
  385. m_ptMargin     = XTPDlu2Pix(xtpDluMargin, xtpDluMargin);
  386. m_ptPadding    = XTPDlu2Pix(xtpDluPadding, xtpDluPadding);
  387. m_ptBtnSpacing = CPoint(XTPDlu2Pix(xtpDluBtnSpacing, xtpDluBtnSpacing).x, 0);
  388. if (!m_bThemeReady)
  389. m_ptBtnSpacing = CPoint(m_ptMargin.x, 2);
  390. m_nMinClientWidth = XTPDlu2Pix(xtpDluMinClient, 0).x - m_ptMargin.x * 2;
  391. CRect rcScreen = XTPMultiMonitor()->GetWorkArea(m_pConfig->hwndParent);
  392. m_nMaxClientWidth = rcScreen.Width() - ((m_ptBorder.x*2) + (m_ptMargin.x*2));
  393. if (m_nMinClientWidth > m_nMaxClientWidth)
  394. m_nMinClientWidth = m_nMaxClientWidth;
  395. }
  396. void CXTPTaskDialogClient::RefreshColors()
  397. {
  398. XTPColorManager()->RefreshColors();
  399. COLORREF crWindow = GetXtremeColor(COLOR_WINDOW);
  400. COLORREF crWindowText = GetXtremeColor(COLOR_WINDOWTEXT);
  401. COLORREF crBtnFace = GetXtremeColor(COLOR_BTNFACE);
  402. COLORREF crBtnText = GetXtremeColor(COLOR_BTNTEXT);
  403. m_cr3DShadow = GetXtremeColor(COLOR_3DSHADOW);
  404. m_cr3DHighLight = GetXtremeColor(COLOR_3DHILIGHT);
  405. m_cr3DLight  = XTPColorManager()->LightColor(crBtnFace, m_cr3DShadow, 750);
  406. m_crContext = m_bThemeReady? crWindow : crBtnFace;
  407. m_crContextText = m_bThemeReady? crWindowText : crBtnText;
  408. m_crMainText = m_bThemeReady ? RGB(0x00, 0x33, 0x99) : m_crContextText;
  409. m_crFooter = crBtnFace;
  410. m_crFooterText = crBtnText;
  411. m_wndContent.SetBackColor(m_crContext);
  412. m_wndContent.SetTextColor(m_crContextText);
  413. m_wndExpandedInformation.SetBackColor(IsExpandFooterArea() ? m_crFooter : m_crContext);
  414. m_wndExpandedInformation.SetTextColor(IsExpandFooterArea() ? m_crFooterText : m_crContextText);
  415. m_wndFooter.SetBackColor(m_crFooter);
  416. m_wndFooter.SetTextColor(m_crFooterText);
  417. }
  418. CString CXTPTaskDialogClient::LoadItemString(PCWSTR pszBuffer)
  419. {
  420. CString strItem;
  421. if (pszBuffer && IS_INTRESOURCE(pszBuffer))
  422. {
  423. UINT uID = (UINT)(UINT_PTR)pszBuffer;
  424. if (::FindResource(m_pConfig->hInstance, MAKEINTRESOURCE((uID>>4)+1), RT_STRING))
  425. XTPLoadStringInst(m_pConfig->hInstance, uID, &strItem);
  426. else
  427. XTPResourceManager()->LoadString(&strItem, uID);
  428. ASSERT(!strItem.IsEmpty());
  429. }
  430. else
  431. {
  432. strItem = pszBuffer;
  433. }
  434. return strItem;
  435. }
  436. void CXTPTaskDialogClient::LoadStrings()
  437. {
  438. m_strMainInstruction.SetCaption(LoadItemString(m_pConfig->pszMainInstruction));
  439. m_strContent.SetCaption(LoadItemString(m_pConfig->pszContent));
  440. m_strFooter.SetCaption(LoadItemString(m_pConfig->pszFooter));
  441. m_strVerificationText.SetCaption(LoadItemString(m_pConfig->pszVerificationText));
  442. m_strExpandedInformation.SetCaption(LoadItemString(m_pConfig->pszExpandedInformation));
  443. if (!m_strExpandedInformation.IsEmpty())
  444. {
  445. m_strExpandedControlText.SetCaption(LoadItemString(m_pConfig->pszExpandedControlText));
  446. m_strCollapsedControlText.SetCaption(LoadItemString(m_pConfig->pszCollapsedControlText));
  447. if (m_strExpandedControlText.IsEmpty() && m_strCollapsedControlText.IsEmpty())
  448. {
  449. VERIFY(XTPResourceManager()->LoadString(&m_strExpandedControlText.m_strCaption, XTP_IDS_TASK_HIDE_DETAILS));
  450. VERIFY(XTPResourceManager()->LoadString(&m_strCollapsedControlText.m_strCaption, XTP_IDS_TASK_SEE_DETAILS));
  451. }
  452. else if (m_strExpandedControlText.IsEmpty())
  453. {
  454. m_strExpandedControlText = m_strCollapsedControlText;
  455. }
  456. else if (m_strCollapsedControlText.IsEmpty())
  457. {
  458. m_strCollapsedControlText = m_strExpandedControlText;
  459. }
  460. }
  461. }
  462. BOOL CXTPTaskDialogClient::CreateCommandButtons()
  463. {
  464. if ((m_pConfig->dwCommonButtons & TDCBF_OK_BUTTON) || (!m_pConfig->pButtons && !m_pConfig->dwCommonButtons))
  465. {
  466. if (AddCommandButton(IDOK, XTP_IDS_TASK_OK, m_sizeCommandButton) == NULL)
  467. {
  468. TRACE0("Failed to create OK button.n");
  469. return FALSE;
  470. }
  471. }
  472. if (m_pConfig->dwCommonButtons & TDCBF_YES_BUTTON)
  473. {
  474. if (AddCommandButton(IDYES, XTP_IDS_TASK_YES, m_sizeCommandButton) == NULL)
  475. {
  476. TRACE0("Failed to create YES button.n");
  477. return FALSE;
  478. }
  479. }
  480. if (m_pConfig->dwCommonButtons & TDCBF_NO_BUTTON)
  481. {
  482. if (AddCommandButton(IDNO, XTP_IDS_TASK_NO, m_sizeCommandButton) == NULL)
  483. {
  484. TRACE0("Failed to create NO button.n");
  485. return FALSE;
  486. }
  487. }
  488. if (m_pConfig->dwCommonButtons & TDCBF_RETRY_BUTTON)
  489. {
  490. if (AddCommandButton(IDRETRY, XTP_IDS_TASK_RETRY, m_sizeCommandButton) == NULL)
  491. {
  492. TRACE0("Failed to create RETRY button.n");
  493. return FALSE;
  494. }
  495. }
  496. if (m_pConfig->dwCommonButtons & TDCBF_CANCEL_BUTTON)
  497. {
  498. if (AddCommandButton(IDCANCEL, XTP_IDS_TASK_CANCEL, m_sizeCommandButton) == NULL)
  499. {
  500. TRACE0("Failed to create CANCEL button.n");
  501. return FALSE;
  502. }
  503. }
  504. if (m_pConfig->dwCommonButtons & TDCBF_CLOSE_BUTTON)
  505. {
  506. if (AddCommandButton(IDCLOSE, XTP_IDS_TASK_CLOSE, m_sizeCommandButton) == NULL)
  507. {
  508. TRACE0("Failed to create CLOSE button.n");
  509. return FALSE;
  510. }
  511. }
  512. return TRUE;
  513. }
  514. BOOL CXTPTaskDialogClient::CreateLinkButtons()
  515. {
  516. if (m_pConfig->pButtons == NULL || m_pConfig->cButtons == 0)
  517. return TRUE;
  518. for (UINT i = 0; i < m_pConfig->cButtons; ++i)
  519. {
  520. CString strButtonText = LoadItemString(m_pConfig->pButtons[i].pszButtonText);
  521. if (IsLinkButtonsUsed())
  522. {
  523. CXTPTaskButtonTheme* pTheme = new CXTPTaskButtonTheme(m_bThemeReady);
  524. pTheme->SetTitleFont(&m_fontLarge);
  525. CButton* pButton = CreateButton(m_pConfig->pButtons[i].nButtonID,
  526. strButtonText, CSize(0, 0), BS_PUSHBUTTON | BS_MULTILINE | WS_TABSTOP, pTheme);
  527. if (pButton == NULL)
  528. {
  529. TRACE0("Error creating command link button.n");
  530. return FALSE;
  531. }
  532. if (m_pIconLinkGlyph)
  533. {
  534. CXTButton* pXTButton = DYNAMIC_DOWNCAST(CXTButton, pButton);
  535. if (pXTButton == NULL)
  536. {
  537. TRACE0("Error creating command link button.n");
  538. SAFE_DELETE(pButton);
  539. return FALSE;
  540. }
  541. CSize sizeGlyph = m_pIconLinkGlyph->GetExtent();
  542. m_pIconLinkGlyph->InternalAddRef(); // Lets share one icon!
  543. pXTButton->SetIcon(sizeGlyph, m_pIconLinkGlyph);
  544. pXTButton->SetImageGap(sizeGlyph.cx / 2);
  545. }
  546. m_arrLinkButtons.Add(pButton);
  547. }
  548. else
  549. {
  550. CSize sizeButton = CalcButtonSize(strButtonText);
  551. sizeButton.cx = max(m_sizeCommandButton.cx, sizeButton.cx);
  552. if (AddCommandButton(m_pConfig->pButtons[i].nButtonID, strButtonText, sizeButton) == NULL)
  553. {
  554. TRACE0("Failed to create OK button.n");
  555. return FALSE;
  556. }
  557. }
  558. }
  559. return TRUE;
  560. }
  561. #ifndef PBS_MARQUEE
  562. #define PBS_MARQUEE             0x08
  563. #endif
  564. BOOL CXTPTaskDialogClient::CreateProgressBar()
  565. {
  566. if (!IsProgressBarVisible())
  567. return TRUE;
  568. if (!m_wndProgressBar.Create(WS_CHILD | WS_VISIBLE |
  569. (m_pConfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR ? PBS_MARQUEE : 0), CRect(0, 0, 0, 0), this, 0))
  570. return FALSE;
  571. return TRUE;
  572. }
  573. BOOL CXTPTaskDialogClient::CreateRadioButtons()
  574. {
  575. if (m_pConfig->pRadioButtons == NULL)
  576. return TRUE;
  577. for (UINT i = 0; i < m_pConfig->cRadioButtons; ++i)
  578. {
  579. CString strButton = LoadItemString(m_pConfig->pRadioButtons[i].pszButtonText);
  580. int nButtonID = m_pConfig->pRadioButtons[i].nButtonID;
  581. CPoint point(10,2);
  582. CButton* pButton = CreateButton(nButtonID, strButton,
  583. CalcButtonSize(strButton, &point), BS_AUTORADIOBUTTON | BS_TEXT | BS_MULTILINE);
  584. if (pButton == NULL)
  585. {
  586. TRACE0("Error creating radio button.n");
  587. return FALSE;
  588. }
  589. if ((m_pConfig->dwFlags & TDF_NO_DEFAULT_RADIO_BUTTON) == 0)
  590. {
  591. if (m_pConfig->nDefaultRadioButton == nButtonID)
  592. {
  593. pButton->SetCheck(TRUE);
  594. m_nSelRadioButtonID = nButtonID;
  595. pButton->ModifyStyle(0, WS_TABSTOP);
  596. }
  597. if (m_pConfig->nDefaultRadioButton == 0 && i == 0)
  598. {
  599. pButton->SetCheck(TRUE);
  600. m_nSelRadioButtonID = nButtonID;
  601. pButton->ModifyStyle(0, WS_TABSTOP);
  602. }
  603. }
  604. else if (i == 0)
  605. {
  606. pButton->ModifyStyle(0, WS_TABSTOP);
  607. }
  608. m_arrRadioButtons.Add(pButton);
  609. }
  610. return TRUE;
  611. }
  612. BOOL CXTPTaskDialogClient::CreateVerifyExpandButtons()
  613. {
  614. // create expando button.
  615. if (!m_strExpandedInformation.IsEmpty())
  616. {
  617. CString strButtonText = IsExpandedByDefault()? m_strExpandedControlText: m_strCollapsedControlText;
  618. CString strButtonSize = m_strExpandedControlText.m_strCaption.GetLength() > m_strCollapsedControlText.m_strCaption.GetLength()
  619. ? m_strExpandedControlText : m_strCollapsedControlText;
  620. CSize sizeButton = CalcButtonSize(strButtonSize, NULL, XTPDlu2Pix(xtpDluMaxVerify,0).x);
  621. CButton* pButton = CreateButton(XTP_IDC_EXPANDO, strButtonText, sizeButton,
  622. BS_PUSHBUTTON | BS_MULTILINE | WS_TABSTOP, new CXTPTaskButtonThemeExpando);
  623. if (pButton == NULL)
  624. {
  625. TRACE0("Error creating Expando button.n");
  626. return FALSE;
  627. }
  628. m_pBtnExpando = DYNAMIC_DOWNCAST(CXTButton, pButton);
  629. if (m_pBtnExpando == NULL)
  630. {
  631. TRACE0("Error creating Expando button.n");
  632. SAFE_DELETE(pButton);
  633. return FALSE;
  634. }
  635. m_pBtnExpando->SetXButtonStyle(BS_XT_WINXP_COMPAT);
  636. m_bExpanded = IsExpandedByDefault();
  637. }
  638. // create verification text check box.
  639. if (!m_strVerificationText.IsEmpty())
  640. {
  641. CString strButtonText = m_strVerificationText;
  642. CPoint point(10, 2);
  643. CSize sizeButton = CalcButtonSize(strButtonText, &point, XTPDlu2Pix(xtpDluMaxVerify,0).x);
  644. CButton* pButton = CreateButton(XTP_IDC_VERIFY, strButtonText, sizeButton,
  645. BS_AUTOCHECKBOX | BS_MULTILINE | BS_TOP | BS_LEFT | WS_TABSTOP);
  646. if (pButton == NULL)
  647. {
  648. TRACE0("Error creating Verification check box.n");
  649. return FALSE;
  650. }
  651. m_bVerification = ((m_pConfig->dwFlags & TDF_VERIFICATION_FLAG_CHECKED) != 0);
  652. m_pBtnVerify = pButton;
  653. m_pBtnVerify->SetCheck(m_bVerification);
  654. }
  655. return TRUE;
  656. }
  657. BOOL CXTPTaskDialogClient::CreateClient(BOOL bMoveWindow)
  658. {
  659. DeleteControls();
  660. if (m_bEnableMarkup)
  661. {
  662. m_pMarkupContext = XTPMarkupCreateContext(m_hWnd);
  663. }
  664. #ifdef _XTP_INCLUDE_MARKUP
  665. if (m_pMarkupContext)
  666. {
  667. m_pMarkupContext->AddHandler(CXTPMarkupHyperlink::m_pClickEvent, CreateMarkupClassDelegate(this, &CXTPTaskDialogClient::OnMarkupHyperlinkClick));
  668. }
  669. #endif
  670. RefreshMetrics();
  671. RefreshColors();
  672. LoadStrings();
  673. CreateIcons();
  674. CreateFonts();
  675. m_sizeCommandButton = CalcCommandButtonSize();
  676. if (!CreateLinkButtons() ||         // create command link buttons.
  677. !CreateCommandButtons())        // create common buttons OK, Cancel, etc.
  678. {
  679. return FALSE;
  680. }
  681. // If hyperlinks are enabled, creating the links now with a zero size
  682. // will extract all hyperlink information from the string so the layout
  683. // can be determined correctly. The links will be resized when RecalcLayout
  684. // is called.
  685. if (IsHyperlinksEnabled())
  686. {
  687. CXTPEmptyRect rect;
  688. m_wndContent.Create(rect, m_strContent.m_strCaption, &m_font, this);
  689. m_wndExpandedInformation.Create(rect, m_strExpandedInformation.m_strCaption, &m_font, this);
  690. m_wndFooter.Create(rect, m_strFooter.m_strCaption, &m_font, this);
  691. }
  692. if (!CreateProgressBar() ||
  693. !CreateRadioButtons() ||        // create radio buttons.
  694. !CreateVerifyExpandButtons())   // create verify and expando buttons.
  695. {
  696. return FALSE;
  697. }
  698. RecalcLayout(bMoveWindow);
  699. return TRUE;
  700. }
  701. void CXTPTaskDialogClient::UpdateZOrder()
  702. {
  703. ZOrder(&m_wndContent);
  704. if (!IsExpandFooterArea())
  705. ZOrder(&m_wndExpandedInformation);
  706. ZOrder(&m_wndProgressBar);
  707. int i;
  708. for (i = 0; i < (int)m_arrRadioButtons.GetSize(); i++)
  709. {
  710. ZOrder(m_arrRadioButtons[i]);
  711. }
  712. for (i = 0; i < (int)m_arrLinkButtons.GetSize(); i++)
  713. {
  714. ZOrder(m_arrLinkButtons[i]);
  715. }
  716. ZOrder(m_pBtnExpando);
  717. ZOrder(m_pBtnVerify);
  718. for (i = 0; i < (int)m_arrCommandButtons.GetSize(); i++)
  719. {
  720. ZOrder(m_arrCommandButtons[i]);
  721. }
  722. ZOrder(&m_wndFooter);
  723. if (IsExpandFooterArea())
  724. ZOrder(&m_wndExpandedInformation);
  725. }
  726. void CXTPTaskDialogClient::ZOrder(CWnd* pWnd)
  727. {
  728. if (!pWnd || !pWnd->GetSafeHwnd() )
  729. return;
  730. pWnd->SetWindowPos(&CWnd::wndBottom, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
  731. }
  732. HICON CXTPTaskDialogClient::CreateIcon(HICON hIcon, PCWSTR lpwzIcon, CSize sizeIcon, BOOL bUseHandle)
  733. {
  734. HICON hNewIcon = NULL;
  735. if (bUseHandle && hIcon != NULL)
  736. {
  737. hNewIcon = ::CopyIcon(hIcon);
  738. }
  739. else if (!bUseHandle)
  740. {
  741. if (m_pConfig->hInstance == NULL || lpwzIcon == NULL || !IS_INTRESOURCE(lpwzIcon))
  742. {
  743. return FALSE;
  744. }
  745. if (lpwzIcon == TD_ERROR_ICON ||
  746. lpwzIcon == TD_WARNING_ICON ||
  747. lpwzIcon == TD_INFORMATION_ICON ||
  748. lpwzIcon == TD_SHIELD_ICON)
  749. {
  750. DWORD dwID = 0;
  751. if (m_bUseSysIcons)
  752. {
  753. switch ((ULONG_PTR)lpwzIcon)
  754. {
  755. case (ULONG_PTR)TD_ERROR_ICON:       dwID = 0x0067; break;
  756. case (ULONG_PTR)TD_WARNING_ICON:     dwID = 0x0065; break;
  757. case (ULONG_PTR)TD_INFORMATION_ICON: dwID = 0x0068; break;
  758. case (ULONG_PTR)TD_SHIELD_ICON:      dwID = 0x006a; break; // vista and later.
  759. }
  760. hNewIcon = XTPResourceManager()->CreateIconFromResource(
  761. CXTPModuleHandle(_T("user32.dll")), MAKEINTRESOURCE(dwID), sizeIcon);
  762. }
  763. if (hNewIcon == NULL)
  764. {
  765. switch ((ULONG_PTR)lpwzIcon)
  766. {
  767. case (ULONG_PTR)TD_ERROR_ICON:       dwID = XTP_IDI_TASKERROR;  break;
  768. case (ULONG_PTR)TD_WARNING_ICON:     dwID = XTP_IDI_TASKWARN;   break;
  769. case (ULONG_PTR)TD_INFORMATION_ICON: dwID = XTP_IDI_TASKINFO;   break;
  770. case (ULONG_PTR)TD_SHIELD_ICON:      dwID = XTP_IDI_TASKSHIELD; break;
  771. }
  772. hNewIcon = XTPResourceManager()->LoadIcon(MAKEINTRESOURCE(dwID), sizeIcon);
  773. }
  774. }
  775. else
  776. {
  777. hNewIcon = XTPResourceManager()->CreateIconFromResource(
  778. m_pConfig->hInstance, (LPTSTR)lpwzIcon, sizeIcon);
  779. }
  780. }
  781. ASSERT(hNewIcon != NULL);
  782. return hNewIcon;
  783. }
  784. void CXTPTaskDialogClient::CreateIcons()
  785. {
  786. // create small icon.
  787. SAFE_DELETE_HICON(m_hIconFooter);
  788. m_hIconFooter = CreateIcon(m_pConfig->hFooterIcon, m_pConfig->pszFooterIcon, m_sizeIconFooter, IsFooterIconHandleUsed());
  789. // create large icon.
  790. SAFE_DELETE_HICON(m_hIconMain);
  791. m_hIconMain = CreateIcon(m_pConfig->hMainIcon, m_pConfig->pszMainIcon, m_sizeIconMain, IsMainIconHandleUsed());
  792. if (IsLinkButtonsUsed() && IsLinkButtonsIconVisible() && m_pIconLinkGlyph == 0)
  793. {
  794. m_pIconLinkGlyph = new CXTPImageManagerIcon(0, 20, 20);
  795. BOOL bRTLLayout = (m_pConfig->dwFlags & TDF_RTL_LAYOUT);
  796. CXTPImageManagerIconHandle hIconGlyph;
  797. CXTPImageManagerIconHandle hIconGlyphHot;
  798. HBITMAP hBitmap = (HBITMAP)CXTPImageManagerIcon::LoadAlphaBitmap(XTP_IDB_GLYPH);
  799. if (bRTLLayout)
  800. {
  801. hIconGlyph = CXTPImageManagerIcon::InvertAlphaBitmap(hBitmap);
  802. DeleteObject(hBitmap);
  803. }
  804. else
  805. {
  806. hIconGlyph = hBitmap;
  807. }
  808. hBitmap = (HBITMAP)CXTPImageManagerIcon::LoadAlphaBitmap(XTP_IDB_GLYPH_HOT);
  809. if (bRTLLayout)
  810. {
  811. hIconGlyphHot = CXTPImageManagerIcon::InvertAlphaBitmap(hBitmap);
  812. DeleteObject(hBitmap);
  813. }
  814. else
  815. {
  816. hIconGlyphHot = hBitmap;
  817. }
  818. m_pIconLinkGlyph->SetIcon(hIconGlyph);
  819. m_pIconLinkGlyph->SetHotIcon(hIconGlyphHot);
  820. }
  821. }
  822. void CXTPTaskDialogClient::CreateFonts()
  823. {
  824. NONCLIENTMETRICS ncm;
  825. ncm.cbSize = sizeof(NONCLIENTMETRICS);
  826. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  827. m_font.DeleteObject();
  828. m_fontLarge.DeleteObject();
  829. if (m_bThemeReady)
  830. {
  831. CWindowDC dc(NULL);
  832. if (_tcscmp(ncm.lfMenuFont.lfFaceName, _T("Segoe UI")) == 0)
  833. ncm.lfMenuFont.lfQuality = 5;
  834. ncm.lfMenuFont.lfWeight = FW_NORMAL;
  835. ncm.lfMenuFont.lfItalic = 0;
  836. m_font.CreateFontIndirect(&ncm.lfMenuFont);
  837. ncm.lfMenuFont.lfHeight = ::MulDiv(-12, ::GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72);
  838. if (_tcscmp(ncm.lfMenuFont.lfFaceName, _T("Segoe UI")) != 0)
  839. ncm.lfMenuFont.lfWeight = FW_BOLD;
  840. m_fontLarge.CreateFontIndirect(&ncm.lfMenuFont);
  841. }
  842. else
  843. {
  844. m_font.CreateFontIndirect(&ncm.lfMenuFont);
  845. m_fontLarge.CreateFontIndirect(&ncm.lfCaptionFont);
  846. }
  847. }
  848. //---------------------------------------------------------------------------
  849. // Button
  850. //---------------------------------------------------------------------------
  851. CButton *CXTPTaskDialogClient::CreateButton(int nButtonID, LPCTSTR lpszLabel, CSize sizeButton, DWORD dwButtonStyle /*=BS_PUSHBUTTON | BS_MULTILINE*/, CXTButtonTheme* pTheme /*=NULL*/)
  852. {
  853. CButton* pButton = pTheme? new CXTButton: new CButton;
  854. if (pTheme)
  855. dwButtonStyle |= BS_LEFT;
  856. CRect rcButton = XTPSize2Rect(sizeButton);
  857. if (pButton->Create(lpszLabel, WS_CHILD | WS_VISIBLE |
  858. dwButtonStyle, rcButton, this, nButtonID))
  859. {
  860. m_mapWndSize[pButton] = sizeButton;
  861. if (pTheme)
  862. ((CXTButton*)pButton)->SetTheme(pTheme);
  863. pButton->SetFont(&m_font);
  864. return pButton;
  865. }
  866. SAFE_DELETE(pButton);
  867. return NULL;
  868. }
  869. CButton *CXTPTaskDialogClient::AddCommandButton(int nButtonID, int nIDLabel, CSize sizeButton)
  870. {
  871. CString strButton;
  872. XTPResourceManager()->LoadString(&strButton, nIDLabel);
  873. ASSERT(!strButton.IsEmpty());
  874. return AddCommandButton(nButtonID, strButton, sizeButton);
  875. }
  876. CButton *CXTPTaskDialogClient::AddCommandButton(int nButtonID, LPCTSTR lpszLabel, CSize sizeButton)
  877. {
  878. CButton* pButton = CreateButton(nButtonID, lpszLabel, sizeButton, BS_PUSHBUTTON | BS_MULTILINE | WS_TABSTOP);
  879. if (pButton)
  880. {
  881. m_arrCommandButtons.Add(pButton);
  882. return pButton;
  883. }
  884. return NULL;
  885. }
  886. CSize CXTPTaskDialogClient::CalcButtonSize(CString strButton, CPoint* pMarginButton /*=NULL*/, int nMaxWidth /*=0*/)
  887. {
  888. CPoint ptMarginButton;
  889. ptMarginButton.x = m_ptBtnSpacing.x + m_ptMargin.x;
  890. ptMarginButton.y = m_ptPadding.y;
  891. if (pMarginButton == NULL)
  892. pMarginButton = &ptMarginButton;
  893. CXTPEmptySize sizeCaptText;
  894. CString strCaptText = XTPExtractSubString(strButton, 0);
  895. if (!strCaptText.IsEmpty())
  896. {
  897. sizeCaptText.cx = nMaxWidth;
  898. XTPDrawHelpers()->StripMnemonics(strCaptText);
  899. if (nMaxWidth == 0)
  900. XTPCalcIdealTextSize(strCaptText, sizeCaptText, m_font, 330, 7);
  901. else
  902. XTPCalcTextSize(strCaptText, sizeCaptText, m_font);
  903. }
  904. CXTPEmptySize sizeNoteText;
  905. CString strNoteText = XTPExtractSubString(strButton, 1);
  906. if (!strNoteText.IsEmpty())
  907. {
  908. sizeNoteText.cx = nMaxWidth;
  909. if (nMaxWidth == 0)
  910. XTPCalcIdealTextSize(strNoteText, sizeNoteText, m_font, 330, 7);
  911. else
  912. XTPCalcTextSize(strNoteText, sizeNoteText, m_font);
  913. }
  914. CXTPEmptySize sizeButton;
  915. sizeButton.cx = max(sizeCaptText.cx, sizeNoteText.cx) + (pMarginButton->x * 2);
  916. sizeButton.cy = sizeCaptText.cy + sizeNoteText.cy + (pMarginButton->y * 2);
  917. return sizeButton;
  918. }
  919. CSize CXTPTaskDialogClient::CalcCommandButtonSize()
  920. {
  921. CXTPEmptySize sizeCommon;
  922. for (int nIDString = XTP_IDS_TASK_OK; nIDString <= XTP_IDS_TASK_CLOSE; ++nIDString)
  923. {
  924. CString strButton;
  925. XTPResourceManager()->LoadString(&strButton, nIDString);
  926. ASSERT(!strButton.IsEmpty());
  927. CSize sizeButton = CalcButtonSize(strButton);
  928. sizeCommon.cx = max(sizeCommon.cx, sizeButton.cx);
  929. sizeCommon.cy = max(sizeCommon.cy, sizeButton.cy);
  930. }
  931. return sizeCommon;
  932. }
  933. int CXTPTaskDialogClient::CalcLinkButtonIdealWidth(CString strButton, int cxWidth)
  934. {
  935. if (strButton.IsEmpty() || !HasLinkButtons())
  936. return 0;
  937. cxWidth -= ((m_ptMargin.x*2) + m_nPadding);
  938. if (m_pIconLinkGlyph)
  939. cxWidth -= m_pIconLinkGlyph->GetExtent().cx - m_nPadding;
  940. CString strCaptText = XTPExtractSubString(strButton, 0);
  941. int nCaptionWidth = 0;
  942. CSize sizeText(cxWidth, 0);
  943. if (XTPCalcIdealTextSize(strCaptText, sizeText, m_fontLarge, 120, 30))
  944. {
  945. nCaptionWidth = sizeText.cx;
  946. }
  947. CStringMarkup strNoteText;
  948. strNoteText.SetCaption(XTPExtractSubString(strButton, 1));
  949. int nNoteWidth = CalcIdealTextWidth(strNoteText, cxWidth, FALSE);
  950. cxWidth = max(nCaptionWidth, nNoteWidth);
  951. if (m_pIconLinkGlyph)
  952. cxWidth += m_pIconLinkGlyph->GetExtent().cx;
  953. return cxWidth + m_ptMargin.x * 2 + m_nPadding;
  954. }
  955. CSize CXTPTaskDialogClient::CalcLinkButtonSize(CString strButton, int cxMaxWidth)
  956. {
  957. if (strButton.IsEmpty() || !HasLinkButtons())
  958. return CXTPEmptySize();
  959. cxMaxWidth -= ((m_ptMargin.x*2) + m_nPadding);
  960. if (m_pIconLinkGlyph)
  961. cxMaxWidth -= m_pIconLinkGlyph->GetExtent().cx;
  962. // get the initial text size.
  963. CXTPEmptySize sizeButton;
  964. BOOL bWordWrap = FALSE;
  965. // extract the title string and determine text size.
  966. CString strCaptText = XTPExtractSubString(strButton, 0);
  967. CSize sizeCaptText(cxMaxWidth, 0);
  968. if (XTPCalcTextSize(strCaptText, sizeCaptText, m_fontLarge, &bWordWrap))
  969. {
  970. // if the string spans multiple rows, set the max width.
  971. if (bWordWrap)
  972. sizeCaptText.cx = cxMaxWidth;
  973. }
  974. else
  975. {
  976. sizeCaptText.cx = 0;
  977. }
  978. // extract the note string and determine text size.
  979. CString strNoteText = XTPExtractSubString(strButton, 1);
  980. CSize sizeNoteText(cxMaxWidth, 0);
  981. if (XTPCalcTextSize(strNoteText, sizeNoteText, m_font, &bWordWrap))
  982. {
  983. // if the string spans multiple rows, set the max width.
  984. if (bWordWrap)
  985. sizeNoteText.cx = cxMaxWidth;
  986. }
  987. else
  988. {
  989. sizeNoteText.cx = 0;
  990. }
  991. // add padding around text.
  992. sizeButton.cx = max(sizeCaptText.cx, sizeNoteText.cx) + m_ptMargin.x * 2 + m_nPadding;
  993. sizeButton.cy = sizeCaptText.cy + sizeNoteText.cy + m_ptMargin.y * 2 /*+ m_nPadding*/;
  994. return sizeButton;
  995. }
  996. BOOL CXTPTaskDialogClient::MoveButton(CButton* pButton, int x, int y, int cx, int cy, BOOL bRedraw /*=FALSE*/)
  997. {
  998. // position the button.
  999. if (IsWindow(pButton) && pButton->SetWindowPos(NULL, x, y, cx, cy, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE))
  1000. {
  1001. // invalidate.
  1002. if (bRedraw)
  1003. pButton->RedrawWindow();
  1004. return TRUE;
  1005. }
  1006. return FALSE;
  1007. }
  1008. void CXTPTaskDialogClient::SetCommandButtonPos()
  1009. {
  1010. int x = m_rcCommandButtons.left, y = m_rcCommandButtons.top +  m_ptMargin.y - 1;
  1011. int i, nCount = (int)m_arrCommandButtons.GetSize();
  1012. for (i = 0; i < nCount; i++)
  1013. {
  1014. CButton* pButton = m_arrCommandButtons[i];
  1015. CXTPEmptySize sizeButton;
  1016. if (m_mapWndSize.Lookup(pButton, sizeButton))
  1017. {
  1018. // no more room, adjust height.
  1019. if (x !=  m_rcCommandButtons.left && x + sizeButton.cx > m_rcCommandButtons.right)
  1020. {
  1021. x = m_rcCommandButtons.left;
  1022. y += sizeButton.cy + m_ptBtnSpacing.y;
  1023. }
  1024. MoveButton(pButton, x, y, sizeButton.cx, sizeButton.cy);
  1025. x += sizeButton.cx + m_ptBtnSpacing.x;
  1026. }
  1027. }
  1028. }
  1029. void CXTPTaskDialogClient::SetLinkButtonPos()
  1030. {
  1031. int nTop = m_rcLinkButtons.top + m_ptMargin.x + m_ptPadding.y / 2 + 2;
  1032. int nCount = (int)m_arrLinkButtons.GetSize();
  1033. for (int i = 0; i < nCount; ++i)
  1034. {
  1035. CSize sizeButton;
  1036. if (m_mapWndSize.Lookup(m_arrLinkButtons[i], sizeButton))
  1037. {
  1038. MoveButton(m_arrLinkButtons[i], m_rcLinkButtons.left, nTop, m_rcLinkButtons.Width(), sizeButton.cy);
  1039. nTop += sizeButton.cy;
  1040. }
  1041. }
  1042. }
  1043. void CXTPTaskDialogClient::SetVerifyButtonPos()
  1044. {
  1045. CXTPEmptySize sizeVerify;
  1046. if (IsWindow(m_pBtnVerify) && m_mapWndSize.Lookup(m_pBtnVerify, sizeVerify))
  1047. {
  1048. CXTPEmptyRect rcButton;
  1049. rcButton.left = m_ptMargin.x + 3;
  1050. rcButton.right = rcButton.left + sizeVerify.cx;
  1051. // vertically center.
  1052. rcButton.top = m_rcCommandButtons.top + (m_rcCommandButtons.Height() - sizeVerify.cy)/2;
  1053. CXTPEmptySize sizeExpando;
  1054. if (IsWindow(m_pBtnExpando) && m_mapWndSize.Lookup(m_pBtnExpando, sizeExpando))
  1055. {
  1056. rcButton.top = m_rcCommandButtons.top + m_ptMargin.y + sizeExpando.cy;
  1057. }
  1058. rcButton.bottom = rcButton.top + sizeVerify.cy;
  1059. MoveButton(m_pBtnVerify, rcButton);
  1060. }
  1061. }
  1062. void CXTPTaskDialogClient::SetExpandoButtonPos()
  1063. {
  1064. CXTPEmptySize sizeExpando;
  1065. if (IsWindow(m_pBtnExpando) && m_mapWndSize.Lookup(m_pBtnExpando, sizeExpando))
  1066. {
  1067. CXTPEmptyRect rcButton;
  1068. rcButton.left = m_ptMargin.x + 3;
  1069. rcButton.right = rcButton.left + sizeExpando.cx;
  1070. // vertically center.
  1071. rcButton.top = m_rcCommandButtons.top + (m_rcCommandButtons.Height()-sizeExpando.cy)/2;
  1072. CXTPEmptySize sizeVerify;
  1073. if (IsWindow(m_pBtnVerify) && m_mapWndSize.Lookup(m_pBtnVerify, sizeVerify))
  1074. {
  1075. rcButton.top = m_rcCommandButtons.top + m_ptMargin.y;
  1076. }
  1077. rcButton.bottom = rcButton.top + sizeExpando.cy;
  1078. MoveButton(m_pBtnExpando, rcButton);
  1079. }
  1080. }
  1081. void CXTPTaskDialogClient::SetLinkCtrlPos()
  1082. {
  1083. if (IsHyperlinksEnabled())
  1084. {
  1085. if (m_wndContent) m_wndContent.MoveWindow(m_rcContent);
  1086. if (m_wndExpandedInformation) m_wndExpandedInformation.MoveWindow(m_rcExpandedInformation);
  1087. if (m_wndFooter) m_wndFooter.MoveWindow(m_rcFooter);
  1088. if (m_wndExpandedInformation) m_wndExpandedInformation.ShowWindow(m_bExpanded ? SW_SHOWNOACTIVATE : SW_HIDE);
  1089. }
  1090. }
  1091. //---------------------------------------------------------------------------
  1092. // Layout
  1093. //---------------------------------------------------------------------------
  1094. int CXTPTaskDialogClient::CalcIdealTextWidth(const CStringMarkup& strItemText, int nMinWidth, BOOL bLargeFont)
  1095. {
  1096. if (strItemText.IsEmpty())
  1097. return nMinWidth;
  1098. CSize sizeText(nMinWidth, 0);
  1099. if (strItemText.m_pUIElement)
  1100. {
  1101. if (XTPCalcIdealTextSize(m_pMarkupContext, strItemText.m_pUIElement, sizeText,
  1102. bLargeFont? m_fontLarge: m_font,
  1103. bLargeFont? 275: 330,
  1104. bLargeFont? 14: 7))
  1105. {
  1106. nMinWidth = max(nMinWidth, sizeText.cx);
  1107. }
  1108. }
  1109. else
  1110. {
  1111. if (XTPCalcIdealTextSize(strItemText, sizeText,
  1112. bLargeFont? m_fontLarge: m_font,
  1113. bLargeFont? 275: 330,
  1114. bLargeFont? 14: 7))
  1115. {
  1116. nMinWidth = max(nMinWidth, sizeText.cx);
  1117. }
  1118. }
  1119. return nMinWidth;
  1120. }
  1121. CRect CXTPTaskDialogClient::CalcTextRect(const CStringMarkup& strItemText, int nWidth, BOOL bLargeFont)
  1122. {
  1123. CRect rcItemText(0, 0, 0, 0);
  1124. if (strItemText.m_pUIElement)
  1125. {
  1126. XTPMarkupSetDefaultFont(m_pMarkupContext, bLargeFont? m_fontLarge: m_font, COLORREF_NULL);
  1127. CSize sizeText = XTPMarkupMeasureElement(strItemText.m_pUIElement, nWidth, INT_MAX);
  1128. rcItemText.SetRect(0, 0, nWidth, sizeText.cy);
  1129. }
  1130. else
  1131. {
  1132. CSize sizeText(nWidth, 0);
  1133. if (XTPCalcTextSize(strItemText, sizeText, bLargeFont? m_fontLarge: m_font))
  1134. {
  1135. rcItemText.SetRect(0, 0, nWidth, sizeText.cy);
  1136. }
  1137. }
  1138. return rcItemText;
  1139. }
  1140. CRect CXTPTaskDialogClient::CalcCommandRect(int nWidth)
  1141. {
  1142. CRect rcCommand(0, 0, nWidth, 0);
  1143. if (m_pBtnExpando == 0 && m_pBtnVerify == 0 && m_arrCommandButtons.GetSize() == 0)
  1144. return rcCommand;
  1145. int nMinHeight = 0;
  1146. int nLeftMargin = 0;
  1147. CXTPEmptySize sizeButton;
  1148. if (m_pBtnVerify && m_mapWndSize.Lookup(m_pBtnVerify, sizeButton))
  1149. {
  1150. nMinHeight = sizeButton.cy;
  1151. nLeftMargin = sizeButton.cx;
  1152. }
  1153. if (m_pBtnExpando && m_mapWndSize.Lookup(m_pBtnExpando, sizeButton))
  1154. {
  1155. nMinHeight += sizeButton.cy;
  1156. nLeftMargin = max(nLeftMargin, sizeButton.cx);
  1157. }
  1158. if (nLeftMargin)
  1159. nWidth -= nLeftMargin + m_ptBtnSpacing.x;
  1160. int i, nCount = (int)m_arrCommandButtons.GetSize();
  1161. int x = 0;
  1162. int nMaxWidth = 0;
  1163. for (i = 0; i < nCount; i++)
  1164. {
  1165. CButton* pButton = m_arrCommandButtons[i];
  1166. if (m_mapWndSize.Lookup(pButton, sizeButton))
  1167. {
  1168. // no more room, adjust height.
  1169. if (x != 0 && x + sizeButton.cx > nWidth)
  1170. {
  1171. nMaxWidth = max(nMaxWidth, x - m_ptBtnSpacing.x);
  1172. x = 0;
  1173. rcCommand.bottom += m_ptBtnSpacing.y;
  1174. }
  1175. // first button in row, adjust height.
  1176. if (x == 0)
  1177. rcCommand.bottom += sizeButton.cy;
  1178. x += sizeButton.cx + m_ptBtnSpacing.x;
  1179. }
  1180. }
  1181. nMaxWidth = max(nMaxWidth, x - m_ptBtnSpacing.x);
  1182. rcCommand.left = nWidth - nMaxWidth;
  1183. if (nLeftMargin)
  1184. rcCommand.left += nLeftMargin + m_ptBtnSpacing.x;
  1185. if (nMinHeight > rcCommand.Height())
  1186. rcCommand.bottom = rcCommand.top + nMinHeight;
  1187. rcCommand.bottom += m_ptMargin.y * 2 - 2;
  1188. return rcCommand;
  1189. }
  1190. int CXTPTaskDialogClient::CalcClientWidth()
  1191. {
  1192. int nIdealWidth = m_nMinClientWidth;
  1193. if (HasFixedWidth())
  1194. {
  1195. CSize sizeBase = ::GetDialogBaseUnits();
  1196. int cxWidth = ::MulDiv(m_pConfig->cxWidth, sizeBase.cx, 4);
  1197. nIdealWidth = max(cxWidth - m_ptMargin.x * 2, nIdealWidth);
  1198. return nIdealWidth;
  1199. }
  1200. int nCommandButtonWidth = -m_ptBtnSpacing.x + m_ptMargin.x * 2, nCount, i;
  1201. nCount = (int)m_arrCommandButtons.GetSize();
  1202. for (i = 0; i < nCount; ++i)
  1203. {
  1204. CSize size;
  1205. if (m_mapWndSize.Lookup(m_arrCommandButtons[i], size))
  1206. nCommandButtonWidth += size.cx + m_ptBtnSpacing.x;
  1207. }
  1208. if (!HasLinkButtons())
  1209. {
  1210. nIdealWidth = max(nIdealWidth, nCommandButtonWidth);
  1211. }
  1212. if (m_pBtnVerify->GetSafeHwnd())
  1213. {
  1214. CSize size;
  1215. if (m_mapWndSize.Lookup(m_pBtnVerify, size))
  1216. {
  1217. nIdealWidth = max(nIdealWidth, size.cx + nCommandButtonWidth + m_ptMargin.x);
  1218. }
  1219. }
  1220. if (m_pBtnExpando->GetSafeHwnd())
  1221. {
  1222. CSize size;
  1223. if (m_mapWndSize.Lookup(m_pBtnExpando , size))
  1224. {
  1225. nIdealWidth = max(nIdealWidth, size.cx + nCommandButtonWidth + m_ptMargin.x);
  1226. }
  1227. }
  1228. int nMainIconMargin = (m_hIconMain ? (m_sizeIconMain.cx + m_ptMargin.x): 0);
  1229. int nFooterIconMargin = (m_hIconFooter ? (m_sizeIconFooter.cx + m_ptMargin.x): 0);
  1230. int nExpanIconMargin = IsExpandFooterArea() ? nFooterIconMargin : nMainIconMargin;
  1231. nCount = (int)m_arrRadioButtons.GetSize();
  1232. for (i = 0; i < nCount; ++i)
  1233. {
  1234. CSize size;
  1235. if (m_mapWndSize.Lookup(m_arrRadioButtons[i], size))
  1236. nIdealWidth = max(nIdealWidth, size.cx + nMainIconMargin);
  1237. }
  1238. CXTPEmptySize size;
  1239. if (m_mapWndSize.Lookup(m_pBtnVerify, size))
  1240. nIdealWidth = max(nIdealWidth, size.cx);
  1241. if (m_mapWndSize.Lookup(m_pBtnExpando, size))
  1242. nIdealWidth = max(nIdealWidth, size.cx);
  1243. int nWidth = CalcIdealTextWidth(m_strMainInstruction, nIdealWidth - nMainIconMargin, TRUE);
  1244. nIdealWidth = max(nIdealWidth, nWidth + nMainIconMargin);
  1245. nWidth = CalcIdealTextWidth(m_strContent, nIdealWidth - nMainIconMargin, FALSE);
  1246. nIdealWidth = max(nIdealWidth, nWidth + nMainIconMargin);
  1247. if (HasLinkButtons())
  1248. {
  1249. for (i = 0; i < (int)m_pConfig->cButtons; ++i)
  1250. {
  1251. CString strButton = LoadItemString(m_pConfig->pButtons[i].pszButtonText);
  1252. nWidth = CalcLinkButtonIdealWidth(strButton, nIdealWidth - nMainIconMargin);
  1253. nIdealWidth = max(nIdealWidth, nWidth + nMainIconMargin);
  1254. }
  1255. }
  1256. nWidth = CalcIdealTextWidth(m_strExpandedInformation, nIdealWidth - nExpanIconMargin, FALSE);
  1257. nIdealWidth = max(nIdealWidth, nWidth + nExpanIconMargin);
  1258. nWidth = CalcIdealTextWidth(m_strFooter, nIdealWidth - nFooterIconMargin, FALSE);
  1259. nIdealWidth = max(nIdealWidth, nWidth + nFooterIconMargin);
  1260. nIdealWidth = min(nIdealWidth, m_nMaxClientWidth);
  1261. return nIdealWidth;
  1262. }
  1263. CSize CXTPTaskDialogClient::CalcDynamicLayout(int nIdealWidth)
  1264. {
  1265. int nMainIconMargin = m_hIconMain ? (m_sizeIconMain.cx + m_ptMargin.x) : 0;
  1266. int nFooterIconMargin = m_hIconFooter ? (m_sizeIconFooter.cx + m_ptMargin.x) : 0;
  1267. m_rcMainInstruction = CalcTextRect(m_strMainInstruction, nIdealWidth - nMainIconMargin, TRUE);
  1268. if (!m_rcMainInstruction.IsRectEmpty())
  1269. m_rcMainInstruction.OffsetRect(m_ptMargin.x + nMainIconMargin, m_ptMargin.y);
  1270. m_rcContent = CalcTextRect(m_strContent, nIdealWidth - nMainIconMargin, FALSE);
  1271. m_rcContent.OffsetRect(m_ptMargin.x + nMainIconMargin,
  1272. m_rcMainInstruction.bottom + m_ptMargin.y + 1);
  1273. int nLinkTop = m_rcContent.bottom + m_ptPadding.y;
  1274. if (nLinkTop < m_ptMargin.y * 4 - 3)
  1275. nLinkTop = m_ptMargin.y * 4 - 3;
  1276. if (!IsExpandFooterArea())
  1277. {
  1278. if (!m_strExpandedInformation.IsEmpty())
  1279. {
  1280. if (m_bExpanded)
  1281. {
  1282. m_rcExpandedInformation = CalcTextRect(m_strExpandedInformation, nIdealWidth - nMainIconMargin, FALSE);
  1283. m_rcExpandedInformation.OffsetRect(m_ptMargin.x + nMainIconMargin, nLinkTop + m_ptPadding.y);
  1284. }
  1285. else
  1286. {
  1287. m_rcExpandedInformation.SetRect(m_rcContent.left, nLinkTop, m_rcContent.right, nLinkTop + m_ptPadding.y);
  1288. }
  1289. nLinkTop += m_rcExpandedInformation.Height() + m_ptPadding.y;
  1290. }
  1291. else
  1292. {
  1293. m_rcExpandedInformation.SetRect(m_rcContent.left, nLinkTop, m_rcContent.right, nLinkTop);
  1294. }
  1295. }
  1296. if (m_wndProgressBar.GetSafeHwnd())
  1297. {
  1298. CRect rcProgressBar(m_rcContent.left, nLinkTop + m_ptMargin.y, nIdealWidth + m_ptMargin.x, nLinkTop + m_ptMargin.y * 5/2);
  1299. m_wndProgressBar.MoveWindow(rcProgressBar);
  1300. nLinkTop += rcProgressBar.Height() + m_ptMargin.y;
  1301. }
  1302. if (m_arrRadioButtons.GetSize() > 0)
  1303. {
  1304. nLinkTop +=  m_ptMargin.y;
  1305. m_rcRadioButtons = CRect(m_rcContent.left + m_ptMargin.x, nLinkTop, nIdealWidth, nLinkTop);
  1306. for (int i = 0; i < m_arrRadioButtons.GetSize(); i++)
  1307. {
  1308. CButton* pButton = m_arrRadioButtons[i];
  1309. CSize sizeButton;
  1310. if (m_mapWndSize.Lookup(pButton, sizeButton))
  1311. {
  1312. pButton->MoveWindow(m_rcRadioButtons.left, nLinkTop, sizeButton.cx, sizeButton.cy);
  1313. nLinkTop += sizeButton.cy + 3;
  1314. }
  1315. }
  1316. m_rcRadioButtons.bottom = nLinkTop;
  1317. }
  1318. else
  1319. {
  1320. m_rcRadioButtons = CRect(m_rcContent.left + 1, nLinkTop, m_rcContent.right, nLinkTop);
  1321. }
  1322. m_rcLinkButtons = CRect(m_rcContent.left + 1, nLinkTop + 1, m_ptMargin.y + nIdealWidth - 1, nLinkTop + 1);
  1323. for (int i = 0; i < (int)m_arrLinkButtons.GetSize(); ++i)
  1324. {
  1325. CString strButton = LoadItemString(m_pConfig->pButtons[i].pszButtonText);
  1326. CButton* pButton = m_arrLinkButtons[i];
  1327. CSize sizeButton = CalcLinkButtonSize(strButton, m_rcLinkButtons.Width());
  1328. sizeButton.cx = m_rcLinkButtons.Width();
  1329. m_mapWndSize[pButton] = sizeButton;
  1330. m_rcLinkButtons.bottom += sizeButton.cy;
  1331. }
  1332. if (m_arrLinkButtons.GetSize() > 0) m_rcLinkButtons.bottom += m_ptMargin.y;
  1333. m_rcCommandButtons = CalcCommandRect(nIdealWidth);
  1334. m_rcCommandButtons.OffsetRect(m_ptMargin.x, m_rcLinkButtons.bottom  + m_ptMargin.y + m_ptPadding.y);
  1335. int nBottom = m_rcCommandButtons.bottom;
  1336. if (!m_strFooter.IsEmpty())
  1337. {
  1338. m_rcFooter = CalcTextRect(m_strFooter, nIdealWidth - nFooterIconMargin, FALSE);
  1339. m_rcFooter.OffsetRect(m_ptMargin.x + nFooterIconMargin - 1, nBottom + m_ptMargin.y + 1);
  1340. nBottom += m_rcFooter.Height() + 2 * m_ptMargin.y + 1;
  1341. }
  1342. if (IsExpandFooterArea())
  1343. {
  1344. if (!m_strExpandedInformation.IsEmpty() && m_bExpanded)
  1345. {
  1346. m_rcExpandedInformation = CalcTextRect(m_strExpandedInformation, nIdealWidth, FALSE);
  1347. m_rcExpandedInformation.OffsetRect(m_ptMargin.x, nBottom + m_ptMargin.y);
  1348. nBottom += m_rcExpandedInformation.Height() + 2 * m_ptMargin.y;
  1349. }
  1350. else
  1351. {
  1352. m_rcExpandedInformation.SetRect(m_rcFooter.left, nBottom, m_rcFooter.right, nBottom);
  1353. }
  1354. }
  1355. return CSize(nIdealWidth + m_ptMargin.x * 2, nBottom);
  1356. }
  1357. void CXTPTaskDialogClient::RecalcLayout(BOOL bMoveWindow)
  1358. {
  1359. UpdateZOrder();
  1360. CSize szClient = CalcDynamicLayout(CalcClientWidth());
  1361. SetCommandButtonPos();
  1362. SetLinkButtonPos();
  1363. SetVerifyButtonPos();
  1364. SetExpandoButtonPos();
  1365. SetLinkCtrlPos();
  1366. m_strContent.SetFinalRect(m_rcContent);
  1367. m_strMainInstruction.SetFinalRect(m_rcMainInstruction);
  1368. m_strExpandedInformation.SetFinalRect(m_rcExpandedInformation);
  1369. m_strFooter.SetFinalRect(m_rcFooter);
  1370. ResizeParentToFit(szClient, bMoveWindow);
  1371. RedrawWindow(0, 0, RDW_ALLCHILDREN | RDW_INVALIDATE);
  1372. }
  1373. BOOL CXTPTaskDialogClient::ResizeParentToFit(CSize szClient, BOOL bMoveWindow)
  1374. {
  1375. CXTPWindowRect rc(this);
  1376. CRect rcParent = IsPositionRelativeToWindow()?
  1377. CXTPWindowRect(m_pConfig->hwndParent): XTPMultiMonitor()->GetWorkArea(m_pConfig->hwndParent);
  1378. CPoint ptPos((rcParent.left + rcParent.right - szClient.cx) / 2 - 3,
  1379. (rcParent.top + rcParent.bottom - szClient.cy) / 2 - 12);
  1380. CRect rcWindow(ptPos, szClient);
  1381. AdjustWindowRectEx(rcWindow, GetStyle(), FALSE, GetExStyle());
  1382. //rcWindow.InflateRect(m_ptMargin.x, m_ptMargin.y);
  1383. if (bMoveWindow)
  1384. MoveWindow(rcWindow);
  1385. else
  1386. SetWindowPos(0, 0, 0, rcWindow.Width(), rcWindow.Height(), SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  1387. return TRUE;
  1388. }
  1389. //---------------------------------------------------------------------------
  1390. // Rendering
  1391. //---------------------------------------------------------------------------
  1392. void CXTPTaskDialogClient::DrawBackground(CDC* pDC, CRect rect)
  1393. {
  1394. pDC->FillSolidRect(&rect, m_crFooter);
  1395. if (m_bThemeReady)
  1396. {
  1397. pDC->FillSolidRect(rect.left, rect.top, rect.Width(), m_rcCommandButtons.top, m_crContext);
  1398. if (m_rcCommandButtons.top != m_rcCommandButtons.bottom)
  1399. {
  1400. pDC->FillSolidRect(rect.left, m_rcCommandButtons.top,  rect.Width(), 1, m_cr3DLight);
  1401. }
  1402. if (!m_rcFooter.IsRectEmpty())
  1403. {
  1404. pDC->FillSolidRect(rect.left, m_rcCommandButtons.bottom,  rect.Width(), 1, m_cr3DLight);
  1405. pDC->FillSolidRect(rect.left, m_rcCommandButtons.bottom + 1,  rect.Width(), 1, m_cr3DHighLight);
  1406. }
  1407. if (m_bExpanded && !m_strExpandedInformation.IsEmpty() && IsExpandFooterArea() && !m_rcExpandedInformation.IsRectEmpty())
  1408. {
  1409. pDC->FillSolidRect(rect.left, m_rcExpandedInformation.top - m_ptMargin.y,  rect.Width(), 1, m_cr3DLight);
  1410. pDC->FillSolidRect(rect.left, m_rcExpandedInformation.top - m_ptMargin.y + 1,  rect.Width(), 1, m_cr3DHighLight);
  1411. }
  1412. }
  1413. else
  1414. {
  1415. if (!m_rcFooter.IsRectEmpty())
  1416. {
  1417. pDC->FillSolidRect(rect.left, m_rcCommandButtons.bottom + 1, rect.Width(), 1, m_cr3DShadow);
  1418. }
  1419. if (m_bExpanded && !m_strExpandedInformation.IsEmpty() && IsExpandFooterArea() && !m_rcExpandedInformation.IsRectEmpty())
  1420. {
  1421. pDC->FillSolidRect(rect.left, m_rcExpandedInformation.top - m_ptMargin.y,  rect.Width(), 1, m_cr3DShadow);
  1422. }
  1423. }
  1424. }
  1425. void CXTPTaskDialogClient::DrawIcon(CDC* pDC, HICON hIcon, CPoint pt, CSize sz)
  1426. {
  1427. DWORD dwLayout = XTPDrawHelpers()->IsContextRTL(pDC);
  1428. if (dwLayout & LAYOUT_RTL)
  1429. XTPDrawHelpers()->SetContextRTL(pDC, dwLayout | LAYOUT_BITMAPORIENTATIONPRESERVED);
  1430. ::DrawIconEx(*pDC, pt.x, pt.y, hIcon, sz.cx, sz.cy, 0, NULL, DI_NORMAL);
  1431. if (dwLayout & LAYOUT_RTL)
  1432. XTPDrawHelpers()->SetContextRTL(pDC, dwLayout);
  1433. }
  1434. void CXTPTaskDialogClient::DrawText(CDC* pDC, const CStringMarkup& strItemText, CRect rcItem, COLORREF clrText, CFont* pFont)
  1435. {
  1436. if (!rcItem.IsRectEmpty() && !strItemText.IsEmpty())
  1437. {
  1438. if (strItemText.m_pUIElement)
  1439. {
  1440. XTPMarkupSetDefaultFont(m_pMarkupContext, (HFONT)pFont->GetSafeHandle(), clrText);
  1441. XTPMarkupRenderElement(strItemText.m_pUIElement, pDC->GetSafeHdc(), strItemText.m_rcFinalRect);
  1442. }
  1443. else
  1444. {
  1445. pDC->SetTextColor(clrText);
  1446. CXTPFontDC fontDC(pDC, pFont);
  1447. pDC->DrawText(strItemText, rcItem, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_TOP);
  1448. }
  1449. }
  1450. }
  1451. void CXTPTaskDialogClient::DrawMainInstruction(CDC* pDC)
  1452. {
  1453. if (m_hIconMain)
  1454. {
  1455. DrawIcon(pDC, m_hIconMain, m_ptMargin, m_sizeIconMain);
  1456. }
  1457. DrawText(pDC, m_strMainInstruction, m_rcMainInstruction, m_crMainText, &m_fontLarge);
  1458. }
  1459. void CXTPTaskDialogClient::DrawContent(CDC* pDC)
  1460. {
  1461. if (m_rcContent.IsRectEmpty())
  1462. return;
  1463. if (!::IsWindow(m_wndContent.m_hWnd))
  1464. {
  1465. DrawText(pDC, m_strContent, m_rcContent, m_crContextText, &m_font);
  1466. }
  1467. }
  1468. void CXTPTaskDialogClient::DrawExpandedInfo(CDC* pDC)
  1469. {
  1470. if (m_rcExpandedInformation.IsRectEmpty() || m_strExpandedInformation.IsEmpty() || !m_bExpanded)
  1471. return;
  1472. if (!::IsWindow(m_wndExpandedInformation.m_hWnd))
  1473. {
  1474. DrawText(pDC, m_strExpandedInformation, m_rcExpandedInformation, IsExpandFooterArea() ? m_crFooterText : m_crContextText, &m_font);
  1475. }
  1476. }
  1477. void CXTPTaskDialogClient::DrawFootNote(CDC* pDC)
  1478. {
  1479. if (m_rcFooter.IsRectEmpty())
  1480. return;
  1481. if (m_hIconFooter)
  1482. {
  1483. DrawIcon(pDC, m_hIconFooter, CPoint(m_ptMargin.x + 2, m_rcFooter.top), m_sizeIconFooter);
  1484. }
  1485. if (!::IsWindow(m_wndFooter.m_hWnd))
  1486. {
  1487. DrawText(pDC, m_strFooter, m_rcFooter, m_crFooterText, &m_font);
  1488. }
  1489. }
  1490. void CXTPTaskDialogClient::OnExpandExpandoClicked()
  1491. {
  1492. if (!m_pBtnExpando)
  1493. return;
  1494. CString strButtonText = m_bExpanded ? m_strExpandedControlText: m_strCollapsedControlText;
  1495. m_pBtnExpando->SetWindowText(strButtonText);
  1496. m_pBtnExpando->SetChecked(m_bExpanded);
  1497. RecalcLayout();
  1498. }