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

对话框与窗口

开发平台:

Visual C++

  1. // XTButton.cpp : implementation of the CXTPButton 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 "math.h"
  22. #include "Common/XTPWinThemeWrapper.h"
  23. #include "Common/XTPColorManager.h"
  24. #include "Common/XTPDrawHelpers.h"
  25. #include "Common/XTPImageManager.h"
  26. #include "Common/XTPOffice2007Image.h"
  27. #include "Common/XTPMarkupRender.h"
  28. #include "XTPButton.h"
  29. #ifdef _DEBUG
  30. #define new DEBUG_NEW
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. #ifndef WM_QUERYUISTATE
  35. #define WM_UPDATEUISTATE    0x0128
  36. #define WM_QUERYUISTATE     0x0129
  37. #define UISF_HIDEACCEL      0x2
  38. #define UISF_HIDEFOCUS      0x1
  39. #endif
  40. #define DT_HIDEPREFIX       0x00100000
  41. #define BS_HORZMASK   (BS_LEFT | BS_RIGHT | BS_CENTER)
  42. #define BS_VERTMASK   (BS_TOP | BS_BOTTOM | BS_VCENTER)
  43. #define CBR_CLIENTRECT 0
  44. #define CBR_CHECKBOX   1
  45. #define CBR_RADIOBOX   2
  46. #define CBR_CHECKTEXT  3
  47. #define CBR_RADIOTEXT  4
  48. #define CBR_GROUPTEXT  5
  49. #define CBR_GROUPFRAME 6
  50. #define CBR_PUSHBUTTON 7
  51. /////////////////////////////////////////////////////////////////////////////
  52. // CXTPButton
  53. /////////////////////////////////////////////////////////////////////////////
  54. IMPLEMENT_DYNAMIC(CXTPButton, CButton)
  55. CXTPButton::CXTPButton()
  56. {
  57. m_bHot = FALSE;
  58. m_bPushed = FALSE;
  59. m_bChecked = FALSE;
  60. m_bFlatStyle = FALSE;
  61. m_bUseVisualStyle = TRUE;
  62. m_pButtonTheme = new CXTPButtonTheme();
  63. m_pButtonTheme->RefreshMetrics(this);
  64. m_bEnableMarkup = FALSE;
  65. m_pMarkupContext = NULL;
  66. m_pUIElement = NULL;
  67. m_nPushButtonStyle = 0;
  68. m_nBorderGap = 4;
  69. m_nImageGap = 3;
  70. m_pIcon = 0;
  71. m_nImageAlignment = BS_VCENTER | BS_CENTER;
  72. m_nTextImageRelation = xtpButtonImageBeforeText;
  73. m_nBorderStyle = 0;
  74. m_bShowFocus = TRUE;
  75. }
  76. CXTPButton::~CXTPButton()
  77. {
  78. CMDTARGET_RELEASE(m_pButtonTheme);
  79. XTPMarkupReleaseElement(m_pUIElement);
  80. XTPMarkupReleaseContext(m_pMarkupContext);
  81. CMDTARGET_RELEASE(m_pIcon);
  82. }
  83. BEGIN_MESSAGE_MAP(CXTPButton, CXTPButtonBase)
  84. //{{AFX_MSG_MAP(CXTPButton)
  85. ON_WM_ERASEBKGND()
  86. ON_WM_MOUSEMOVE()
  87. ON_WM_SETFOCUS()
  88. ON_WM_KILLFOCUS()
  89. ON_WM_LBUTTONDOWN()
  90. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  91. ON_WM_CHAR()
  92. ON_WM_KEYDOWN()
  93. ON_WM_SYSCOLORCHANGE()
  94. ON_MESSAGE(WM_GETDLGCODE, OnGetDlgCode)
  95. //}}AFX_MSG_MAP
  96. ON_WM_PAINT()
  97. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  98. ON_MESSAGE(BM_SETSTYLE, OnDefaultAndInvalidate)
  99. ON_MESSAGE(BM_SETCHECK, OnDefaultAndInvalidate)
  100. ON_MESSAGE(WM_CAPTURECHANGED, OnDefaultAndInvalidate)
  101. ON_MESSAGE_VOID(WM_ENABLE, OnInvalidate)
  102. ON_MESSAGE(WM_UPDATEUISTATE, OnUpdateUIState)
  103. ON_MESSAGE(BM_SETSTATE, OnSetState)
  104. ON_MESSAGE(WM_SETTEXT, OnSetText)
  105. //}}AFX_MSG_MAP
  106. END_MESSAGE_MAP()
  107. void CXTPButton::OnMouseMove(UINT nFlags, CPoint point)
  108. {
  109. if (GetButtonStyle() == BS_GROUPBOX)
  110. return;
  111. CXTPButtonBase::OnMouseMove(nFlags, point);
  112. CRect rc;
  113. GetClientRect(&rc);
  114. BOOL bHot = rc.PtInRect(point);
  115. if (bHot != m_bHot)
  116. {
  117. m_bHot = bHot;
  118. RedrawButton();
  119. if (m_bHot)
  120. {
  121. TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, HOVER_DEFAULT};
  122. _TrackMouseEvent(&tme);
  123. }
  124. }
  125. }
  126. void CXTPButton::OnMouseLeave()
  127. {
  128. OnMouseMove(0, CPoint(-1, -1));
  129. }
  130. void CXTPButton::OnLButtonDown(UINT nFlags, CPoint point)
  131. {
  132. if (m_nPushButtonStyle == xtpButtonSplitDropDown)
  133. {
  134. CXTPClientRect rcDropDown(this);
  135. rcDropDown.left = rcDropDown.right - 16 - GetBorderGap();
  136. if (rcDropDown.PtInRect(point))
  137. {
  138. DoDropDown();
  139. return;
  140. }
  141. }
  142. CXTPButtonBase::OnLButtonDown(nFlags, point);
  143. }
  144. LRESULT CXTPButton::OnSetState(WPARAM wParam, LPARAM /*lParam*/)
  145. {
  146. BOOL bVisible = GetStyle() & WS_VISIBLE;
  147. if (bVisible) ModifyStyle(WS_VISIBLE, 0);
  148. Default();
  149. if (bVisible) ModifyStyle(0, WS_VISIBLE);
  150. if (m_bPushed == 2)
  151. return 0;
  152. m_bPushed = (wParam != 0);
  153. RedrawButton();
  154. if (m_bPushed && IsDropDownStyle() && IsPushButton() && (m_nPushButtonStyle != xtpButtonSplitDropDown))
  155. {
  156. DoDropDown();
  157. }
  158. return 0;
  159. }
  160. void CXTPButton::DoDropDown()
  161. {
  162. m_bPushed = 2;
  163. RedrawButton();
  164. OnDropDown();
  165. m_bPushed = 0;
  166. RedrawButton();
  167. }
  168. void CXTPButton::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  169. {
  170. if (IsDropDownStyle() && (nChar == VK_SPACE))
  171. {
  172. DoDropDown();
  173. return;
  174. }
  175. if ((m_nPushButtonStyle == xtpButtonDropDown || m_nPushButtonStyle == xtpButtonDropDownRight) && (nChar == VK_RETURN))
  176. {
  177. DoDropDown();
  178. return;
  179. }
  180. CXTPButtonBase::OnChar(nChar, nRepCnt, nFlags);
  181. }
  182. LRESULT CXTPButton::OnGetDlgCode(WPARAM wParam, LPARAM lParam)
  183. {
  184. LRESULT lCode = CXTPButtonBase::OnGetDlgCode();
  185. if (IsDropDownStyle() && lParam && ((LPMSG)lParam)->message == WM_CHAR && wParam == VK_SPACE)
  186. {
  187. lCode |= DLGC_WANTCHARS;
  188. }
  189. if ((m_nPushButtonStyle == xtpButtonDropDown || m_nPushButtonStyle == xtpButtonDropDownRight)
  190. && lParam && (((LPMSG)lParam)->message == WM_KEYDOWN || ((LPMSG)lParam)->message == WM_CHAR) && wParam == VK_RETURN)
  191. {
  192. lCode |= DLGC_WANTALLKEYS;
  193. }
  194. return lCode;
  195. }
  196. void CXTPButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  197. {
  198. if (nChar == VK_SPACE && IsDropDownStyle())
  199. return;
  200. if (nChar == VK_RETURN && (m_nPushButtonStyle == xtpButtonDropDown || m_nPushButtonStyle == xtpButtonDropDownRight))
  201. {
  202. return;
  203. }
  204. CXTPButtonBase::OnKeyDown(nChar, nRepCnt, nFlags);
  205. }
  206. void CXTPButton::OnDropDown()
  207. {
  208. GetParent()->SendMessage(WM_COMMAND,
  209. (WPARAM)MAKELONG(::GetDlgCtrlID(GetSafeHwnd()), CBN_DROPDOWN),
  210. (LPARAM)GetSafeHwnd());
  211. }
  212. void CXTPButton::OnSetFocus(CWnd* pOldWnd)
  213. {
  214. CXTPButtonBase::OnSetFocus(pOldWnd);
  215. RedrawButton();
  216. }
  217. void CXTPButton::OnKillFocus(CWnd* pNewWnd)
  218. {
  219. CXTPButtonBase::OnKillFocus(pNewWnd);
  220. RedrawButton();
  221. }
  222. LRESULT CXTPButton::OnDefaultAndInvalidate(WPARAM, LPARAM)
  223. {
  224. LRESULT lResult = Default();
  225. RedrawButton();
  226. return lResult;
  227. }
  228. void CXTPButton::OnInvalidate()
  229. {
  230. RedrawButton();
  231. }
  232. LRESULT CXTPButton::OnPrintClient(WPARAM wParam, LPARAM lParam)
  233. {
  234. if ((lParam & PRF_CLIENT) == 0)
  235. return Default();
  236. CDC* pDC = CDC::FromHandle((HDC)wParam);
  237. if (pDC) OnDraw(pDC);
  238. return 1;
  239. }
  240. void CXTPButton::OnPaint()
  241. {
  242. CPaintDC dcPaint(this);
  243. OnDraw(&dcPaint);
  244. }
  245. void CXTPButton::OnDraw(CDC* pDC)
  246. {
  247. if ((GetButtonStyle() == BS_GROUPBOX))
  248. {
  249. CFont* pOldFont = pDC->SelectObject(CWnd::GetFont());
  250. pDC->SetBkColor(GetSysColor(COLOR_3DFACE));
  251. pDC->SetBkMode(TRANSPARENT);
  252. DoDraw(pDC);
  253. pDC->SelectObject(pOldFont);
  254. }
  255. else
  256. {
  257. CXTPClientRect rc(this);
  258. CXTPBufferDC memDC(*pDC, rc);
  259. HBRUSH hBrush = (HBRUSH)GetParent()->SendMessage(WM_CTLCOLORBTN, (WPARAM)memDC.GetSafeHdc(), (LPARAM)GetSafeHwnd());
  260. if (hBrush)
  261. {
  262. ::FillRect(memDC.GetSafeHdc(), rc, hBrush);
  263. }
  264. else
  265. {
  266. memDC.FillSolidRect(rc, GetSysColor(COLOR_3DFACE));
  267. }
  268. CFont* pOldFont = memDC.SelectObject(CWnd::GetFont());
  269. memDC.SetBkMode(TRANSPARENT);
  270. DoDraw(&memDC);
  271. memDC.SelectObject(pOldFont);
  272. }
  273. }
  274. void CXTPButton::DoDraw(CDC* pDC)
  275. {
  276. if (IsPushButton())
  277. {
  278. m_pButtonTheme->DrawButtonBackground(pDC, this);
  279. m_pButtonTheme->DrawPushButtonText(pDC, this);
  280. m_pButtonTheme->DrawPushButtonIcon(pDC, this);
  281. if (IsDropDownStyle())
  282. {
  283. m_pButtonTheme->DrawPushButtonDropDown(pDC, this);
  284. }
  285. if (::GetFocus() == m_hWnd && m_bShowFocus)
  286. {
  287. m_pButtonTheme->DrawFocusRect(pDC, this);
  288. }
  289. return;
  290. }
  291. switch (GetButtonStyle())
  292. {
  293. case BS_RADIOBUTTON:
  294. case BS_AUTORADIOBUTTON:
  295. m_pButtonTheme->DrawRadioButtonMark(pDC, this);
  296. m_pButtonTheme->DrawButtonText(pDC, this);
  297. break;
  298. case BS_3STATE:
  299. case BS_AUTO3STATE:
  300. case BS_CHECKBOX:
  301. case BS_AUTOCHECKBOX:
  302. m_pButtonTheme->DrawCheckBoxMark(pDC, this);
  303. m_pButtonTheme->DrawButtonText(pDC, this);
  304. break;
  305. case BS_GROUPBOX:
  306. if (m_nBorderStyle != 2)
  307. {
  308. m_pButtonTheme->DrawGroupBox(pDC, this);
  309. m_pButtonTheme->DrawButtonText(pDC, this);
  310. }
  311. break;
  312. default:
  313. TRACE(_T("Warning: unkown style"));
  314. }
  315. }
  316. LRESULT CXTPButton::OnUpdateUIState(WPARAM wParam, LPARAM lParam)
  317. {
  318. LRESULT lResult = ::DefWindowProc(m_hWnd, WM_UPDATEUISTATE, wParam, lParam);
  319. RedrawButton();
  320. return lResult;
  321. }
  322. LRESULT CXTPButton::OnSetText(WPARAM wParam, LPARAM lParam)
  323. {
  324. BOOL bVisible = GetStyle() & WS_VISIBLE;
  325. if (bVisible) ModifyStyle(WS_VISIBLE, 0);
  326. LRESULT lResult = DefWindowProc(WM_SETTEXT, wParam, lParam);
  327. if (bVisible) ModifyStyle(0, WS_VISIBLE);
  328. InternalTextChanged();
  329. RedrawButton();
  330. return lResult;
  331. }
  332. BOOL CXTPButton::OnEraseBkgnd(CDC* /*pDC*/)
  333. {
  334. return TRUE;
  335. }
  336. void CXTPButton::OnSysColorChange()
  337. {
  338. CXTPButtonBase::OnSysColorChange();
  339. m_pButtonTheme->RefreshMetrics(this);
  340. RedrawButton();
  341. SendMessageToDescendants(WM_SYSCOLORCHANGE, 0, 0L, TRUE, FALSE);
  342. }
  343. //////////////////////////////////////////////////////////////////////////
  344. COLORREF CXTPButton::GetButtonTextColor()
  345. {
  346. return GetSysColor(COLOR_BTNTEXT);
  347. }
  348. COLORREF CXTPButton::GetButtonBackColor()
  349. {
  350. return GetSysColor(COLOR_BTNFACE);
  351. }
  352. BYTE CXTPButton::GetButtonStyle() const
  353. {
  354. BYTE bStyle = BYTE(GetStyle() & 0xF);
  355. return bStyle;
  356. }
  357. CSize CXTPButton::GetImageSize()
  358. {
  359. if (m_pIcon)
  360. return CSize(m_pIcon->GetWidth(), m_pIcon->GetHeight());
  361. return CSize(0, 0);
  362. }
  363. void CXTPButton::DrawImage(CDC* pDC, CRect rc)
  364. {
  365. CXTPImageManagerIcon* pIcon = GetIcon();
  366. if (pIcon)
  367. {
  368. BOOL  bSelected = GetChecked() || IsPushed();
  369. if (!IsWindowEnabled())
  370. {
  371. pIcon->Draw(pDC, rc.TopLeft(), pIcon->GetDisabledIcon(), rc.Size());
  372. }
  373. else if (IsHighlighted() || bSelected)
  374. {
  375. pIcon->Draw(pDC, rc.TopLeft(), GetChecked() ? pIcon->GetCheckedIcon() :
  376. IsPushed() ? pIcon->GetPressedIcon() : pIcon->GetHotIcon(), rc.Size());
  377. }
  378. else
  379. {
  380. pIcon->Draw(pDC, rc.TopLeft(), pIcon->GetIcon(), rc.Size());
  381. }
  382. }
  383. }
  384. BOOL CXTPButton::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  385. {
  386. if (m_pUIElement)
  387. {
  388. if (XTPMarkupRelayMessage(m_pUIElement, message, wParam, lParam, pResult))
  389. return TRUE;
  390. }
  391. return CXTPButtonBase::OnWndMsg(message, wParam, lParam, pResult);
  392. }
  393. int CXTPButton::GetTextAlignment() const
  394. {
  395. DWORD bHorz;
  396. DWORD bVert;
  397. DWORD dwStyle = GetStyle();
  398. bHorz = dwStyle & (BS_LEFT | BS_RIGHT | BS_CENTER);
  399. bVert = dwStyle & (BS_TOP | BS_BOTTOM | BS_VCENTER);
  400. if (!bHorz || !bVert)
  401. {
  402. if (IsPushButton())
  403. {
  404. if (!bHorz)
  405. bHorz = BS_CENTER;
  406. }
  407. else
  408. {
  409. if (!bHorz)
  410. bHorz = BS_LEFT;
  411. }
  412. if (!bVert)
  413. bVert = BS_VCENTER;
  414. }
  415. return bHorz | bVert;
  416. }
  417. CSize CXTPButton::GetGlyphSize(BOOL bCheckBox)
  418. {
  419. CXTPClientRect rcButton(this);
  420. CSize sz(13, 13);
  421. if (m_bUseVisualStyle && m_pButtonTheme->m_themeButton.IsAppThemed())
  422. {
  423. m_pButtonTheme->m_themeButton.GetThemePartSize(NULL,
  424. bCheckBox ? BP_CHECKBOX : BP_RADIOBUTTON,
  425. 1, rcButton, TS_DRAW, &sz);
  426. }
  427. return sz;
  428. }
  429. void CXTPButton::InternalTextChanged()
  430. {
  431. if (m_pMarkupContext)
  432. {
  433. XTPMarkupReleaseElement(m_pUIElement);
  434. m_pUIElement = XTPMarkupParseText(m_pMarkupContext, GetButtonText());
  435. }
  436. }
  437. CString CXTPButton::GetButtonText()
  438. {
  439. CString str;
  440. if (m_hWnd) GetWindowText(str);
  441. return str;
  442. }
  443. void CXTPButton::EnableMarkup(BOOL bEnableMarkup)
  444. {
  445. m_bEnableMarkup = bEnableMarkup;
  446. XTPMarkupReleaseElement(m_pUIElement);
  447. XTPMarkupReleaseContext(m_pMarkupContext);
  448. if (m_bEnableMarkup)
  449. {
  450. m_pMarkupContext = XTPMarkupCreateContext(m_hWnd);
  451. }
  452. InternalTextChanged();
  453. }
  454. BOOL CXTPButton::IsPushButton() const
  455. {
  456. DWORD dwStyle = GetStyle();
  457. switch (GetButtonStyle())
  458. {
  459. case LOBYTE(BS_PUSHBUTTON):
  460. case LOBYTE(BS_DEFPUSHBUTTON):
  461. case LOBYTE(BS_OWNERDRAW):
  462. return TRUE;
  463. default:
  464. if ((dwStyle & BS_PUSHLIKE) == BS_PUSHLIKE)
  465. return TRUE;
  466. break;
  467. }
  468. return FALSE;
  469. }
  470. void CXTPButton::SetTheme(XTPButtonTheme nStyle)
  471. {
  472. CMDTARGET_RELEASE(m_pButtonTheme);
  473. switch (nStyle)
  474. {
  475. case xtpButtonThemeFlat:
  476. m_pButtonTheme = new CXTPButtonFlatTheme();
  477. break;
  478. case xtpButtonThemeUltraFlat:
  479. m_pButtonTheme = new CXTPButtonUltraFlatTheme();
  480. break;
  481. case xtpButtonThemeOffice2000:
  482. m_pButtonTheme = new CXTPButtonOffice2000Theme();
  483. break;
  484. case xtpButtonThemeOfficeXP:
  485. m_pButtonTheme = new CXTPButtonOfficeXPTheme();
  486. break;
  487. case xtpButtonThemeOffice2003:
  488. m_pButtonTheme = new CXTPButtonOffice2003Theme();
  489. break;
  490. case xtpButtonThemeOffice2007:
  491. m_pButtonTheme = new CXTPButtonOffice2007Theme();
  492. break;
  493. default:
  494. m_pButtonTheme = new CXTPButtonTheme();
  495. }
  496. m_bUseVisualStyle = (nStyle == xtpButtonThemeStandard);
  497. m_pButtonTheme->RefreshMetrics(this);
  498. RedrawButton();
  499. }
  500. void CXTPButton::SetUseVisualStyle(BOOL bUseVisualStyle/* = TRUE*/)
  501. {
  502. m_bUseVisualStyle = bUseVisualStyle;
  503. m_pButtonTheme->RefreshMetrics(this);
  504. RedrawButton();
  505. }
  506. BOOL CXTPButton::GetChecked()
  507. {
  508. if (IsPushButton() || !m_hWnd)
  509. {
  510. return m_bChecked;
  511. }
  512. return (BOOL)::SendMessage(m_hWnd, BM_GETCHECK, 0, 0);
  513. }
  514. void CXTPButton::SetChecked(BOOL bChecked)
  515. {
  516. if (IsPushButton() || !m_hWnd)
  517. {
  518. m_bChecked = bChecked;
  519. RedrawButton();
  520. }
  521. else
  522. {
  523. ::SendMessage(m_hWnd, BM_SETCHECK, bChecked, 0);
  524. }
  525. }
  526. BOOL CXTPButton::SetIcon(CSize size, UINT nID, UINT nHotID/*= 0*/, BOOL bRedraw/*= TRUE*/)
  527. {
  528. return CXTPButton::SetIcon(
  529. size, MAKEINTRESOURCE(nID), MAKEINTRESOURCE(nHotID), bRedraw);
  530. }
  531. BOOL CXTPButton::SetIcon(CSize size, LPCTSTR lpszID, LPCTSTR lpszHotID/*= NULL*/, BOOL bRedraw/*= TRUE*/)
  532. {
  533. CXTPImageManagerIconHandle hIcon;
  534. CXTPImageManagerIconHandle hIconHot;
  535. hIcon.CreateIconFromResource(lpszID, size);
  536. // Return false if the icon handle is NULL.
  537. if (hIcon.IsEmpty())
  538. {
  539. TRACE0("Failed to load Icon resource.n");
  540. return FALSE;
  541. }
  542. // If we are using a pushed image as well...
  543. if (lpszHotID)
  544. {
  545. hIconHot.CreateIconFromResource(lpszHotID, size);
  546. // Return false if the icon handle is NULL.
  547. if (hIconHot.IsEmpty())
  548. {
  549. TRACE0("Failed to load Icon resource.n");
  550. return FALSE;
  551. }
  552. }
  553. return CXTPButton::SetIcon(size, hIcon, hIconHot, bRedraw);
  554. }
  555. BOOL CXTPButton::SetIcon(CSize /*size*/, CXTPImageManagerIcon* pIcon, BOOL bRedraw/*= TRUE*/)
  556. {
  557. // Construct the icon manager.
  558. CMDTARGET_RELEASE(m_pIcon);
  559. m_pIcon = pIcon;
  560. // Redraw the button.
  561. if (bRedraw)
  562. RedrawButton();
  563. return TRUE;
  564. }
  565. BOOL CXTPButton::SetIcon(CSize size, const CXTPImageManagerIconHandle& hIcon, const CXTPImageManagerIconHandle& hIconHot, BOOL bRedraw/*= TRUE*/)
  566. {
  567. ASSERT(!hIcon.IsEmpty());
  568. // Save the image size and set the icon
  569. // handles to NULL.
  570. size = size != CSize(0) ? size : hIcon.GetExtent();
  571. CXTPImageManagerIcon* pIcon = new CXTPImageManagerIcon(0, size.cx, size.cy);
  572. pIcon->SetIcon(hIcon);
  573. if (!hIconHot.IsEmpty())
  574. pIcon->SetHotIcon(hIconHot);
  575. return SetIcon(size, pIcon, bRedraw);
  576. }
  577. BOOL CXTPButton::SetIcon(CSize size, HICON hIcon, HICON hIconHot/*= NULL*/, BOOL bRedraw/*= TRUE*/)
  578. {
  579. return SetIcon(size, CXTPImageManagerIconHandle(hIcon), CXTPImageManagerIconHandle(hIconHot), bRedraw);
  580. }
  581. BOOL CXTPButton::SetBitmap(CSize size, UINT nID, BOOL bRedraw/*= TRUE*/)
  582. {
  583. // Free previous resources (if any).
  584. CXTPImageManagerIconHandle hIconHandle;
  585. BOOL bAlphaBitmap = FALSE;
  586. HBITMAP hBitmap = CXTPImageManagerIcon::LoadBitmapFromResource(MAKEINTRESOURCE(nID), &bAlphaBitmap);
  587. if (!hBitmap)
  588. return FALSE;
  589. if (bAlphaBitmap)
  590. {
  591. hIconHandle = hBitmap; // Will call DeleteObject;
  592. }
  593. else
  594. {
  595. CBitmap bmpIcon;
  596. bmpIcon.Attach(hBitmap);
  597. // convert the bitmap to a transparent icon.
  598. HICON hIcon = CXTPTransparentBitmap(bmpIcon).ConvertToIcon();
  599. hIconHandle = hIcon; // Will call DestoyIcon;
  600. }
  601. if (hIconHandle.IsEmpty())
  602. return FALSE;
  603. return CXTPButton::SetIcon(size, hIconHandle, CXTPImageManagerIconHandle(), bRedraw);
  604. }
  605. //////////////////////////////////////////////////////////////////////
  606. // Construction/Destruction
  607. //////////////////////////////////////////////////////////////////////
  608. CXTPButtonTheme::CXTPButtonTheme()
  609. {
  610. m_nBorderWidth = 4;
  611. m_bOffsetHiliteText = TRUE;
  612. m_bFlatGlyphs = FALSE;
  613. m_cxBorder = GetSystemMetrics(SM_CXBORDER);
  614. m_cyBorder = GetSystemMetrics(SM_CYBORDER);
  615. m_cxEdge = GetSystemMetrics(SM_CXEDGE);
  616. m_cyEdge = GetSystemMetrics(SM_CYEDGE);
  617. }
  618. CXTPButtonTheme::~CXTPButtonTheme()
  619. {
  620. }
  621. void CXTPButtonTheme::RefreshMetrics(CXTPButton* /*pButton*/)
  622. {
  623. m_themeButton.OpenTheme(0, L"BUTTON");
  624. RefreshXtremeColors();
  625. // background colors.
  626. m_crBack.SetStandardValue(GetXtremeColor(COLOR_BTNFACE));
  627. // text colors.
  628. m_crText.SetStandardValue(GetXtremeColor(COLOR_BTNTEXT));
  629. m_crTextDisabled.SetStandardValue(GetXtremeColor(COLOR_GRAYTEXT));
  630. // border colors.
  631. m_crBorderHilite.SetStandardValue(GetXtremeColor(COLOR_BTNFACE));
  632. m_crBorderShadow.SetStandardValue(GetXtremeColor(COLOR_3DSHADOW));
  633. m_crBorder3DHilite.SetStandardValue(GetXtremeColor(COLOR_3DHILIGHT));
  634. m_crBorder3DShadow.SetStandardValue(GetXtremeColor(COLOR_3DDKSHADOW));
  635. }
  636. void CXTPButtonTheme::DrawFocusRect(CDC* pDC, CXTPButton* pButton)
  637. {
  638. if ((pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0)
  639. {
  640. pDC->SetTextColor(GetXtremeColor(COLOR_BTNTEXT));
  641. CXTPClientRect rcItem(pButton);
  642. rcItem.DeflateRect(m_nBorderWidth, m_nBorderWidth);
  643. pDC->DrawFocusRect(rcItem);
  644. }
  645. }
  646. void CXTPButtonTheme::DrawButtonVisualStyleBackground(CDC* pDC, CXTPButton* pButton)
  647. {
  648. BOOL bPressed = pButton->IsPushed();
  649. BOOL bHot = pButton->IsHighlighted();
  650. BYTE bStyle = pButton->GetButtonStyle();
  651. BOOL bDefault = bStyle == BS_DEFPUSHBUTTON;
  652. BOOL bEnabled = pButton->IsWindowEnabled();
  653. BOOL bChecked = pButton->GetChecked();
  654. CXTPClientRect rc(pButton);
  655. int nState = !bEnabled? PBS_DISABLED: bPressed? PBS_PRESSED: bHot? PBS_HOT: bChecked ? PBS_PRESSED : bDefault? PBS_DEFAULTED: PBS_NORMAL;
  656. m_themeButton.DrawThemeBackground(pDC->GetSafeHdc(), BP_PUSHBUTTON, nState, rc, NULL);
  657. }
  658. void CXTPButtonTheme::DrawButtonBackground(CDC* pDC, CXTPButton* pButton)
  659. {
  660. BOOL bPressed = pButton->IsPushed();
  661. BOOL bHot = pButton->IsHighlighted();
  662. BYTE bStyle = pButton->GetButtonStyle();
  663. BOOL bDefault = bStyle == BS_DEFPUSHBUTTON;
  664. BOOL bChecked = pButton->GetChecked();
  665. CXTPClientRect rc(pButton);
  666. if (pButton->GetFlatStyle() && !bHot && !bPressed && !bChecked)
  667. return;
  668. if (pButton->GetUseVisualStyle() && m_themeButton.IsAppThemed())
  669. {
  670. DrawButtonVisualStyleBackground(pDC, pButton);
  671. return;
  672. }
  673. pDC->FillSolidRect(rc, pButton->GetButtonBackColor());
  674. BOOL bSelected = bPressed || bChecked;
  675. if (bDefault)
  676. {
  677. pDC->Draw3dRect(rc, m_crBorder3DShadow, m_crBorder3DShadow);
  678. rc.DeflateRect(1,1);
  679. }
  680. pDC->Draw3dRect(rc,
  681. bSelected ? m_crBorder3DShadow : m_crBorder3DHilite,
  682. bSelected ? m_crBorder3DHilite : m_crBorder3DShadow);
  683. rc.DeflateRect(1, 1);
  684. pDC->Draw3dRect(rc,
  685. bSelected ? m_crBorderShadow : m_crBorderHilite,
  686. bSelected ? m_crBorderHilite : m_crBorderShadow);
  687. }
  688. COLORREF CXTPButtonTheme::GetTextColor(CXTPButton* pButton)
  689. {
  690. if (!pButton->IsWindowEnabled())
  691. {
  692. return m_crTextDisabled;
  693. }
  694. return pButton->GetButtonTextColor();
  695. }
  696. AFX_INLINE BOOL IsAlignRight (int nAlign) { return (nAlign & BS_HORZMASK) == BS_RIGHT;}
  697. AFX_INLINE BOOL IsAlignCenter (int nAlign) { return (nAlign & BS_HORZMASK) == BS_CENTER;}
  698. AFX_INLINE BOOL IsAlignTop (int nAlign) { return (nAlign & BS_VERTMASK) == BS_TOP;}
  699. AFX_INLINE BOOL IsAlignBottom (int nAlign) { return (nAlign & BS_VERTMASK) == BS_BOTTOM;}
  700. AFX_INLINE BOOL IsAlignMiddle (int nAlign) { return (nAlign & BS_VERTMASK) == BS_VCENTER;}
  701. void CXTPButtonTheme::DrawButtonText(CDC* pDC, CXTPButton* pButton)
  702. {
  703. pDC->SetTextColor(pButton->IsWindowEnabled() ?
  704. pButton->GetButtonTextColor() : m_crTextDisabled);
  705. static const BYTE buttonsStyles[] =
  706. {
  707. CBR_PUSHBUTTON,
  708. CBR_PUSHBUTTON,
  709. CBR_CHECKTEXT,
  710. CBR_CHECKTEXT,
  711. CBR_RADIOTEXT,
  712. CBR_CHECKTEXT,
  713. CBR_CHECKTEXT,
  714. CBR_GROUPTEXT,
  715. CBR_CLIENTRECT,
  716. CBR_RADIOTEXT,
  717. CBR_CLIENTRECT,
  718. CBR_PUSHBUTTON,
  719. };
  720. RECT    rc;
  721. int     x, y, cx = 0, cy = 0;
  722. CString strText;
  723. UINT dsFlags = DT_SINGLELINE | DT_LEFT | DT_TOP | DT_NOCLIP;
  724. BYTE bStyle = pButton->GetButtonStyle();
  725. DWORD dwStyle = pButton->GetStyle();
  726. BOOL pbfPush = pButton->IsPushButton();
  727. if (pbfPush)
  728. {
  729. CalcRect(pDC, pButton, &rc, CBR_PUSHBUTTON);
  730. }
  731. else
  732. {
  733. CalcRect(pDC, pButton, &rc, buttonsStyles[bStyle]);
  734. }
  735. // Alignment
  736. strText = pButton->GetButtonText();
  737. UINT wAlignment = pButton->GetTextAlignment();
  738. HGDIOBJ hImage = 0;
  739. if (pButton->GetStyle() & BS_BITMAP)
  740. {
  741. hImage = (HGDIOBJ)pButton->SendMessage(BM_GETIMAGE, IMAGE_BITMAP);
  742. if (!hImage)
  743. return;
  744. BITMAP bmp;
  745. GetObject(hImage, sizeof(BITMAP), &bmp);
  746. cx = bmp.bmWidth;
  747. cy = bmp.bmHeight;
  748. }
  749. else if (pButton->GetStyle() & BS_ICON)
  750. {
  751. hImage = (HGDIOBJ)pButton->SendMessage(BM_GETIMAGE, IMAGE_ICON);
  752. if (!hImage)
  753. return;
  754. cx = cy = 16;
  755. }
  756. else
  757. {
  758. // Text button
  759. if (strText.IsEmpty())
  760. return;
  761. if (pButton->GetMarkupUIElement())
  762. {
  763. XTPMarkupSetDefaultFont(pButton->GetMarkupContext(), (HFONT)pButton->SendMessage(WM_GETFONT), COLORREF_NULL);
  764. CSize sz = XTPMarkupMeasureElement(pButton->GetMarkupUIElement(), rc.right - rc.left, rc.bottom - rc.top);
  765. cx = sz.cx;
  766. cy = sz.cy;
  767. }
  768. else
  769. {
  770. if (pButton->GetStyle() & BS_MULTILINE)
  771. {
  772. dsFlags |= DT_WORDBREAK | DT_EDITCONTROL;
  773. dsFlags &= ~DT_SINGLELINE;
  774. }
  775. CRect rcText(0, 0, rc.right - rc.left, 0);
  776. pDC->DrawText(strText, rcText, dsFlags | DT_CALCRECT);
  777. cx = rcText.Width();
  778. cy = rcText.Height();
  779. }
  780. }
  781. CRect rcText(rc);
  782. if (pbfPush && ((pButton->GetStyle() & BS_MULTILINE) == 0)) rcText.DeflateRect(m_cxBorder, m_cyBorder);
  783. // Horizontal
  784. switch (wAlignment & BS_HORZMASK)
  785. {
  786. case BS_LEFT:
  787. x = rc.left + (pbfPush ? m_cxBorder : 0);
  788. break;
  789. case BS_RIGHT:
  790. x = rc.right - cx -  (pbfPush ? m_cxBorder : 0);
  791. dsFlags |= DT_RIGHT;
  792. break;
  793. default:
  794. x = (rc.left + rc.right - cx) / 2;
  795. dsFlags |= DT_CENTER;
  796. break;
  797. }
  798. // Vertical
  799. switch (wAlignment & BS_VERTMASK)
  800. {
  801. case BS_TOP:
  802. y = rc.top + (pbfPush ? m_cyBorder : 0);
  803. break;
  804. case BS_BOTTOM:
  805. y = rc.bottom - cy - (pbfPush ? m_cyBorder : 0);
  806. dsFlags |= DT_BOTTOM;
  807. break;
  808. default:
  809. y = (rc.top + rc.bottom - cy) / 2;
  810. dsFlags |= DT_VCENTER;
  811. break;
  812. }
  813. if (dwStyle & BS_BITMAP)
  814. {
  815. pDC->DrawState(CPoint(x, y), CSize(cx, cy), (HBITMAP)hImage, DSS_NORMAL, 0);
  816. }
  817. else if (dwStyle & BS_ICON)
  818. {
  819. pDC->DrawState(CPoint(x, y), CSize(cx, cy), (HICON)hImage, DSS_NORMAL, (HBRUSH)0);
  820. }
  821. else if (bStyle !=  LOBYTE(BS_USERBUTTON))
  822. {
  823. if (pButton->GetMarkupUIElement())
  824. {
  825. XTPMarkupSetDefaultFont(pButton->GetMarkupContext(), NULL, pDC->GetTextColor());
  826. XTPMarkupRenderElement(pButton->GetMarkupUIElement(), pDC->GetSafeHdc(), CRect(x, y, x + cx, y + cy));
  827. }
  828. else
  829. {
  830. if (pButton->GetExStyle() & WS_EX_RTLREADING)
  831. dsFlags |= DT_RTLREADING;
  832. if (pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEACCEL)
  833. {
  834. dsFlags |= DT_HIDEPREFIX;
  835. }
  836. if (dwStyle & BS_MULTILINE)
  837. {
  838. pDC->DrawText(strText, CRect(x, y, x + cx, y + cy), dsFlags | DT_NOCLIP);
  839. }
  840. else
  841. {
  842. pDC->DrawText(strText, rcText, dsFlags);
  843. }
  844. }
  845. }
  846. if (::GetFocus() == pButton->m_hWnd && pButton->GetShowFocus())
  847. {
  848. if ((pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0)
  849. {
  850. if (!pbfPush)
  851. {
  852. RECT rcClient;
  853. pButton->GetClientRect(&rcClient);
  854. if (bStyle == LOBYTE(BS_USERBUTTON))
  855. CopyRect(&rc, &rcClient);
  856. else
  857. {
  858. // Try to leave a border all around text.  That causes
  859. // focus to hug text.
  860. rc.top = max(rcClient.top, y - m_cyBorder);
  861. rc.bottom = min(rcClient.bottom, rc.top + m_cyEdge + cy);
  862. rc.left = max(rcClient.left, x-m_cxBorder);
  863. rc.right = min(rcClient.right, rc.left + m_cxEdge + cx);
  864. }
  865. }
  866. else
  867. InflateRect(&rc, -m_cxBorder, -m_cyBorder);
  868. pDC->SetTextColor(GetXtremeColor(COLOR_BTNTEXT));
  869. pDC->SetBkColor(GetXtremeColor(COLOR_WINDOW));
  870. // Are back & fore colors set properly?
  871. ::DrawFocusRect(pDC->GetSafeHdc(), &rc);
  872. }
  873. }
  874. }
  875. void CXTPButtonTheme::CalcRect(CDC* pDC, CXTPButton* pButton, LPRECT lprc, int code)
  876. {
  877. int dy;
  878. UINT align;
  879. CSize extent;
  880. pButton->GetClientRect(lprc);
  881. align = pButton->GetTextAlignment();
  882. switch (code)
  883. {
  884. case CBR_PUSHBUTTON:
  885. // Subtract out raised edge all around
  886. InflateRect(lprc, -m_cxEdge, -m_cyEdge);
  887. break;
  888. case CBR_CHECKBOX:
  889. case CBR_RADIOBOX:
  890. {
  891. CSize szGlyph = pButton->GetGlyphSize(code == CBR_CHECKBOX);
  892. switch (align & BS_VERTMASK)
  893. {
  894. case BS_VCENTER:
  895. lprc->top = (lprc->top + lprc->bottom - szGlyph.cy) / 2;
  896. break;
  897. case BS_TOP:
  898. case BS_BOTTOM:
  899. {
  900. extent = pDC->GetTextExtent(_T(" "), 1);
  901. dy = extent.cy + extent.cy/4;
  902. // Save vertical extent
  903. extent.cx = dy;
  904. // Get centered amount
  905. dy = (dy - szGlyph.cy) / 2;
  906. if ((align & BS_VERTMASK) == BS_TOP)
  907. lprc->top += dy;
  908. else
  909. lprc->top = lprc->bottom - extent.cx + dy;
  910. break;
  911. }
  912. }
  913. lprc->bottom = lprc->top + szGlyph.cy;
  914. if (pButton->GetStyle() & BS_RIGHTBUTTON)
  915. lprc->left = lprc->right - szGlyph.cx;
  916. else
  917. lprc->right = lprc->left + szGlyph.cx;
  918. }
  919. break;
  920. case CBR_CHECKTEXT:
  921. case CBR_RADIOTEXT:
  922. {
  923. int nOffset = pButton->GetGlyphSize(code == CBR_CHECKBOX).cx + 3;
  924. if (pButton->GetStyle() & BS_RIGHTBUTTON)
  925. {
  926. lprc->right -= nOffset;
  927. }
  928. else
  929. {
  930. lprc->left += nOffset;
  931. }
  932. }
  933. break;
  934. case CBR_GROUPTEXT:
  935. {
  936. CString strText = pButton->GetButtonText();
  937. XTPDrawHelpers()->StripMnemonics(strText);
  938. if (strText.IsEmpty())
  939. {
  940. SetRectEmpty(lprc);
  941. break;
  942. }
  943. extent = pDC->GetTextExtent(strText);
  944. extent.cx += m_cxEdge * 2;
  945. // Left Align. TODO!
  946. if (pButton->GetBorderStyle() == 1)
  947. {
  948. if (pButton->GetTextAlignment() & BS_RIGHT)
  949. {
  950. lprc->left = lprc->right - (int)(extent.cx);
  951. }
  952. else
  953. lprc->right = lprc->left + (int)(extent.cx);
  954. }
  955. else if (pButton->GetTextAlignment() & BS_RIGHT)
  956. {
  957. lprc->right -= 6 + m_cxBorder;
  958. lprc->left += lprc->right - (int)(extent.cx);
  959. }
  960. else
  961. {
  962. lprc->left += 8 + m_cxBorder;
  963. lprc->right = lprc->left + (int)(extent.cx);
  964. }
  965. lprc->bottom = lprc->top + extent.cy;
  966. }
  967. break;
  968. case CBR_GROUPFRAME:
  969. extent = pDC->GetTextExtent(_T(" "), 1);
  970. lprc->top += extent.cy / 2;
  971. break;
  972. }
  973. }
  974. void CXTPButtonTheme::CalcRects(CDC* pDC, CXTPButton* pButton, CRect* pButtonText, UINT* pDrawFlags, CRect* pButtonIcon)
  975. {
  976. CString strText = pButton->GetButtonText();
  977. UINT dsFlags = DT_SINGLELINE | DT_LEFT | DT_TOP | DT_NOCLIP;
  978. if (pButton->GetExStyle() & WS_EX_RTLREADING)
  979. dsFlags |= DT_RTLREADING;
  980. if (pButton->GetStyle() & BS_MULTILINE)
  981. {
  982. dsFlags |= DT_WORDBREAK | DT_EDITCONTROL;
  983. dsFlags &= ~DT_SINGLELINE;
  984. }
  985. CRect rcItem;
  986. pButton->GetClientRect(rcItem);
  987. rcItem.DeflateRect(pButton->GetBorderGap(), pButton->GetBorderGap());
  988. if (pButton->IsDropDownStyle())
  989. {
  990. rcItem.right -= 12 + (pButton->GetPushButtonStyle() == xtpButtonSplitDropDown ?
  991. 2 : 1) * pButton->GetBorderGap() ;
  992. }
  993. int nTextImageRelation = pButton->GetTextImageRelation();
  994. int nTextAlign = pButton->GetTextAlignment();
  995. int nImageAlign = pButton->GetImageAlignment();
  996. CSize sizeImage = pButton->GetImageSize();
  997. if (sizeImage.cx == 0 || strText.IsEmpty())
  998. nTextImageRelation = xtpButtonOverlay;
  999. CSize sizeText = CSize(rcItem.Width(), 0);
  1000. switch (nTextImageRelation)
  1001. {
  1002. case xtpButtonImageBeforeText:
  1003. case xtpButtonTextBeforeImage:
  1004. sizeImage.cx += pButton->GetImageGap();
  1005. sizeText.cx -= sizeImage.cx;
  1006. break;
  1007. case xtpButtonImageAboveText:
  1008. case xtpButtonTextAboveImage:
  1009. sizeImage.cy += pButton->GetImageGap();
  1010. break;
  1011. }
  1012. if (!strText.IsEmpty())
  1013. {
  1014. if (pButton->GetMarkupUIElement())
  1015. {
  1016. XTPMarkupSetDefaultFont(pButton->GetMarkupContext(), (HFONT)pButton->SendMessage(WM_GETFONT), (COLORREF)-1);
  1017. CSize szDesiredSize = XTPMarkupMeasureElement(pButton->GetMarkupUIElement(), sizeText.cx, rcItem.Height());
  1018. sizeText = CSize(min(sizeText.cx, szDesiredSize.cx), szDesiredSize.cy);
  1019. }
  1020. else
  1021. {
  1022. CRect rcTextCalc(0, 0, sizeText.cx, 0);
  1023. pDC->DrawText(strText, rcTextCalc, dsFlags | DT_CALCRECT);
  1024. sizeText = CSize(min(sizeText.cx, rcTextCalc.Width()), rcTextCalc.Height());
  1025. }
  1026. }
  1027. else
  1028. {
  1029. sizeText = CSize(0, 0);
  1030. }
  1031. if (nTextImageRelation == xtpButtonOverlay && pButtonText) sizeImage = CSize(0, 0);
  1032. if (nTextImageRelation == xtpButtonOverlay && pButtonIcon) sizeText = CSize(0, 0);
  1033. CRect rcText(rcItem);
  1034. CPoint ptImage(rcItem.TopLeft());
  1035. ptImage.x = IsAlignRight(nImageAlign) ? rcItem.right - sizeImage.cx :
  1036. IsAlignCenter(nImageAlign) ? (rcItem.left + rcItem.right - sizeImage.cx) /2 : rcItem.left;
  1037. ptImage.y = IsAlignBottom(nImageAlign) ? rcItem.bottom - sizeImage.cy :
  1038. IsAlignMiddle(nImageAlign) ? (rcItem.top + rcItem.bottom - sizeImage.cy) / 2 : rcItem.top;
  1039. rcText.left = IsAlignRight(nTextAlign) ? rcText.right - sizeText.cx :
  1040. IsAlignCenter(nTextAlign) ? (rcText.left + rcText.right - sizeText.cx) / 2 : rcItem.left;
  1041. dsFlags |= IsAlignRight(nTextAlign) ? DT_RIGHT: IsAlignCenter(nTextAlign) ? DT_CENTER : DT_LEFT;
  1042. rcText.top = IsAlignBottom(nTextAlign) ? rcText.bottom - sizeText.cy :
  1043. IsAlignMiddle(nTextAlign) ? (rcText.top + rcText.bottom - sizeText.cy) / 2 : rcItem.top;
  1044. switch (nTextImageRelation)
  1045. {
  1046. case xtpButtonImageBeforeText:
  1047. ptImage.x = IsAlignRight(nImageAlign) ?
  1048. rcItem.right - (sizeImage.cx + sizeText.cx):
  1049. IsAlignCenter(nImageAlign) ?
  1050. (rcItem.left + rcItem.right - (sizeImage.cx + sizeText.cx)) /2 :
  1051. rcItem.left;
  1052. rcText.left = max(rcText.left, ptImage.x + sizeImage.cx);
  1053. break;
  1054. case xtpButtonImageAboveText:
  1055. ptImage.y = IsAlignBottom(nImageAlign) ?
  1056. rcItem.bottom - (sizeImage.cy + sizeText.cy):
  1057. IsAlignMiddle(nImageAlign) ?
  1058. (rcItem.top + rcItem.bottom - (sizeImage.cy + sizeText.cy)) /2 :
  1059. rcItem.top;
  1060. rcText.top = max(rcText.top, ptImage.y + sizeImage.cy);
  1061. break;
  1062. case xtpButtonTextBeforeImage:
  1063. ptImage.x = pButton->GetImageGap() +
  1064. (IsAlignRight(nImageAlign) ?
  1065. rcItem.right - sizeImage.cx :
  1066. IsAlignCenter(nImageAlign) ?
  1067. (rcItem.left + rcItem.right + (-sizeImage.cx + sizeText.cx)) /2 :
  1068. rcItem.left + sizeText.cx);
  1069. if (rcText.left + sizeText.cx + pButton->GetImageGap() > ptImage.x)
  1070. rcText.left = ptImage.x - sizeText.cx - pButton->GetImageGap();
  1071. break;
  1072. case xtpButtonTextAboveImage:
  1073. ptImage.y = pButton->GetImageGap() +
  1074. (IsAlignBottom(nImageAlign) ?
  1075. rcItem.bottom - sizeImage.cy :
  1076. IsAlignMiddle(nImageAlign) ?
  1077. (rcItem.top + rcItem.bottom + (-sizeImage.cy + sizeText.cy)) /2 :
  1078. rcItem.top + sizeText.cy);
  1079. if (rcText.top + sizeText.cy + pButton->GetImageGap() > ptImage.y)
  1080. rcText.top = ptImage.y - sizeText.cy - pButton->GetImageGap();
  1081. break;
  1082. }
  1083. rcText.right = rcText.left + sizeText.cx;
  1084. rcText.bottom = rcText.top + sizeText.cy;
  1085. if (pButtonText) *pButtonText = rcText;
  1086. if (pButtonIcon) *pButtonIcon = CRect(ptImage, sizeImage);
  1087. if (pDrawFlags) *pDrawFlags = dsFlags;
  1088. }
  1089. BOOL CXTPButtonTheme::IsVisualThemeUsed(CXTPButton* pButton)
  1090. {
  1091. return (m_themeButton.IsAppThemed() && pButton->GetUseVisualStyle());
  1092. }
  1093. void CXTPButtonTheme::DrawPushButtonDropDown(CDC* pDC, CXTPButton* pButton)
  1094. {
  1095. CRect rcItem;
  1096. pButton->GetClientRect(rcItem);
  1097. rcItem.DeflateRect(pButton->GetBorderGap(), pButton->GetBorderGap());
  1098. CString strText = pButton->GetButtonText();
  1099. BOOL bEmpty = strText.IsEmpty() && pButton->GetImageSize() == CSize(0, 0);
  1100. if (!bEmpty)
  1101. rcItem.left = rcItem.right - 16;
  1102. BOOL  bSelected = pButton->GetChecked() || pButton->IsPushed();
  1103. if (bSelected && (m_bOffsetHiliteText || IsVisualThemeUsed(pButton)))
  1104. rcItem.OffsetRect(1, 1);
  1105. CPoint ptCenter = rcItem.CenterPoint();
  1106. BOOL bEnabled = pButton->IsWindowEnabled();
  1107. if (pButton->GetPushButtonStyle() == xtpButtonDropDown)
  1108. {
  1109. XTPDrawHelpers()->Triangle(pDC, CPoint(ptCenter.x - 4, ptCenter.y - 2),
  1110. CPoint(ptCenter.x + 4, ptCenter.y - 2),CPoint(ptCenter.x, ptCenter.y + 2), !bEnabled ? GetXtremeColor(COLOR_GRAYTEXT) : 0);
  1111. }
  1112. if (pButton->GetPushButtonStyle() == xtpButtonDropDownRight)
  1113. {
  1114. XTPDrawHelpers()->Triangle(pDC, CPoint(ptCenter.x - 2, ptCenter.y - 4),
  1115. CPoint(ptCenter.x - 2, ptCenter.y + 4),CPoint(ptCenter.x + 2, ptCenter.y ), !bEnabled ? GetXtremeColor(COLOR_GRAYTEXT) : 0);
  1116. }
  1117. if (pButton->GetPushButtonStyle() == xtpButtonSplitDropDown)
  1118. {
  1119. ptCenter.x += 1;
  1120. XTPDrawHelpers()->Triangle(pDC, CPoint(ptCenter.x - 4, ptCenter.y - 2),
  1121. CPoint(ptCenter.x + 4, ptCenter.y - 2),CPoint(ptCenter.x, ptCenter.y + 2), !bEnabled ? GetXtremeColor(COLOR_GRAYTEXT) : 0);
  1122. COLORREF crBorderShadow = !bEnabled ? GetXtremeColor(COLOR_GRAYTEXT) : IsVisualThemeUsed(pButton) ?  GetSysColor(COLOR_BTNSHADOW) : m_crBorderShadow;
  1123. pDC->FillSolidRect(rcItem.left, rcItem.top, 1, rcItem.Height(), crBorderShadow);
  1124. pDC->FillSolidRect(rcItem.left + 1, rcItem.top, 1, rcItem.Height(), GetSysColor(COLOR_BTNHIGHLIGHT));
  1125. }
  1126. }
  1127. void CXTPButtonTheme::DrawPushButtonText(CDC* pDC, CXTPButton* pButton)
  1128. {
  1129. CString strText = pButton->GetButtonText();
  1130. // if the string is empty just return.
  1131. if (strText.IsEmpty())
  1132. return;
  1133. CRect rcText;
  1134. UINT dsFlags;
  1135. CalcRects(pDC, pButton, &rcText, &dsFlags, NULL);
  1136. BOOL  bSelected = pButton->GetChecked() || pButton->IsPushed();
  1137. if (bSelected && (m_bOffsetHiliteText || (IsVisualThemeUsed(pButton))))
  1138. rcText.OffsetRect(1, 1);
  1139. COLORREF clrText = GetTextColor(pButton);
  1140. pDC->SetTextColor(clrText);
  1141. if (pButton->GetMarkupUIElement())
  1142. {
  1143. XTPMarkupSetDefaultFont(pButton->GetMarkupContext(), NULL, clrText);
  1144. XTPMarkupRenderElement(pButton->GetMarkupUIElement(), pDC->GetSafeHdc(), rcText);
  1145. }
  1146. else
  1147. {
  1148. if (pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEACCEL)
  1149. {
  1150. dsFlags |= DT_HIDEPREFIX;
  1151. }
  1152. pDC->DrawText(strText, rcText, dsFlags);
  1153. }
  1154. }
  1155. void CXTPButtonTheme::DrawPushButtonIcon(CDC* pDC, CXTPButton* pButton)
  1156. {
  1157. CSize sz = pButton->GetImageSize();
  1158. if (sz == CSize(0, 0))
  1159. return;
  1160. CRect rcImage;
  1161. CalcRects(pDC, pButton, NULL, NULL, &rcImage);
  1162. CPoint pt = rcImage.TopLeft();
  1163. BOOL  bSelected = pButton->GetChecked() || pButton->IsPushed();
  1164. if (bSelected && (m_bOffsetHiliteText || (IsVisualThemeUsed(pButton))))
  1165. pt.Offset(1, 1);
  1166. pButton->DrawImage(pDC, CRect(pt, sz));
  1167. }
  1168. void CXTPButtonTheme::DrawCheckBoxMark(CDC* pDC, CXTPButton* pButton)
  1169. {
  1170. BOOL bPressed = pButton->IsPushed();
  1171. BOOL bHot = pButton->IsHighlighted();
  1172. BYTE bStyle = pButton->GetButtonStyle();
  1173. BOOL bEnabled = pButton->IsWindowEnabled();
  1174. BOOL bChecked = pButton->GetChecked();
  1175. CRect rcRadio;
  1176. CalcRect(pDC, pButton, &rcRadio, CBR_CHECKBOX);
  1177. if (IsVisualThemeUsed(pButton))
  1178. {
  1179. int nState = !bEnabled? RBS_UNCHECKEDDISABLED: bPressed? RBS_UNCHECKEDPRESSED: bHot? RBS_UNCHECKEDHOT: RBS_UNCHECKEDNORMAL;
  1180. if (bChecked)
  1181. nState += 4;
  1182. if ((bChecked == BST_INDETERMINATE) && (bStyle == BS_AUTO3STATE || bStyle == BS_3STATE))
  1183. nState += 4;
  1184. m_themeButton.DrawThemeBackground(pDC->GetSafeHdc(), BP_CHECKBOX, nState, rcRadio, NULL);
  1185. return;
  1186. }
  1187. int nButton = ((bChecked == BST_INDETERMINATE) && (bStyle == BS_AUTO3STATE || bStyle == BS_3STATE))
  1188. ? DFCS_BUTTON3STATE : DFCS_BUTTONCHECK;
  1189. DrawFrameControl(pDC->GetSafeHdc(), rcRadio, DFC_BUTTON, nButton | (m_bFlatGlyphs ? DFCS_FLAT : 0) |
  1190. (bChecked ? DFCS_CHECKED : 0) | (bPressed ? DFCS_PUSHED : 0) | (bEnabled ? 0 : DFCS_INACTIVE));
  1191. }
  1192. void CXTPButtonTheme::DrawRadioButtonMark(CDC* pDC, CXTPButton* pButton)
  1193. {
  1194. BOOL bPressed = pButton->IsPushed();
  1195. BOOL bHot = pButton->IsHighlighted();
  1196. BOOL bEnabled = pButton->IsWindowEnabled();
  1197. BOOL bChecked = pButton->GetChecked();
  1198. CRect rcRadio;
  1199. CalcRect(pDC, pButton, &rcRadio, CBR_RADIOBOX);
  1200. if (IsVisualThemeUsed(pButton))
  1201. {
  1202. int nState = !bEnabled? RBS_UNCHECKEDDISABLED: bPressed? RBS_UNCHECKEDPRESSED: bHot? RBS_UNCHECKEDHOT: RBS_UNCHECKEDNORMAL;
  1203. if (bChecked) nState += 4;
  1204. m_themeButton.DrawThemeBackground(pDC->GetSafeHdc(), BP_RADIOBUTTON, nState, rcRadio, NULL);
  1205. return;
  1206. }
  1207. DrawFrameControl(pDC->GetSafeHdc(), rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO | (m_bFlatGlyphs ? DFCS_FLAT : 0) |
  1208. (bChecked ? DFCS_CHECKED : 0) | (bPressed ? DFCS_PUSHED : 0) | (bEnabled ? 0 : DFCS_INACTIVE));
  1209. }
  1210. void CXTPButtonTheme::DrawGroupBox(CDC* pDC, CXTPButton* pButton)
  1211. {
  1212. BOOL bEnabled = pButton->IsWindowEnabled();
  1213. int nState = !bEnabled? GBS_DISABLED: GBS_NORMAL;
  1214. CRect rcGroupBox;
  1215. CalcRect(pDC, pButton, &rcGroupBox, CBR_GROUPFRAME);
  1216. CRect rcGrouText;
  1217. CalcRect(pDC, pButton, &rcGrouText, CBR_GROUPTEXT);
  1218. if (pButton->GetTextAlignment() & BS_RIGHT)
  1219. rcGrouText.OffsetRect(+m_cxEdge, 0);
  1220. else
  1221. rcGrouText.OffsetRect(-m_cxEdge, 0);
  1222. pDC->ExcludeClipRect(&rcGrouText);
  1223. if (pButton->GetBorderStyle() == 1)
  1224. {
  1225. if (IsVisualThemeUsed(pButton))
  1226. {
  1227. COLORREF clrLine = GetSysColor(COLOR_3DSHADOW);
  1228. m_themeButton.GetThemeColor(BP_GROUPBOX, GBS_NORMAL, TMT_BORDERCOLORHINT, &clrLine);
  1229. pDC->FillSolidRect(rcGroupBox.left, rcGroupBox.top, rcGroupBox.Width(), 1, clrLine);
  1230. }
  1231. else
  1232. {
  1233. DrawEdge(pDC->GetSafeHdc(), &rcGroupBox, EDGE_ETCHED, BF_TOP | (m_bFlatGlyphs ? BF_FLAT | BF_MONO : 0) );
  1234. }
  1235. }
  1236. else
  1237. {
  1238. if (IsVisualThemeUsed(pButton))
  1239. {
  1240. m_themeButton.DrawThemeBackground(pDC->GetSafeHdc(), BP_GROUPBOX, nState, rcGroupBox, NULL);
  1241. }
  1242. else
  1243. {
  1244. DrawEdge(pDC->GetSafeHdc(), &rcGroupBox, EDGE_ETCHED, BF_RECT |
  1245. (m_bFlatGlyphs ? BF_FLAT | BF_MONO : 0));
  1246. }
  1247. }
  1248. pDC->SelectClipRgn(NULL);
  1249. }
  1250. //////////////////////////////////////////////////////////////////////////
  1251. // CXTPButtonFlatTheme
  1252. CXTPButtonFlatTheme::CXTPButtonFlatTheme()
  1253. {
  1254. m_bFlatGlyphs = TRUE;
  1255. m_nBorderWidth = 4;
  1256. }
  1257. void CXTPButtonFlatTheme::DrawButtonBackground(CDC* pDC, CXTPButton* pButton)
  1258. {
  1259. BOOL bPressed = pButton->IsPushed();
  1260. BOOL bHot = pButton->IsHighlighted();
  1261. BYTE bStyle = pButton->GetButtonStyle();
  1262. BOOL bDefault = bStyle == BS_DEFPUSHBUTTON;
  1263. BOOL bChecked = pButton->GetChecked();
  1264. CXTPClientRect rc(pButton);
  1265. if (pButton->GetFlatStyle() && !bHot && !bPressed && !bChecked)
  1266. return;
  1267. if (pButton->GetUseVisualStyle() && m_themeButton.IsAppThemed())
  1268. {
  1269. DrawButtonVisualStyleBackground(pDC, pButton);
  1270. return;
  1271. }
  1272. pDC->FillSolidRect(rc, pButton->GetButtonBackColor());
  1273. COLORREF clrBorder = GetXtremeColor(COLOR_WINDOWFRAME);
  1274. if (bDefault)
  1275. {
  1276. pDC->Draw3dRect(rc, clrBorder, clrBorder);
  1277. rc.DeflateRect(1,1);
  1278. }
  1279. pDC->Draw3dRect(rc, clrBorder, clrBorder);
  1280. rc.DeflateRect(1, 1);
  1281. pDC->Draw3dRect(rc, GetXtremeColor(COLOR_WINDOW), GetXtremeColor(COLOR_WINDOW));
  1282. }
  1283. //////////////////////////////////////////////////////////////////////////
  1284. //
  1285. CXTPButtonUltraFlatTheme::CXTPButtonUltraFlatTheme()
  1286. {
  1287. m_bFlatGlyphs = TRUE;
  1288. m_nBorderWidth = 3;
  1289. m_bHiglightButtons = TRUE;
  1290. }
  1291. void CXTPButtonUltraFlatTheme::RefreshMetrics(CXTPButton* pButton)
  1292. {
  1293. CXTPButtonTheme::RefreshMetrics(pButton);
  1294. COLORREF clrWindow = GetXtremeColor(COLOR_WINDOW);
  1295. COLORREF clrToolBar = GetXtremeColor(XPCOLOR_TOOLBAR_FACE);
  1296. COLORREF clrFace = pButton->GetButtonBackColor();
  1297. m_crBack.SetStandardValue(clrFace);
  1298. COLORREF clrPushed = GetXtremeColor(COLOR_3DSHADOW);
  1299. clrPushed = XTPColorManager()->LightColor(clrPushed,
  1300. clrFace, 0x32);
  1301. m_crBackPushed.SetStandardValue(clrPushed);
  1302. COLORREF clrHighlight = clrFace;
  1303. clrHighlight = XTPColorManager()->LightColor(clrHighlight, clrWindow, 0x1E);
  1304. m_crBackHilite.SetStandardValue(clrHighlight);
  1305. COLORREF clrChecked =
  1306. RGB(GetRValue(clrWindow) * 40 / 100 + GetRValue(clrHighlight) * 10 / 100 + GetRValue(clrToolBar) * 50 / 100,
  1307. GetGValue(clrWindow) * 40 / 100 + GetGValue(clrHighlight) * 10 / 100 + GetGValue(clrToolBar) * 50 / 100,
  1308. GetBValue(clrWindow) * 40 / 100 + GetBValue(clrHighlight) * 10 / 100 + GetBValue(clrToolBar) * 50 / 100);
  1309. m_crBackChecked.SetStandardValue(clrChecked);
  1310. m_crBorderShadow.SetStandardValue(GetXtremeColor(COLOR_3DSHADOW));
  1311. m_crBorderHilite.SetStandardValue(GetXtremeColor(COLOR_3DSHADOW));
  1312. COLORREF clrText = pButton->GetButtonTextColor();
  1313. m_crText.SetStandardValue(clrText);
  1314. m_crTextHilite.SetStandardValue(clrText);
  1315. m_crTextPushed.SetStandardValue(clrText);
  1316. }
  1317. void CXTPButtonUltraFlatTheme::DrawButtonBackground(CDC* pDC, CXTPButton* pButton)
  1318. {
  1319. BOOL bPressed = pButton->IsPushed();
  1320. BOOL bHot = pButton->IsHighlighted();
  1321. BYTE bStyle = pButton->GetButtonStyle();
  1322. BOOL bDefault = bStyle == BS_DEFPUSHBUTTON;
  1323. BOOL bChecked = pButton->GetChecked();
  1324. CXTPClientRect rc(pButton);
  1325. if (pButton->GetFlatStyle() && !bHot && !bPressed && !bChecked)
  1326. return;
  1327. if (pButton->GetUseVisualStyle() && m_themeButton.IsAppThemed())
  1328. {
  1329. DrawButtonVisualStyleBackground(pDC, pButton);
  1330. return;
  1331. }
  1332. if (bDefault)
  1333. {
  1334. pDC->Draw3dRect(rc, m_crBorderShadow, m_crBorderShadow);
  1335. rc.DeflateRect(1,1);
  1336. }
  1337. if (bHot || bPressed || bChecked)
  1338. {
  1339. pDC->FillSolidRect(rc, bPressed ? m_crBackPushed :
  1340. bChecked ? (bHot ? m_crBackPushed : m_crBackChecked) : m_crBackHilite);
  1341. pDC->Draw3dRect(rc, m_crBorderHilite,
  1342. m_crBorderHilite);
  1343. }
  1344. else
  1345. {
  1346. pDC->FillSolidRect(rc, pButton->GetButtonBackColor());
  1347. pDC->Draw3dRect(rc, m_crBorderShadow, m_crBorderShadow);
  1348. }
  1349. }
  1350. void CXTPButtonUltraFlatTheme::DrawGroupBox(CDC* pDC, CXTPButton* pButton)
  1351. {
  1352. if (IsVisualThemeUsed(pButton))
  1353. {
  1354. CXTPButtonTheme::DrawGroupBox(pDC, pButton);
  1355. return;
  1356. }
  1357. CRect rcGroupBox;
  1358. CalcRect(pDC, pButton, &rcGroupBox, CBR_GROUPFRAME);
  1359. CRect rcGrouText;
  1360. CalcRect(pDC, pButton, &rcGrouText, CBR_GROUPTEXT);
  1361. if (pButton->GetTextAlignment() & BS_RIGHT)
  1362. rcGrouText.OffsetRect(+m_cxEdge, 0);
  1363. else
  1364. rcGrouText.OffsetRect(-m_cxEdge, 0);
  1365. pDC->ExcludeClipRect(&rcGrouText);
  1366. if (pButton->GetBorderStyle() == 1)
  1367. {
  1368. pDC->FillSolidRect(rcGroupBox.left, rcGroupBox.top, rcGroupBox.Width(), 1, m_crBorderShadow);
  1369. }
  1370. else
  1371. {
  1372. pDC->Draw3dRect(&rcGroupBox, m_crBorderShadow, m_crBorderShadow);
  1373. }
  1374. pDC->SelectClipRgn(NULL);
  1375. }
  1376. void CXTPButtonUltraFlatTheme::DrawCheckBoxMark(CDC* pDC, CXTPButton* pButton)
  1377. {
  1378. if (IsVisualThemeUsed(pButton))
  1379. {
  1380. CXTPButtonTheme::DrawCheckBoxMark(pDC, pButton);
  1381. return;
  1382. }
  1383. BOOL bPressed = pButton->IsPushed();
  1384. BOOL bSelected = pButton->IsHighlighted();
  1385. BOOL bEnabled = pButton->IsWindowEnabled();
  1386. BOOL bChecked = pButton->GetChecked();
  1387. CXTPClientRect rCXTPButton(pButton);
  1388. CRect rc;
  1389. CalcRect(pDC, pButton, &rc, CBR_CHECKBOX);
  1390. if (!bEnabled)
  1391. {
  1392. pDC->FillSolidRect(rc, GetXtremeColor(COLOR_3DFACE));
  1393. pDC->Draw3dRect(rc, GetXtremeColor(XPCOLOR_GRAYTEXT), GetXtremeColor(XPCOLOR_GRAYTEXT));
  1394. }
  1395. else
  1396. {
  1397. if (!m_bHiglightButtons)
  1398. {
  1399. pDC->FillSolidRect(rc, bSelected && bPressed ?
  1400. GetXtremeColor(COLOR_3DFACE) : GetXtremeColor(COLOR_WINDOW));
  1401. }
  1402. else
  1403. {
  1404. pDC->FillSolidRect(rc, bSelected && bPressed ?
  1405. m_crBackPushed : bPressed || bSelected ? m_crBackHilite : GetXtremeColor(COLOR_WINDOW));
  1406. }
  1407. COLORREF clrBorder = bSelected || bPressed ? m_crBorderHilite : m_crBorderShadow;
  1408. pDC->Draw3dRect(rc, clrBorder, clrBorder);
  1409. }
  1410. if (bChecked)
  1411. {
  1412. CPoint pt = rc.CenterPoint();
  1413. CXTPPenDC pen(pDC->GetSafeHdc(), GetXtremeColor(!bEnabled || bChecked == 2 ? XPCOLOR_GRAYTEXT : COLOR_BTNTEXT));
  1414. if (CXTPDrawHelpers::IsContextRTL(pDC))  // Revert Check Box
  1415. {
  1416. for (int i = 0; i < 3; i++)
  1417. {
  1418. pDC->MoveTo(pt.x + 3, pt.y - 1 + i);
  1419. pDC->LineTo(pt.x + 1, pt.y + 1 + i);
  1420. pDC->LineTo(pt.x - 4, pt.y - 4 + i);
  1421. }
  1422. }
  1423. else
  1424. {
  1425. for (int i = 0; i < 3; i++)
  1426. {
  1427. pDC->MoveTo(pt.x - 3, pt.y - 1 + i);
  1428. pDC->LineTo(pt.x - 1, pt.y + 1 + i);
  1429. pDC->LineTo(pt.x + 4, pt.y - 4 + i);
  1430. }
  1431. }
  1432. }
  1433. }
  1434. AFX_INLINE COLORREF Mix(CDC* pDC, int x, int y, COLORREF clrBorder, COLORREF clrFace, double a)
  1435. {
  1436. COLORREF clr = clrFace;
  1437. if (a < 0)
  1438. a = -a;
  1439. else
  1440. {
  1441. clr = pDC->GetPixel(x, y);
  1442. }
  1443. int r = int(GetRValue(clrBorder) + a * double(GetRValue(clr) -  GetRValue(clrBorder)));
  1444. int g = int(GetGValue(clrBorder) + a * double(GetGValue(clr) -  GetGValue(clrBorder)));
  1445. int b = int(GetBValue(clrBorder) + a * double(GetBValue(clr) -  GetBValue(clrBorder)));
  1446. return RGB(r, g, b);
  1447. }
  1448. void CXTPButtonTheme::AlphaEllipse(CDC* pDC, CRect rc, COLORREF clrBorder, COLORREF clrFace)
  1449. {
  1450. ASSERT(rc.Width() == rc.Height());
  1451. double x0 = double(rc.left + rc.right - 1) / 2;
  1452. double y0 = double(rc.top + rc.bottom - 1) / 2;
  1453. double radius = double(rc.right - rc.left - 1) / 2 - 0.25;
  1454. for (int x = rc.left; x < rc.right; x++)
  1455. for (int y = rc.top; y < rc.bottom; y++)
  1456. {
  1457. double distance = sqrt(pow(x0 - x, 2) + pow(y0 - y, 2));
  1458. if (distance >= radius - 1 && distance <= radius + 1)
  1459. {
  1460. pDC->SetPixel(x, y, Mix(pDC, x, y, clrBorder, clrFace, distance - radius));
  1461. }
  1462. else if (distance < radius - 1)
  1463. {
  1464. pDC->SetPixel(x, y, clrFace);
  1465. }
  1466. }
  1467. }
  1468. void CXTPButtonUltraFlatTheme::DrawRadioButtonMark(CDC* pDC, CXTPButton* pButton)
  1469. {
  1470. if (IsVisualThemeUsed(pButton))
  1471. {
  1472. CXTPButtonTheme::DrawRadioButtonMark(pDC, pButton);
  1473. return;
  1474. }
  1475. BOOL bPressed = pButton->IsPushed();
  1476. BOOL bSelected = pButton->IsHighlighted();
  1477. BOOL bEnabled = pButton->IsWindowEnabled();
  1478. BOOL bChecked = pButton->GetChecked();
  1479. CXTPClientRect rCXTPButton(pButton);
  1480. CRect rc;
  1481. CalcRect(pDC, pButton, &rc, CBR_RADIOBOX);
  1482. if (!bEnabled)
  1483. {
  1484. AlphaEllipse(pDC, rc, GetXtremeColor(XPCOLOR_GRAYTEXT), GetXtremeColor(XPCOLOR_3DFACE));
  1485. }
  1486. else
  1487. {
  1488. if (!m_bHiglightButtons)
  1489. {
  1490. AlphaEllipse(pDC, rc, m_crBorderShadow, bSelected && bPressed ? GetXtremeColor(COLOR_3DFACE) :
  1491. GetXtremeColor(COLOR_WINDOW));
  1492. }
  1493. else
  1494. {
  1495. AlphaEllipse(pDC, rc, bSelected || bPressed ? m_crBorderHilite : m_crBorderShadow,
  1496. bSelected && bPressed ? m_crBackPushed :
  1497. bPressed || bSelected ? m_crBackHilite : GetXtremeColor(COLOR_WINDOW));
  1498. }
  1499. }
  1500. if (bChecked)
  1501. {
  1502. COLORREF clrFace = GetXtremeColor(!bEnabled || bChecked == 2 ? XPCOLOR_GRAYTEXT : COLOR_BTNTEXT);
  1503. AlphaEllipse(pDC, CRect(rc.left + 4, rc.top + 4, rc.left + 9, rc.top + 9), clrFace, clrFace);
  1504. }
  1505. }
  1506. //////////////////////////////////////////////////////////////////////////
  1507. //
  1508. CXTPButtonOffice2000Theme::CXTPButtonOffice2000Theme()
  1509. {
  1510. m_nBorderWidth = 2;
  1511. m_bHiglightButtons = FALSE;
  1512. }
  1513. void CXTPButtonOffice2000Theme::DrawButtonBackground(CDC* pDC, CXTPButton* pButton)
  1514. {
  1515. BOOL bPressed = pButton->IsPushed();
  1516. BOOL bHot = pButton->IsHighlighted();
  1517. BOOL bChecked = pButton->GetChecked();
  1518. CXTPClientRect rc(pButton);
  1519. if (pButton->GetFlatStyle() && !bHot && !bPressed && !bChecked)
  1520. return;
  1521. if (pButton->GetUseVisualStyle() && m_themeButton.IsAppThemed())
  1522. {
  1523. DrawButtonVisualStyleBackground(pDC, pButton);
  1524. return;
  1525. }
  1526. pDC->FillSolidRect(rc, pButton->GetButtonBackColor());
  1527. BOOL bSelected = bPressed || bChecked;
  1528. pDC->Draw3dRect(rc,
  1529. bSelected ? m_crBorderShadow : m_crBorder3DHilite,
  1530. bSelected ? m_crBorder3DHilite : m_crBorderShadow);
  1531. }
  1532. //////////////////////////////////////////////////////////////////////////
  1533. // CXTPButtonOffice2007Theme
  1534. CXTPButtonOffice2007Theme::CXTPButtonOffice2007Theme()
  1535. {
  1536. m_nBorderWidth = 2;
  1537. m_bHiglightButtons = TRUE;
  1538. }
  1539. void CXTPButtonOffice2007Theme::RefreshMetrics(CXTPButton* pButton)
  1540. {
  1541. CXTPButtonUltraFlatTheme::RefreshMetrics(pButton);
  1542. m_crBorderShadow.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("Controls"), _T("GroupBoxFrame")));
  1543. }
  1544. void CXTPButtonOffice2007Theme::DrawCheckBoxMark(CDC* pDC, CXTPButton* pButton)
  1545. {
  1546. if (IsVisualThemeUsed(pButton))
  1547. {
  1548. CXTPButtonTheme::DrawCheckBoxMark(pDC, pButton);
  1549. return;
  1550. }
  1551. CXTPOffice2007Image* pImage = XTPOffice2007Images()->LoadFile(_T("TOOLBARBUTTONCHECKBOX"));
  1552. ASSERT(pImage);
  1553. if (!pImage)
  1554. {
  1555. CXTPButtonTheme::DrawCheckBoxMark(pDC, pButton);
  1556. return;
  1557. }
  1558. BOOL bPressed = pButton->IsPushed();
  1559. BOOL bSelected = pButton->IsHighlighted();
  1560. BOOL bEnabled = pButton->IsWindowEnabled();
  1561. BOOL bChecked = pButton->GetChecked();
  1562. CXTPClientRect rCXTPButton(pButton);
  1563. CRect rc;
  1564. CalcRect(pDC, pButton, &rc, CBR_CHECKBOX);
  1565. int nState = 0;
  1566. if (!bEnabled)
  1567. nState = 3;
  1568. else if (bSelected && bPressed)
  1569. nState = 2;
  1570. else if (bSelected)
  1571. nState = 1;
  1572. if (bChecked == 1)
  1573. nState += 4;
  1574. if (bChecked == 2)
  1575. nState += 8;
  1576. pImage->DrawImage(pDC, rc, pImage->GetSource(nState, 12), CRect(0, 0, 0, 0));
  1577. }
  1578. void CXTPButtonOffice2007Theme::DrawRadioButtonMark(CDC* pDC, CXTPButton* pButton)
  1579. {
  1580. if (IsVisualThemeUsed(pButton))
  1581. {
  1582. CXTPButtonTheme::DrawRadioButtonMark(pDC, pButton);
  1583. return;
  1584. }
  1585. CXTPOffice2007Image* pImage = XTPOffice2007Images()->LoadFile(_T("TOOLBARBUTTONRADIOBUTTON"));
  1586. ASSERT(pImage);
  1587. if (!pImage)
  1588. {
  1589. CXTPButtonTheme::DrawRadioButtonMark(pDC, pButton);
  1590. return;
  1591. }
  1592. CRect rc;
  1593. CalcRect(pDC, pButton, &rc, CBR_RADIOBOX);
  1594. BOOL bPressed = pButton->IsPushed();
  1595. BOOL bSelected = pButton->IsHighlighted();
  1596. BOOL bEnabled = pButton->IsWindowEnabled();
  1597. BOOL bChecked = pButton->GetChecked();
  1598. int nState = 0;
  1599. if (!bEnabled)
  1600. nState = 3;
  1601. else if (bSelected && bPressed)
  1602. nState = 2;
  1603. else if (bSelected)
  1604. nState = 1;
  1605. if (bChecked)
  1606. nState += 4;
  1607. pImage->DrawImage(pDC, rc, pImage->GetSource(nState, 8), CRect(0, 0, 0, 0));
  1608. }
  1609. void CXTPButtonOffice2007Theme::DrawButtonBackground(CDC* pDC, CXTPButton* pButton)
  1610. {
  1611. BOOL bPressed = pButton->IsPushed();
  1612. BOOL bSelected = pButton->IsHighlighted();
  1613. BYTE bStyle = pButton->GetButtonStyle();
  1614. BOOL bDefault = bStyle == BS_DEFPUSHBUTTON;
  1615. BOOL bEnabled = pButton->IsWindowEnabled();
  1616. BOOL bChecked = pButton->GetChecked();
  1617. CXTPClientRect rc(pButton);
  1618. if (pButton->GetFlatStyle() && !bSelected && !bPressed && !bChecked)
  1619. return;
  1620. if (pButton->GetUseVisualStyle() && m_themeButton.IsAppThemed())
  1621. {
  1622. DrawButtonVisualStyleBackground(pDC, pButton);
  1623. return;
  1624. }
  1625. CXTPOffice2007Image* pImage = XTPOffice2007Images()->LoadFile(_T("PUSHBUTTON"));
  1626. ASSERT(pImage);
  1627. if (!pImage)
  1628. {
  1629. CXTPButtonTheme::DrawButtonBackground(pDC, pButton);
  1630. return;
  1631. }
  1632. int nState = bDefault ? 4 : 0;
  1633. if (!bEnabled)
  1634. {
  1635. nState = 3;
  1636. }
  1637. else if (bChecked && !bSelected && !bPressed) nState = 2;
  1638. else if (bChecked && bSelected && !bPressed) nState = 1;
  1639. else if ((bSelected && bPressed) || pButton->IsPushed()) nState = 2;
  1640. else if (bSelected || bPressed) nState = 1;
  1641. if (nState != -1)
  1642. {
  1643. pImage->DrawImage(pDC, rc, pImage->GetSource(nState, 5), CRect(3, 3, 3, 3), 0xFF00FF);
  1644. }
  1645. }
  1646. //////////////////////////////////////////////////////////////////////////
  1647. // CXTPButtonOfficeXPTheme
  1648. CXTPButtonOfficeXPTheme::CXTPButtonOfficeXPTheme()
  1649. {
  1650. m_nBorderWidth = 2;
  1651. m_bOffsetHiliteText = FALSE;
  1652. }
  1653. void CXTPButtonOfficeXPTheme::RefreshMetrics(CXTPButton* pButton)
  1654. {
  1655. CXTPButtonUltraFlatTheme::RefreshMetrics(pButton);
  1656. m_crBack.SetStandardValue(GetXtremeColor(XPCOLOR_TOOLBAR_FACE));
  1657. m_crBackPushed.SetStandardValue(GetXtremeColor(XPCOLOR_HIGHLIGHT_PUSHED));
  1658. m_crBackHilite.SetStandardValue(GetXtremeColor(XPCOLOR_HIGHLIGHT));
  1659. m_crBorderShadow.SetStandardValue(GetXtremeColor(COLOR_3DSHADOW));
  1660. m_crBorderHilite.SetStandardValue(GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER));
  1661. m_crText.SetStandardValue(GetXtremeColor(XPCOLOR_TOOLBAR_TEXT));
  1662. m_crTextHilite.SetStandardValue(GetXtremeColor(XPCOLOR_HIGHLIGHT_TEXT));
  1663. m_crTextPushed.SetStandardValue(GetXtremeColor(XPCOLOR_PUSHED_TEXT));
  1664. m_crBackChecked.SetStandardValue(GetXtremeColor(XPCOLOR_HIGHLIGHT_CHECKED));
  1665. }
  1666. void CXTPButtonOfficeXPTheme::DrawButtonBackground(CDC* pDC, CXTPButton* pButton)
  1667. {
  1668. BOOL bPressed = pButton->IsPushed();
  1669. BOOL bHot = pButton->IsHighlighted();
  1670. BOOL bChecked = pButton->GetChecked();
  1671. CXTPClientRect rc(pButton);
  1672. if (pButton->GetFlatStyle() && !bHot && !bPressed && !bChecked)
  1673. return;
  1674. if (pButton->GetUseVisualStyle() && m_themeButton.IsAppThemed())
  1675. {
  1676. DrawButtonVisualStyleBackground(pDC, pButton);
  1677. return;
  1678. }
  1679. if (bHot || bPressed || bChecked)
  1680. {
  1681. pDC->FillSolidRect(rc, bPressed ? m_crBackPushed :
  1682. bChecked ? (bHot ? m_crBackPushed : m_crBackChecked) : m_crBackHilite);
  1683. pDC->Draw3dRect(rc, m_crBorderHilite,
  1684. m_crBorderHilite);
  1685. }
  1686. else
  1687. {
  1688. pDC->FillSolidRect(rc, m_crBack);
  1689. pDC->Draw3dRect(rc, m_crBorderShadow, m_crBorderShadow);
  1690. }
  1691. }
  1692. //////////////////////////////////////////////////////////////////////////
  1693. //
  1694. //////////////////////////////////////////////////////////////////////////
  1695. // CXTPButtonOffice2003Theme
  1696. CXTPButtonOffice2003Theme::CXTPButtonOffice2003Theme()
  1697. {
  1698. m_bLunaTheme = FALSE;
  1699. }
  1700. void CXTPButtonOffice2003Theme::RefreshMetrics(CXTPButton* pButton)
  1701. {
  1702. CXTPButtonOfficeXPTheme::RefreshMetrics(pButton);
  1703. XTPCurrentSystemTheme systemTheme = XTPColorManager()->GetCurrentSystemTheme();
  1704. if (systemTheme != xtpSystemThemeUnknown)
  1705. {
  1706. m_crBackHilite.SetStandardValue(RGB(255, 238, 194));
  1707. m_crBackPushed.SetStandardValue(RGB(254, 128, 62));
  1708. m_crBackChecked.SetStandardValue(RGB(255, 192, 111));
  1709. m_crText.SetStandardValue(0);
  1710. m_crTextHilite.SetStandardValue(0);
  1711. m_crTextPushed.SetStandardValue(0);
  1712. }
  1713. switch (systemTheme)
  1714. {
  1715. case xtpSystemThemeBlue:
  1716. m_crBack.SetStandardValue(RGB(169, 199, 240));
  1717. m_crBorderShadow.SetStandardValue(RGB(127, 157, 185));
  1718. m_crBorderHilite.SetStandardValue(RGB(0, 0, 128));
  1719. break;
  1720. case xtpSystemThemeOlive:
  1721. m_crBack.SetStandardValue(RGB(197, 212, 159));
  1722. m_crBorderShadow.SetStandardValue(RGB(164, 185, 127));
  1723. m_crBorderHilite.SetStandardValue(RGB(63, 93, 56));
  1724. break;
  1725. case xtpSystemThemeSilver:
  1726. m_crBack.SetStandardValue(RGB(192, 192, 211));
  1727. m_crBorderShadow.SetStandardValue(RGB(165, 172, 178));
  1728. m_crBorderHilite.SetStandardValue(RGB(75, 75, 11));
  1729. break;
  1730. }
  1731. m_bLunaTheme = systemTheme != xtpSystemThemeUnknown;
  1732. }
  1733. void CXTPButtonOffice2003Theme::DrawButtonBackground(CDC* pDC, CXTPButton* pButton)
  1734. {
  1735. if (!m_bLunaTheme)
  1736. {
  1737. CXTPButtonOfficeXPTheme::DrawButtonBackground(pDC, pButton);
  1738. return;
  1739. }
  1740. BOOL bPressed = pButton->IsPushed();
  1741. BOOL bHot = pButton->IsHighlighted();
  1742. BOOL bChecked = pButton->GetChecked();
  1743. CXTPClientRect rc(pButton);
  1744. if (pButton->GetFlatStyle() && !bHot && !bPressed && !bChecked)
  1745. return;
  1746. if (pButton->GetUseVisualStyle() && m_themeButton.IsAppThemed())
  1747. {
  1748. DrawButtonVisualStyleBackground(pDC, pButton);
  1749. return;
  1750. }
  1751. if (bHot || bPressed || bChecked)
  1752. {
  1753. if (bPressed)
  1754. {
  1755. XTPDrawHelpers()->GradientFill(pDC, &rc,
  1756. XTPColorManager()->grcLunaPushed, FALSE);
  1757. }
  1758. else if (bHot)
  1759. {
  1760. XTPDrawHelpers()->GradientFill(pDC, &rc,
  1761. XTPColorManager()->grcLunaSelected, FALSE);
  1762. }
  1763. else if (bChecked)
  1764. {
  1765. XTPDrawHelpers()->GradientFill(pDC, &rc,
  1766. XTPColorManager()->grcLunaChecked, FALSE);
  1767. }
  1768. pDC->Draw3dRect(rc, m_crBorderHilite,
  1769. m_crBorderHilite);
  1770. }
  1771. else
  1772. {
  1773. pDC->FillSolidRect(rc, m_crBack);
  1774. pDC->Draw3dRect(rc, m_crBorderShadow, m_crBorderShadow);
  1775. }
  1776. }