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

对话框与窗口

开发平台:

Visual C++

  1. // XTPTaskDialogControls.cpp
  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/Resource.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPColorManager.h"
  25. #include "Common/XTPResourceManager.h"
  26. #include "Common/XTPVc50Helpers.h"
  27. #include "Common/XTPSystemHelpers.h"
  28. #include "XTButton.h"
  29. #include "XTPTaskDialogAPI.h"
  30. #include "XTPTaskDialogControls.h"
  31. #ifndef WM_UPDATEUISTATE
  32. #define WM_UPDATEUISTATE    0x0128
  33. #endif
  34. #ifdef _DEBUG
  35. #define new DEBUG_NEW
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CXTPTaskDialogLinkCtrl
  41. CXTPTaskDialogLinkCtrl::CXTPTaskDialogLinkCtrl()
  42. : m_nFocused(-1)
  43. , m_crBack(COLORREF_NULL)
  44. , m_crText(GetXtremeColor(COLOR_WINDOWTEXT))
  45. , m_crTextLink(RGB(0x00, 0x66, 0xcc))
  46. , m_hcurHand(NULL)
  47. , m_bPreSubclassWindow(TRUE)
  48. {
  49. // try loading system hand cursor first.
  50. m_hcurHand = ::LoadCursor(NULL, MAKEINTRESOURCE(32649));
  51. // if this fails load default.
  52. if (m_hcurHand == NULL)
  53. {
  54. m_hcurHand = XTPResourceManager()->LoadCursor(XTP_IDC_HAND);
  55. ASSERT(m_hcurHand != NULL);
  56. }
  57. }
  58. CXTPTaskDialogLinkCtrl::~CXTPTaskDialogLinkCtrl()
  59. {
  60. RemoveAllLinks();
  61. }
  62. void CXTPTaskDialogLinkCtrl::RemoveAllLinks()
  63. {
  64. for (int i = 0; i < m_arrLinks.GetSize(); i++)
  65. {
  66. delete m_arrLinks[i];
  67. }
  68. m_arrLinks.RemoveAll();
  69. }
  70. IMPLEMENT_DYNCREATE(CXTPTaskDialogLinkCtrl, CWnd)
  71. BEGIN_MESSAGE_MAP(CXTPTaskDialogLinkCtrl, CWnd)
  72. //{{AFX_MSG_MAP(CXTPTaskDialogLinkCtrl)
  73. ON_WM_PAINT()
  74. ON_WM_ERASEBKGND()
  75. ON_WM_SETCURSOR()
  76. ON_WM_LBUTTONDOWN()
  77. ON_WM_LBUTTONUP()
  78. ON_WM_NCHITTEST_EX()
  79. ON_WM_SETFOCUS()
  80. ON_WM_KILLFOCUS()
  81. ON_WM_GETDLGCODE()
  82. ON_WM_KEYDOWN()
  83. ON_MESSAGE(WM_SETTEXT, OnSetText)
  84. ON_MESSAGE(WM_UPDATEUISTATE, OnUpdateUIState)
  85. //}}AFX_MSG_MAP
  86. END_MESSAGE_MAP()
  87. /////////////////////////////////////////////////////////////////////////////
  88. // CXTPTaskDialogLinkCtrl message handlers
  89. CXTPTaskDialogLinkCtrl::LINKITEM* CXTPTaskDialogLinkCtrl::HitTest(CPoint pt) const
  90. {
  91. for (int i = 0; i < m_arrLinks.GetSize(); i++)
  92. {
  93. LINKITEM* pItem = m_arrLinks[i];
  94. for (int j = 0; j < pItem->arrParts.GetSize(); j++)
  95. {
  96. if (::PtInRect(&pItem->arrParts[j], pt))
  97. return pItem;
  98. }
  99. }
  100. return NULL;
  101. }
  102. void CXTPTaskDialogLinkCtrl::OnPaint()
  103. {
  104. CPaintDC dc(this);
  105. CXTPClientRect rClient(this);
  106. CXTPBufferDC memDC(dc);
  107. if (m_crBack != COLORREF_NULL)
  108. memDC.FillSolidRect(&rClient, m_crBack);
  109. else
  110. {
  111. HBRUSH hBrush = (HBRUSH)GetParent()->SendMessage(WM_CTLCOLORSTATIC, (WPARAM)memDC.GetSafeHdc(), (LPARAM)m_hWnd);
  112. if (hBrush)
  113. {
  114. ::FillRect(memDC.GetSafeHdc(), rClient, hBrush);
  115. }
  116. else
  117. {
  118. memDC.FillSolidRect(rClient, GetXtremeColor(COLOR_3DFACE));
  119. }
  120. }
  121. memDC.SetBkMode(TRANSPARENT);
  122. DrawText(&memDC, rClient);
  123. }
  124. int CXTPTaskDialogLinkCtrl::DrawTextPartText(CDC* pDC, CString strBuffer, int x, int y, LINKITEM* pItem)
  125. {
  126. if (strBuffer.IsEmpty())
  127. return 0;
  128. CSize sz = pDC->GetTextExtent(strBuffer);
  129. pDC->DrawText(strBuffer, CRect(x, y, x + sz.cx + 10, y + sz.cy), DT_TOP | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE);
  130. CRect rcItem(x, y, x + sz.cx, y + sz.cy);
  131. if (pItem)
  132. {
  133. if (m_nFocused == pItem->nIndex)
  134. {
  135. COLORREF clr = pDC->SetTextColor(m_crText);
  136. pDC->DrawFocusRect(rcItem);
  137. pDC->SetTextColor(clr);
  138. }
  139. pItem->arrParts.Add(rcItem);
  140. }
  141. return sz.cx;
  142. }
  143. void CXTPTaskDialogLinkCtrl::DrawTextPart(CDC* pDC, int&x, int&y, int nWidth, CString strBuffer, LINKITEM* pItem)
  144. {
  145. CXTPFontDC fontDC(pDC, pItem && m_fontUL.GetSafeHandle() ? &m_fontUL : GetFont(), pItem ? m_crTextLink :m_crText);
  146. int nTextHeight = pDC->GetTextExtent(_T("XXX"), 3).cy;
  147. int nStartPos = 0;
  148. int nGoodPos = 0;
  149. while (nStartPos < strBuffer.GetLength())
  150. {
  151. TCHAR t = strBuffer[nStartPos];
  152. if (t == _T(' ') || t == _T('t') || t == _T('n'))
  153. {
  154. CString strPart = strBuffer.Left(nStartPos);
  155. if (x + pDC->GetTextExtent(strPart).cx > nWidth)
  156. {
  157. if (x == 0 && nGoodPos == 0)
  158. nGoodPos = nStartPos - 1;
  159. if (nGoodPos > 0)
  160. {
  161. strPart = strBuffer.Left(nGoodPos);
  162. DrawTextPartText(pDC, strPart, x, y, pItem);
  163. DELETE_S(strBuffer, 0, nGoodPos + 1);
  164. nStartPos -= nGoodPos + 1;
  165. }
  166. else
  167. {
  168. if (strBuffer[0] == _T(' '))
  169. {
  170. DELETE_S(strBuffer, 0);
  171. nStartPos--;
  172. }
  173. }
  174. x = 0;
  175. y += nTextHeight;
  176. nGoodPos = 0;
  177. if (t != _T('n')) continue;
  178. }
  179. else
  180. nGoodPos = nStartPos;
  181. }
  182. if (t == _T('n'))
  183. {
  184. CString strPart = strBuffer.Left(nStartPos);
  185. DrawTextPartText(pDC, strPart, x, y, pItem);
  186. DELETE_S(strBuffer, 0, nStartPos + 1);
  187. x = 0;
  188. y += nTextHeight;
  189. nStartPos = nGoodPos = 0;
  190. continue;
  191. }
  192. nStartPos++;
  193. }
  194. CString strPart = strBuffer;
  195. if (x + pDC->GetTextExtent(strPart).cx > nWidth)
  196. {
  197. if (nGoodPos != 0)
  198. {
  199. strPart = strBuffer.Left(nGoodPos);
  200. DrawTextPartText(pDC, strPart, x, y, pItem);
  201. DELETE_S(strBuffer, 0, nGoodPos + 1);
  202. }
  203. x = 0;
  204. y += nTextHeight;
  205. }
  206. int nLength = DrawTextPartText(pDC, strBuffer, x, y, pItem);
  207. x += nLength;
  208. }
  209. void CXTPTaskDialogLinkCtrl::DrawText(CDC* pDC, CRect rClient)
  210. {
  211. if (m_arrLinks.GetSize() == 0)
  212. {
  213. CXTPFontDC fontDC(pDC, GetFont(), m_crText);
  214. pDC->DrawText(m_strBuffer, rClient, DT_TOP | DT_WORDBREAK | DT_NOPREFIX);
  215. return;
  216. }
  217. int x = 0, y = 0, nWidth = rClient.Width();
  218. CString strBuffer = m_strBuffer;
  219. int nPos = 0;
  220. for (int i = 0; i < m_arrLinks.GetSize(); i++)
  221. {
  222. LINKITEM* pItem = m_arrLinks.GetAt(i);
  223. int iStart = pItem->nStart;
  224. int iCount = pItem->strLabel.GetLength();
  225. pItem->arrParts.RemoveAll();
  226. DrawTextPart(pDC, x, y, nWidth, m_strBuffer.Mid(nPos, iStart - nPos), NULL);
  227. DrawTextPart(pDC, x, y, nWidth, m_strBuffer.Mid(iStart, iCount), pItem);
  228. nPos = iStart + iCount;
  229. }
  230. DrawTextPart(pDC, x, y, nWidth, m_strBuffer.Mid(nPos, m_strBuffer.GetLength() - nPos), NULL);
  231. }
  232. BOOL CXTPTaskDialogLinkCtrl::OnEraseBkgnd(CDC* pDC)
  233. {
  234. UNREFERENCED_PARAMETER(pDC);
  235. return TRUE;
  236. }
  237. BOOL CXTPTaskDialogLinkCtrl::PreCreateWindow(CREATESTRUCT& cs)
  238. {
  239. if (!CWnd::PreCreateWindow(cs))
  240. return FALSE;
  241. //
  242. // PreCreateWindow is called when a control is dynamically
  243. // created. We want to set m_bPreSubclassWindow to FALSE
  244. // here so the control is initialized from CWnd::Create and
  245. // not CWnd::PreSubclassWindow.
  246. //
  247. m_bPreSubclassWindow = FALSE;
  248. return TRUE;
  249. }
  250. void CXTPTaskDialogLinkCtrl::PreSubclassWindow()
  251. {
  252. CWnd::PreSubclassWindow();
  253. if (m_bPreSubclassWindow)
  254. {
  255. RemoveAllLinks();
  256. GetWindowText(m_strBuffer);
  257. ExtractLinks(m_strBuffer);
  258. DefWindowProc(WM_SETTEXT, 0, (LPARAM)(LPCTSTR)m_strBuffer);
  259. if (m_arrLinks.GetSize() > 0 && GetFont())
  260. {
  261. LOGFONT lf;
  262. GetFont()->GetLogFont(&lf);
  263. lf.lfUnderline = 1;
  264. m_fontUL.DeleteObject();
  265. m_fontUL.CreateFontIndirect(&lf);
  266. }
  267. Invalidate(FALSE);
  268. }
  269. }
  270. LRESULT CXTPTaskDialogLinkCtrl::OnSetText(WPARAM, LPARAM lParam)
  271. {
  272. RemoveAllLinks();
  273. m_strBuffer = (LPCTSTR)lParam;
  274. ExtractLinks(m_strBuffer);
  275. DefWindowProc(WM_SETTEXT, 0, (LPARAM)(LPCTSTR)m_strBuffer);
  276. Invalidate(FALSE);
  277. return m_strBuffer.GetLength();
  278. }
  279. BOOL CXTPTaskDialogLinkCtrl::Create(const CRect& rect, CString& strBuffer, CFont* pFont, CWnd* pParentWnd)
  280. {
  281. RemoveAllLinks();
  282. if (strBuffer.IsEmpty() || !pFont->GetSafeHandle() || !::IsWindow(pParentWnd->GetSafeHwnd()))
  283. return FALSE;
  284. m_strBuffer = strBuffer;
  285. if (!ExtractLinks(m_strBuffer))
  286. return FALSE;
  287. if (!CStatic::Create(0, WS_CHILD | WS_VISIBLE | WS_TABSTOP, rect, pParentWnd, 0))
  288. return FALSE;
  289. LOGFONT lf;
  290. pFont->GetLogFont(&lf);
  291. lf.lfUnderline = 1;
  292. m_fontUL.DeleteObject();
  293. m_fontUL.CreateFontIndirect(&lf);
  294. SetFont(pFont);
  295. DefWindowProc(WM_SETTEXT, 0, (LPARAM)(LPCTSTR)m_strBuffer);
  296. strBuffer = m_strBuffer;
  297. return TRUE;
  298. }
  299. DWORD CXTPTaskDialogLinkCtrl::GetLinkPos(CString strBuffer, int iPos /*= 0*/)
  300. {
  301. strBuffer.MakeLower();
  302. int iStart = FIND_S(strBuffer, _T("<a href=""), iPos);
  303. if (iStart == -1)
  304. return NULL;
  305. int iValid = FIND_S(strBuffer, _T("""), iStart);
  306. if (iValid == -1)
  307. return NULL;
  308. int iEnd = FIND_S(strBuffer, _T("</a>"), iValid);
  309. if (iEnd == -1)
  310. return NULL;
  311. return MAKELONG(iStart, (iEnd + 4) - iStart);
  312. }
  313. BOOL CXTPTaskDialogLinkCtrl::ExtractLinks(CString& strBuffer)
  314. {
  315. m_arrLinks.RemoveAll();
  316. for (DWORD dwPos = GetLinkPos(strBuffer); dwPos;)
  317. {
  318. int iStart = LOWORD(dwPos);
  319. int iCount = HIWORD(dwPos);
  320. LINKITEM* pItem = new LINKITEM();
  321. CString strLink = strBuffer.Mid(iStart,iCount);
  322. // extract the link and execute strings from the link.
  323. AfxExtractSubString(pItem->strUrl, strLink, 1, '"');
  324. AfxExtractSubString(pItem->strUrl, pItem->strUrl,  0, '"');
  325. AfxExtractSubString(pItem->strLabel, strLink, 1, '>');
  326. AfxExtractSubString(pItem->strLabel, pItem->strLabel, 0, '<');
  327. // reformat text to remove link tags.
  328. CString strTemp = strBuffer.Left(iStart);
  329. strTemp  += pItem->strLabel;
  330. strTemp  += strBuffer.Right(strBuffer.GetLength()-(iStart + iCount));
  331. strBuffer = strTemp;
  332. pItem->nStart = iStart;
  333. pItem->nIndex = (int)m_arrLinks.Add(pItem);
  334. dwPos = GetLinkPos(strBuffer);
  335. }
  336. return (m_arrLinks.GetSize() > 0);
  337. }
  338. LRESULT CXTPTaskDialogLinkCtrl::OnNcHitTest(CPoint point)
  339. {
  340. ScreenToClient(&point);
  341. if (HitTest(point))
  342. {
  343. return HTCLIENT;
  344. }
  345. return (LRESULT)HTTRANSPARENT;
  346. }
  347. void CXTPTaskDialogLinkCtrl::FocusItem(int iFocusItem)
  348. {
  349. if (m_nFocused != iFocusItem)
  350. {
  351. m_nFocused = iFocusItem;
  352. Invalidate(FALSE);
  353. }
  354. }
  355. UINT CXTPTaskDialogLinkCtrl::OnGetDlgCode()
  356. {
  357. const MSG& msg = AfxGetThreadState()->m_lastSentMsg;
  358. if (!msg.lParam)
  359. return DLGC_UNDEFPUSHBUTTON;
  360. LPMSG lpMsg = (LPMSG)msg.lParam;
  361. if (lpMsg->message == WM_CHAR)
  362. {
  363. if (lpMsg->wParam == VK_TAB)
  364. return DLGC_WANTTAB;
  365. if (lpMsg->wParam == VK_RETURN)
  366. return DLGC_WANTCHARS;
  367. }
  368. if (lpMsg->message == WM_KEYDOWN)
  369. {
  370. UINT nChar = (UINT)lpMsg->wParam;
  371. if ((nChar == VK_RETURN || nChar == VK_SPACE) && (m_nFocused != -1))
  372. return DLGC_WANTALLKEYS;
  373. if (nChar == VK_TAB)
  374. {
  375. if (GetKeyState(VK_SHIFT) >= 0)
  376. {
  377. if (m_nFocused < m_arrLinks.GetSize() - 1)
  378. {
  379. FocusItem(m_nFocused + 1);
  380. return DLGC_WANTTAB;
  381. }
  382. }
  383. else
  384. {
  385. if (m_nFocused > 0)
  386. {
  387. FocusItem(m_nFocused - 1);
  388. return DLGC_WANTTAB;
  389. }
  390. }
  391. }
  392. }
  393. return DLGC_UNDEFPUSHBUTTON;
  394. }
  395. void CXTPTaskDialogLinkCtrl::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
  396. {
  397. if ((nChar == VK_RETURN || nChar == VK_SPACE) && (m_nFocused != -1))
  398. {
  399. GetOwner()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
  400. }
  401. }
  402. void CXTPTaskDialogLinkCtrl::OnLButtonDown(UINT /*nFlags*/, CPoint point)
  403. {
  404. LINKITEM* pItem = HitTest(point);
  405. if (pItem)
  406. {
  407. FocusItem(pItem->nIndex);
  408. SetFocus();
  409. }
  410. else
  411. {
  412. FocusItem(-1);
  413. }
  414. }
  415. void CXTPTaskDialogLinkCtrl::OnSetFocus(CWnd* /*pOldWnd*/)
  416. {
  417. if (m_nFocused == -1)
  418. {
  419. FocusItem(0);
  420. }
  421. }
  422. void CXTPTaskDialogLinkCtrl::OnKillFocus(CWnd* /*pNewWnd*/)
  423. {
  424. FocusItem(-1);
  425. }
  426. CXTPTaskDialogLinkCtrl::LINKITEM* CXTPTaskDialogLinkCtrl::GetFocusedLink() const
  427. {
  428. return m_nFocused >= 0 && m_nFocused < m_arrLinks.GetSize() ? m_arrLinks[m_nFocused] : NULL;
  429. }
  430. void CXTPTaskDialogLinkCtrl::OnLButtonUp(UINT /*nFlags*/, CPoint point)
  431. {
  432. LINKITEM* pItem = HitTest(point);
  433. if (pItem && pItem->nIndex == m_nFocused)
  434. {
  435. GetOwner()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd );
  436. }
  437. }
  438. BOOL CXTPTaskDialogLinkCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  439. {
  440. if (nHitTest == HTCLIENT && (m_hcurHand != NULL))
  441. {
  442. ::SetCursor(m_hcurHand);
  443. return TRUE;
  444. }
  445. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  446. }
  447. LRESULT CXTPTaskDialogLinkCtrl::OnUpdateUIState(WPARAM wParam, LPARAM lParam)
  448. {
  449. LRESULT lResult = ::DefWindowProc(m_hWnd, WM_UPDATEUISTATE, wParam, lParam);
  450. Invalidate(FALSE);
  451. return lResult;
  452. }
  453. //===========================================================================
  454. // CXTPTaskButtonTheme
  455. //===========================================================================
  456. const UINT  xtpDluMargin           = 5;   // non-client margin.
  457. CXTPTaskButtonTheme::CXTPTaskButtonTheme(BOOL bThemeReady)
  458. {
  459. m_bThemeReady = bThemeReady;
  460. m_ptMargin = XTPDlu2Pix(xtpDluMargin, xtpDluMargin);
  461. m_pFontTitle = NULL;
  462. m_bOffsetHiliteText = FALSE;
  463. }
  464. CXTPTaskButtonTheme::CXTPTaskButtonTheme()
  465. {
  466. m_themeWrapper.OpenThemeData(0, L"BUTTON");
  467. m_bThemeReady = m_themeWrapper.IsAppThemed();
  468. m_ptMargin = XTPDlu2Pix(xtpDluMargin, xtpDluMargin);
  469. m_pFontTitle = NULL;
  470. m_bOffsetHiliteText = FALSE;
  471. }
  472. BOOL CXTPTaskButtonTheme::DrawButtonThemeBackground(LPDRAWITEMSTRUCT lpDIS, CXTButton* pButton)
  473. {
  474. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  475. CRect rcItem(lpDIS->rcItem);
  476. if (pButton->GetChecked())
  477. pDC->FillSolidRect(rcItem, m_crBorderHilite);
  478. else if ((lpDIS->itemState & ODS_SELECTED) || pButton->GetHilite())
  479. {
  480. pDC->FillSolidRect(rcItem, m_crBack);
  481. }
  482. else
  483. {
  484. HBRUSH hBrush = (HBRUSH)pButton->GetParent()->SendMessage(WM_CTLCOLORBTN, (WPARAM)pDC->GetSafeHdc(), (LPARAM)pButton->GetSafeHwnd());
  485. if (hBrush)
  486. {
  487. ::FillRect(pDC->GetSafeHdc(), rcItem, hBrush);
  488. }
  489. else
  490. {
  491. pDC->FillSolidRect(rcItem, m_crBack);
  492. }
  493. }
  494. if (lpDIS->itemState & ODS_SELECTED)
  495. {
  496. pDC->Draw3dRect(rcItem, m_crBorder3DShadow, m_crBorder3DHilite);
  497. rcItem.DeflateRect(1,1);
  498. pDC->Draw3dRect(rcItem, m_crBorderShadow, m_crBorderHilite);
  499. }
  500. else if (pButton->GetHilite())
  501. {
  502. pDC->Draw3dRect(rcItem, m_crBorder3DHilite, m_crBorder3DShadow);
  503. rcItem.DeflateRect(1,1);
  504. pDC->Draw3dRect(rcItem, m_crBorderHilite, m_crBorderShadow);
  505. }
  506. if (pButton->GetButtonStyle() == BS_DEFPUSHBUTTON)
  507. {
  508. pDC->Draw3dRect(CRect(lpDIS->rcItem), m_crBorderActive, m_crBorderActive);
  509. }
  510. return TRUE;
  511. }
  512. BOOL CXTPTaskButtonTheme::DrawWinThemeBackground(LPDRAWITEMSTRUCT lpDIS, CXTButton* pButton)
  513. {
  514. if (m_bThemeReady)
  515. {
  516. CRect rcItem(lpDIS->rcItem);
  517. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  518. HBRUSH hBrush = (HBRUSH)pButton->GetParent()->SendMessage(WM_CTLCOLORBTN, (WPARAM)pDC->GetSafeHdc(), (LPARAM)pButton->GetSafeHwnd());
  519. if (hBrush)
  520. {
  521. ::FillRect(pDC->GetSafeHdc(), rcItem, hBrush);
  522. }
  523. else
  524. {
  525. pDC->FillSolidRect(rcItem, m_crBack);
  526. }
  527. if (!m_themeWrapper.ThemeDataOpen())
  528. m_themeWrapper.OpenThemeData(0, L"BUTTON");
  529. if (m_themeWrapper.IsAppThemed() && XTPSystemVersion()->IsWinVistaOrGreater())
  530. {
  531. CRect rcButton(rcItem);
  532. int iStateId = (lpDIS->itemState & ODS_SELECTED) ? PBS_PRESSED :
  533. pButton->GetHilite() ? PBS_HOT :
  534. pButton->GetButtonStyle() == BS_DEFPUSHBUTTON ? PBS_DEFAULTED : PBS_NORMAL;
  535. if ((lpDIS->itemState & ODS_DISABLED) != 0)
  536. iStateId = PBS_DISABLED;
  537. if (SUCCEEDED(m_themeWrapper.DrawThemeBackground(pDC->GetSafeHdc(),
  538. 6, iStateId, &rcButton, NULL)))
  539. {
  540. return TRUE;
  541. }
  542. }
  543. XTPDrawHelpers()->ExcludeCorners(pDC, rcItem);
  544. BOOL bSelected = (lpDIS->itemState & ODS_SELECTED);
  545. if (bSelected)
  546. {
  547. pDC->FillSolidRect(rcItem, m_crBackSelected);
  548. pDC->Draw3dRect(rcItem, m_crBorderHilite, m_crBorderHilite);
  549. rcItem.DeflateRect(1,1);
  550. XTPDrawHelpers()->DrawLine(pDC, rcItem.left, rcItem.top, rcItem.Width(), 0, m_crBorder3DShadow);
  551. rcItem.top += 1;
  552. pDC->Draw3dRect(&rcItem, m_crBorder3DHilite, m_crBorder3DHilite);
  553. rcItem.DeflateRect(1,1);
  554. pDC->Draw3dRect(&rcItem, m_crBorderShadow, m_crBorderShadow);
  555. }
  556. else if (pButton->GetHilite())
  557. {
  558. XTPDrawHelpers()->GradientFill(pDC, &rcItem, m_crBack, m_crBorderShadow, FALSE);
  559. pDC->Draw3dRect(rcItem, m_crBorderHilite, m_crBorderHilite);
  560. rcItem.DeflateRect(1,1);
  561. pDC->Draw3dRect(&rcItem, m_crBack, m_crBack);
  562. }
  563. if (pButton->GetButtonStyle() == BS_DEFPUSHBUTTON)
  564. {
  565. if (!bSelected && !pButton->GetHilite())
  566. pDC->Draw3dRect(rcItem, m_crBorderActive, m_crBorderActive);
  567. }
  568. return TRUE;
  569. }
  570. return FALSE;
  571. }
  572. void CXTPTaskButtonTheme::DrawButtonIcon(CDC* pDC, UINT nState, CRect& rcItem, CXTButton* pButton)
  573. {
  574. if (pButton == NULL || m_bShowIcon == FALSE)
  575. return;
  576. CXTPImageManagerIcon* pIcon = pButton->GetIcon();
  577. if (pIcon != NULL)
  578. {
  579. CPoint point = CalculateImagePosition(pDC, nState, rcItem, false, pButton);
  580. if (nState & ODS_DISABLED)
  581. pIcon->Draw(pDC, point, pIcon->GetDisabledIcon(), pButton->GetImageSize());
  582. else if (pButton->GetHilite())
  583. pIcon->Draw(pDC, point, pIcon->GetHotIcon(), pButton->GetImageSize());
  584. else
  585. pIcon->Draw(pDC, point, pIcon->GetIcon(), pButton->GetImageSize());
  586. }
  587. }
  588. CPoint CXTPTaskButtonTheme::GetTextPosition(UINT /*nState*/, CRect& rcItem, CSize& sizeText, CXTButton* pButton)
  589. {
  590. CPoint point;
  591. point.x = m_ptMargin.x;
  592. point.y = rcItem.top + (rcItem.Height()-sizeText.cy)/2;
  593. if (m_bShowIcon && pButton->GetIcon())
  594. point.x += pButton->GetImageSize().cx;
  595. return point;
  596. }
  597. #ifndef ODS_NOACCEL
  598. #define ODS_NOACCEL 0x0100
  599. #endif
  600. void CXTPTaskButtonTheme::DrawButtonText(CDC* pDC, UINT nState, CRect& rcItem, CXTButton* pButton)
  601. {
  602. if (m_strButton.IsEmpty())
  603. GetButtonText(pButton);
  604. CRect rcText = rcItem;
  605. rcText.DeflateRect(m_ptMargin.x,m_ptMargin.y);
  606. if (m_bShowIcon && pButton->GetIcon())
  607. rcText.left += pButton->GetImageSize().cx;
  608. CFont* pFontNote = GetThemeFont(pButton);
  609. CSize sizeNoteText = rcText.Size();
  610. XTPCalcTextSize(m_strNoteText, sizeNoteText, *pFontNote);
  611. CSize sizeCaptText = rcText.Size();
  612. XTPCalcTextSize(m_strCaptText, sizeCaptText, m_pFontTitle ? *m_pFontTitle : *pFontNote);
  613. // get the text size.
  614. CXTPEmptySize sizeText;
  615. sizeText.cy = sizeCaptText.cy + sizeNoteText.cy;
  616. sizeText.cx = __max(sizeCaptText.cx, sizeNoteText.cx);
  617. CPoint point = GetTextPosition(nState, rcItem, sizeText, pButton);
  618. BOOL  bSelected = pButton->GetChecked() || (nState & ODS_SELECTED);
  619. if (bSelected && m_bOffsetHiliteText)
  620. point.Offset(1,1);
  621. // Set the draw state flags.
  622. pDC->SetTextColor(GetTextColor(nState, pButton));
  623. pDC->SetTextAlign(TA_LEFT);
  624. pDC->SetBkMode(TRANSPARENT);
  625. if (!m_strCaptText.IsEmpty())
  626. {
  627. CString strCaptText = m_strCaptText;
  628. if (nState & ODS_NOACCEL)
  629. XTPDrawHelpers()->StripMnemonics(strCaptText);
  630. CXTPFontDC fontDC(pDC, m_pFontTitle ? m_pFontTitle : pFontNote);
  631. CRect rcButton(point, sizeCaptText);
  632. pDC->DrawText(strCaptText, &rcButton, DT_LEFT | DT_TOP | DT_WORDBREAK);
  633. point.y += sizeCaptText.cy + 1;
  634. }
  635. if (!m_strNoteText.IsEmpty())
  636. {
  637. CString strNoteText = m_strNoteText;
  638. CXTPFontDC fontDC(pDC, pFontNote);
  639. CRect rcButton(point, sizeNoteText);
  640. pDC->DrawText(strNoteText, &rcButton, DT_LEFT | DT_TOP | DT_WORDBREAK | DT_NOPREFIX);
  641. }
  642. }
  643. void CXTPTaskButtonTheme::GetButtonText(CXTButton* pButton)
  644. {
  645. if (::IsWindow(pButton->GetSafeHwnd()))
  646. {
  647. pButton->GetWindowText(m_strButton);
  648. m_strCaptText = XTPExtractSubString(m_strButton, 0);
  649. m_strNoteText = XTPExtractSubString(m_strButton, 1);
  650. }
  651. }
  652. void CXTPTaskButtonTheme::SetTitleFont(CFont* pFontTitle)
  653. {
  654. m_pFontTitle = pFontTitle;
  655. }
  656. CFont* CXTPTaskButtonTheme::GetTitleFont()
  657. {
  658. return m_pFontTitle;
  659. }
  660. void CXTPTaskButtonTheme::RefreshMetrics()
  661. {
  662. CXTButtonTheme::RefreshMetrics();
  663. if (m_bThemeReady)
  664. {
  665. COLORREF crWindow = GetXtremeColor(COLOR_WINDOW);
  666. COLORREF cr3dFace = GetXtremeColor(COLOR_3DFACE);
  667. COLORREF cr3dShad = GetXtremeColor(COLOR_3DSHADOW);
  668. m_crBack           = crWindow;
  669. m_crText           = RGB(21,28,85);
  670. m_crTextHilite     = RGB(0x00, 0x4a, 0xe5);
  671. m_crBorderActive   = RGB(0xa3, 0xed, 0xff);
  672. m_crBackSelected   = XTPColorManager()->LightColor(crWindow, cr3dFace, 200);
  673. m_crBorder3DShadow = XTPColorManager()->LightColor(cr3dFace, cr3dShad, 775);
  674. m_crBorder3DHilite = XTPColorManager()->LightColor(cr3dFace, cr3dShad, 875);
  675. m_crBorderShadow   = XTPColorManager()->LightColor(crWindow, cr3dFace, 0);
  676. m_crBorderHilite   = XTPColorManager()->LightColor(cr3dFace, cr3dShad, 175);
  677. }
  678. else
  679. {
  680. m_crBorderActive = m_crBorder3DShadow;
  681. }
  682. }
  683. BOOL CXTPTaskButtonTheme::CanHilite(CXTButton* /*pButton*/)
  684. {
  685. return TRUE;
  686. }
  687. COLORREF CXTPTaskButtonTheme::GetTextColor(UINT nState, CXTButton* pButton)
  688. {
  689. if (nState & ODS_DISABLED)
  690. return GetXtremeColor(COLOR_GRAYTEXT);
  691. if (pButton->GetHilite())
  692. return m_crTextHilite;
  693. return m_crText;
  694. }
  695. void CXTPTaskButtonTheme::DrawFocusRect(CDC* pDC, UINT nState, CRect& rcItem, CXTButton* pButton)
  696. {
  697. rcItem.DeflateRect(1, 1);
  698. CXTButtonTheme::DrawFocusRect(pDC, nState, rcItem, pButton);
  699. }
  700. CPoint CXTPTaskButtonTheme::CalculateImagePosition(CDC* pDC, UINT nState, CRect& rcItem, bool bHasPushedImage, CXTButton* pButton)
  701. {
  702. CPoint point = CXTButtonTheme::CalculateImagePosition(pDC, nState, rcItem, bHasPushedImage, pButton);
  703. if (!m_strNoteText.IsEmpty())
  704. point.y = m_ptMargin.y;
  705. point.x += 2;
  706. return point;
  707. }
  708. //===========================================================================
  709. // CXTPTaskButtonThemeExpando
  710. //===========================================================================
  711. CXTPTaskButtonThemeExpando::CXTPTaskButtonThemeExpando()
  712. {
  713. m_bOffsetHiliteText = FALSE;
  714. }
  715. void CXTPTaskButtonThemeExpando::DrawItem(LPDRAWITEMSTRUCT lpDIS, CXTButton* pButton)
  716. {
  717. // define some temporary variables.
  718. CDC*  pDC = CDC::FromHandle(lpDIS->hDC);
  719. CRect rcItem = lpDIS->rcItem;
  720. pDC->FillSolidRect(rcItem, GetXtremeColor(COLOR_3DFACE));
  721. int   nState = lpDIS->itemState;
  722. // Set the background mode to transparent.
  723. pDC->SetBkColor(GetXtremeColor(COLOR_3DFACE));
  724. // select font into device context.
  725. CXTPFontDC fontDC(pDC, GetThemeFont(pButton));
  726. CString strText;
  727. pButton->GetWindowText(strText);
  728. rcItem.left += 26;
  729. // Remove ampersand
  730. if ((nState & ODS_NOACCEL) != 0)
  731. XTPDrawHelpers()->StripMnemonics(strText);
  732. pDC->SetTextColor(GetXtremeColor(COLOR_BTNTEXT));
  733. pDC->DrawText(strText, rcItem, DT_TOP | DT_WORDBREAK);
  734. // Draw the focus rect if style is set and we have focus.
  735. if ((lpDIS->itemState & ODS_FOCUS) && ((lpDIS->itemState & ODS_NOFOCUSRECT) == 0))
  736. {
  737. pDC->DrawText(strText, rcItem, DT_TOP | DT_WORDBREAK | DT_CALCRECT);
  738. rcItem.InflateRect(1, 0);
  739. pDC->DrawFocusRect(rcItem);
  740. }
  741. rcItem = lpDIS->rcItem;
  742. rcItem.right = rcItem.left + 18;
  743. rcItem.bottom = rcItem.top + min(20, rcItem.Height());
  744. CPoint pt(rcItem.right / 2 - 1, rcItem.bottom / 2 - 3);
  745. bool  bSelected = ((nState & ODS_SELECTED) != 0);
  746. BOOL bDrawStandard = TRUE;
  747. if (UseWinXPThemes(pButton))
  748. {
  749. CXTPWinThemeWrapper themeTaskDialog;
  750. themeTaskDialog.OpenTheme(0, L"TASKDIALOG");
  751. if (themeTaskDialog.IsAppThemed())
  752. {
  753. CRect rcButton(0, 0, 19, 21);
  754. int iStateId = bSelected ? 3 : pButton->GetHilite() ? 2 : 1;
  755. if (pButton->GetChecked()) iStateId += 3;
  756. if (SUCCEEDED(themeTaskDialog.DrawThemeBackground(pDC->GetSafeHdc(),
  757. 13, iStateId, &rcButton, NULL)))
  758. {
  759. return;
  760. }
  761. }
  762. CRect rc(rcItem);
  763. rc.right += 1;
  764. int iStateId = bSelected ? PBS_PRESSED : pButton->GetHilite() ? PBS_HOT : PBS_NORMAL;
  765. if (SUCCEEDED(m_themeWrapper.DrawThemeBackground(pDC->GetSafeHdc(),
  766. BP_PUSHBUTTON, iStateId, &rc, NULL)))
  767. {
  768. bDrawStandard = FALSE;
  769. pt.x += 1;
  770. }
  771. }
  772. if (bDrawStandard)
  773. {
  774. pDC->DrawFrameControl(&rcItem, DFC_BUTTON, (bSelected ? DFCS_PUSHED : 0) | DFCS_BUTTONPUSH);
  775. if (bSelected) pt.Offset(1, 1);
  776. }
  777. if (!pButton->GetChecked())
  778. XTPDrawHelpers()->Triangle(pDC, pt - CPoint(4, 0),
  779. pt + CPoint(4, 0), pt + CPoint(0, 4), GetXtremeColor(COLOR_BTNTEXT));
  780. else
  781. XTPDrawHelpers()->Triangle(pDC, pt - CPoint(4, -4),
  782. pt + CPoint(4, 4), pt + CPoint(0, 0), GetXtremeColor(COLOR_BTNTEXT));
  783. }
  784. //////////////////////////////////////////////////////////////////////////
  785. // CXTPTaskDialogProgressCtrl
  786. #ifndef PBS_MARQUEE
  787. #define PBS_MARQUEE             0x08
  788. #endif
  789. #ifndef PBM_SETMARQUEE
  790. #define PBM_SETMARQUEE          (WM_USER+10)
  791. #endif
  792. #ifndef PBM_SETSTATE
  793. #define PBM_SETSTATE            (WM_USER+16)
  794. #endif
  795. CXTPTaskDialogProgressCtrl::CXTPTaskDialogProgressCtrl()
  796. {
  797. m_nState = -1;
  798. m_nMarqueePos = 0;
  799. m_bMarquee = FALSE;
  800. m_nMarqueeDelay = 0;
  801. }
  802. BEGIN_MESSAGE_MAP(CXTPTaskDialogProgressCtrl, CProgressCtrl)
  803. //{{AFX_MSG_MAP(CXTPTaskDialogProgressCtrl)
  804. ON_WM_PAINT()
  805. ON_MESSAGE(PBM_SETMARQUEE, OnStartMarquee)
  806. ON_MESSAGE(PBM_SETSTATE, OnSetState)
  807. ON_WM_TIMER()
  808. //}}AFX_MSG_MAP
  809. END_MESSAGE_MAP()
  810. void CXTPTaskDialogProgressCtrl::OnPaint()
  811. {
  812. if (HIWORD(XTPSystemVersion()->GetComCtlVersion()) > 5)
  813. {
  814. Default();
  815. return;
  816. }
  817. if (((GetStyle() & PBS_MARQUEE) == 0) || !m_bMarquee)
  818. {
  819. Default();
  820. return;
  821. }
  822. BOOL bVista = XTPSystemVersion()->IsWinVistaOrGreater();
  823. CPaintDC dcPaint(this);
  824. CXTPBufferDC dc(dcPaint);
  825. CXTPClientRect rcClient(this);
  826. dc.FillSolidRect(rcClient, GetXtremeColor(COLOR_3DFACE));
  827. if (m_nState == PBST_ERROR || m_nState == PBST_PAUSED)
  828. return;
  829. rcClient.DeflateRect(1, 1);
  830. CRect rc(rcClient);
  831. int dxBlock = rc.Height() * 2 / 3;
  832. int nSpace = bVista ? 0 : 2;
  833. rc.left = m_nMarqueePos + 1;
  834. for (int i = 0; i < 5; i++)
  835. {
  836. if (rc.left >= rcClient.right)
  837. rc.left = 1;
  838. rc.right = rc.left + dxBlock;
  839. if (rc.right > rcClient.right)
  840. rc.right = rcClient.right;
  841. dc.FillSolidRect(rc, GetXtremeColor(COLOR_HIGHLIGHT));
  842. rc.left = rc.right + nSpace;
  843. }
  844. }
  845. LRESULT CXTPTaskDialogProgressCtrl::OnSetState(WPARAM wParam, LPARAM /*lParam*/)
  846. {
  847. m_nState = (int)wParam;
  848. Default();
  849. return 1;
  850. }
  851. LRESULT CXTPTaskDialogProgressCtrl::OnStartMarquee(WPARAM wParam, LPARAM lParam)
  852. {
  853. m_bMarquee = FALSE;
  854. m_nMarqueePos = 0;
  855. m_nMarqueeDelay = 0;
  856. if (HIWORD(XTPSystemVersion()->GetComCtlVersion()) > 5)
  857. return Default();
  858. if (((GetStyle() & PBS_MARQUEE) == 0))
  859. return Default();
  860. m_bMarquee = wParam && (lParam > 0);
  861. m_nMarqueePos = 0;
  862. KillTimer(101);
  863. if (m_bMarquee)
  864. {
  865. m_nMarqueeDelay = (UINT)lParam;
  866. SetTimer(101, m_nMarqueeDelay, NULL);
  867. }
  868. return 1;
  869. }
  870. void CXTPTaskDialogProgressCtrl::OnTimer(UINT_PTR nIDEvent)
  871. {
  872. if (nIDEvent == 101 && m_bMarquee)
  873. {
  874. CXTPClientRect rcClient(this);
  875. BOOL bVista = XTPSystemVersion()->IsWinVistaOrGreater();
  876. int dxBlock = (rcClient.Height() - 2) * 2 / 3;
  877. int nSpace = bVista ? 0 : 2;
  878. m_nMarqueePos += (dxBlock + nSpace) * (m_nMarqueeDelay > 50 ? 1 : 2);
  879. if (m_nMarqueePos > rcClient.right)
  880. m_nMarqueePos = 0;
  881. Invalidate(FALSE);
  882. return;
  883. }
  884. CWnd::OnTimer(nIDEvent);
  885. }