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

对话框与窗口

开发平台:

Visual C++

  1. // XTButton.cpp : implementation of the CXTButton 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 "Common/XTPWinThemeWrapper.h"
  22. #include "Common/XTPColorManager.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "XTThemeManager.h"
  25. #include "XTButtonTheme.h"
  26. #include "XTButton.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. #ifndef WM_QUERYUISTATE
  33. #define WM_UPDATEUISTATE    0x0128
  34. #define WM_QUERYUISTATE     0x0129
  35. #define UISF_HIDEACCEL      0x2
  36. #define UISF_HIDEFOCUS      0x1
  37. #endif
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CXTButton
  40. /////////////////////////////////////////////////////////////////////////////
  41. IMPLEMENT_DYNAMIC(CXTButton, CButton)
  42. IMPLEMENT_THEME_HOST(CXTButton)
  43. IMPLEMENT_THEME_REFRESH(CXTButton, CButton)
  44. CXTButton::CXTButton(CRuntimeClass* pThemeFactoryClass/*=NULL*/)
  45. : CXTThemeManagerStyleHost(pThemeFactoryClass ? pThemeFactoryClass : GetThemeFactoryClass())
  46. , m_nBorderGap(4)
  47. , m_nImageGap(8)
  48. , m_bUserPosition(false)
  49. , m_bChecked(false)
  50. , m_dwxStyle(BS_XT_FLAT | BS_XT_SHOWFOCUS)
  51. , m_sizeImage(CSize(0, 0))
  52. , m_ptImage(CPoint(0, 0))
  53. , m_ptText(CPoint(0, 0))
  54. , m_pIcon(NULL)
  55. , m_bPreSubclassInit(true)
  56. {
  57. m_bOwnerDraw = FALSE;
  58. m_bPushed = FALSE;
  59. m_bHot = FALSE;
  60. }
  61. CXTButton::~CXTButton()
  62. {
  63. CleanUpGDI();
  64. CMDTARGET_RELEASE(m_pIcon);
  65. }
  66. HICON CXTButton::GetNormalIcon()
  67. {
  68. return m_pIcon ? (HICON)m_pIcon->GetIcon() : NULL;
  69. }
  70. HICON CXTButton::GetSelectedIcon()
  71. {
  72. return m_pIcon ? (HICON)m_pIcon->GetHotIcon() : NULL;
  73. }
  74. BEGIN_MESSAGE_MAP(CXTButton, CButton)
  75. //{{AFX_MSG_MAP(CXTButton)
  76. ON_WM_ERASEBKGND()
  77. ON_WM_MOUSEMOVE()
  78. ON_WM_CREATE()
  79. ON_WM_SETFOCUS()
  80. ON_WM_KILLFOCUS()
  81. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  82. ON_WM_PAINT()
  83. ON_WM_SYSCOLORCHANGE()
  84. //}}AFX_MSG_MAP
  85. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  86. ON_MESSAGE(BM_SETSTYLE, OnDefaultAndInvalidate)
  87. ON_MESSAGE(BM_SETCHECK, OnDefaultAndInvalidate)
  88. ON_MESSAGE(WM_CAPTURECHANGED, OnDefaultAndInvalidate)
  89. ON_MESSAGE_VOID(WM_ENABLE, OnInvalidate)
  90. ON_MESSAGE(WM_UPDATEUISTATE, OnUpdateUIState)
  91. ON_MESSAGE(BM_SETSTATE, OnSetState)
  92. ON_MESSAGE(WM_SETTEXT, OnSetText)
  93. //}}AFX_MSG_MAP
  94. ON_WM_GETDLGCODE()
  95. ON_MESSAGE(BM_SETSTYLE, OnSetStyle)
  96. END_MESSAGE_MAP()
  97. void CXTButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  98. {
  99. GetTheme()->DrawItem(lpDIS, this);
  100. }
  101. void CXTButton::OnMouseMove(UINT nFlags, CPoint point)
  102. {
  103. if (GetButtonStyle() == BS_GROUPBOX)
  104. return;
  105. CButton::OnMouseMove(nFlags, point);
  106. CRect rc;
  107. GetClientRect(&rc);
  108. BOOL bHot = rc.PtInRect(point);
  109. if (bHot != m_bHot)
  110. {
  111. m_bHot = bHot;
  112. Invalidate(FALSE);
  113. if (m_bHot)
  114. {
  115. TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, HOVER_DEFAULT};
  116. _TrackMouseEvent(&tme);
  117. }
  118. }
  119. }
  120. LRESULT CXTButton::OnSetState(WPARAM wParam, LPARAM /*lParam*/)
  121. {
  122. BOOL bVisible = GetStyle() & WS_VISIBLE;
  123. if (bVisible) ModifyStyle(WS_VISIBLE, 0);
  124. Default();
  125. if (bVisible) ModifyStyle(0, WS_VISIBLE);
  126. m_bPushed = (wParam != 0);
  127. Invalidate(FALSE);
  128. return 0;
  129. }
  130. void CXTButton::OnSetFocus(CWnd* pOldWnd)
  131. {
  132. CButton::OnSetFocus(pOldWnd);
  133. Invalidate(FALSE);
  134. }
  135. void CXTButton::OnKillFocus(CWnd* pNewWnd)
  136. {
  137. CButton::OnKillFocus(pNewWnd);
  138. Invalidate(FALSE);
  139. }
  140. LRESULT CXTButton::OnDefaultAndInvalidate(WPARAM, LPARAM)
  141. {
  142. LRESULT lResult = Default();
  143. Invalidate(FALSE);
  144. return lResult;
  145. }
  146. void CXTButton::OnInvalidate()
  147. {
  148. Invalidate(FALSE);
  149. }
  150. LRESULT CXTButton::OnPrintClient(WPARAM wParam, LPARAM lParam)
  151. {
  152. if ((lParam & PRF_CLIENT) == 0)
  153. return Default();
  154. CDC* pDC = CDC::FromHandle((HDC)wParam);
  155. if (pDC) OnDraw(pDC);
  156. return 1;
  157. }
  158. void CXTButton::OnPaint()
  159. {
  160. CPaintDC dcPaint(this);
  161. CXTPBufferDC dc(dcPaint); // device context for painting
  162. OnDraw(&dc);
  163. }
  164. void CXTButton::OnDraw(CDC* pDC)
  165. {
  166. DRAWITEMSTRUCT dis;
  167. ZeroMemory(&dis, sizeof(DRAWITEMSTRUCT));
  168. dis.CtlType = ODT_BUTTON;
  169. dis.CtlID = GetDlgCtrlID();
  170. dis.itemState = 0;
  171. if (::GetFocus() == m_hWnd) dis.itemState |= ODS_FOCUS;
  172. if (m_bPushed) dis.itemState |= ODS_SELECTED;
  173. LRESULT dwState = SendMessage(WM_QUERYUISTATE);
  174. if (dwState & UISF_HIDEACCEL) dis.itemState |= ODS_NOACCEL;
  175. if (dwState & UISF_HIDEFOCUS) dis.itemState |= ODS_NOFOCUSRECT;
  176. if (!IsWindowEnabled()) dis.itemState |= ODS_DISABLED;
  177. dis.hwndItem = m_hWnd;
  178. dis.hDC = pDC->GetSafeHdc();
  179. dis.rcItem = CXTPClientRect(this);
  180. DrawItem(&dis);
  181. }
  182. BYTE CXTButton::GetButtonStyle() const
  183. {
  184. BYTE bStyle = BYTE(GetStyle() & 0xF);
  185. return bStyle;
  186. }
  187. LRESULT CXTButton::OnUpdateUIState(WPARAM wParam, LPARAM lParam)
  188. {
  189. LRESULT lResult = ::DefWindowProc(m_hWnd, WM_UPDATEUISTATE, wParam, lParam);
  190. Invalidate(FALSE);
  191. return lResult;
  192. }
  193. LRESULT CXTButton::OnSetText(WPARAM wParam, LPARAM lParam)
  194. {
  195. LRESULT lResult = DefWindowProc(WM_SETTEXT, wParam, lParam);
  196. Invalidate(FALSE);
  197. return lResult;
  198. }
  199. BOOL CXTButton::OnEraseBkgnd(CDC* /*pDC*/)
  200. {
  201. return TRUE;
  202. }
  203. bool CXTButton::Init()
  204. {
  205. m_bOwnerDraw = m_hWnd && ((GetStyle() & 0xF) == BS_OWNERDRAW);
  206. if (m_hWnd) Invalidate(FALSE);
  207. return true;
  208. }
  209. void CXTButton::PreSubclassWindow()
  210. {
  211. CButton::PreSubclassWindow();
  212. if (m_bPreSubclassInit)
  213. {
  214. // Initialize the control.
  215. Init();
  216. }
  217. }
  218. int CXTButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
  219. {
  220. if (CButton::OnCreate(lpCreateStruct) == -1)
  221. return -1;
  222. // Initialize the control.
  223. Init();
  224. return 0;
  225. }
  226. BOOL CXTButton::PreCreateWindow(CREATESTRUCT& cs)
  227. {
  228. if (!CButton::PreCreateWindow(cs))
  229. return FALSE;
  230. // When creating controls dynamically Init() must
  231. // be called from OnCreate() and not from
  232. // PreSubclassWindow().
  233. m_bPreSubclassInit = false;
  234. return TRUE;
  235. }
  236. UINT CXTButton::OnGetDlgCode()
  237. {
  238. if (m_bOwnerDraw)
  239. {
  240. if (GetFocus() == this)
  241. return DLGC_DEFPUSHBUTTON | DLGC_BUTTON;
  242. return DLGC_BUTTON ;
  243. }
  244. return CButton::OnGetDlgCode();
  245. }
  246. LRESULT CXTButton::OnSetStyle(WPARAM wParam, LPARAM lParam)
  247. {
  248. if (m_bOwnerDraw)
  249. {
  250. DWORD dwOldStyle = GetStyle();
  251. ModifyStyle(0, (long)wParam | BS_OWNERDRAW,0);
  252. if ((dwOldStyle != GetStyle()) && LOWORD(lParam))
  253. Invalidate();
  254. return 0;
  255. }
  256. return OnDefaultAndInvalidate(wParam, lParam);
  257. }
  258. void CXTButton::OnMouseLeave()
  259. {
  260. OnMouseMove(0, CPoint(-1, -1));
  261. }
  262. //////////////////////////////////////////////////////////////////////////
  263. //
  264. CSize CXTButton::GetImageSize() const
  265. {
  266. if (!GetTheme()->IsIconVisible())
  267. return CSize(0, 0);
  268. return m_sizeImage;
  269. }
  270. CPoint CXTButton::GetImagePoint() const
  271. {
  272. if (!GetTheme()->IsIconVisible())
  273. return CPoint(0, 0);
  274. return m_ptImage;
  275. }
  276. CPoint CXTButton::GetTextPoint() const
  277. {
  278. if (!GetTheme()->IsIconVisible())
  279. return CPoint(0, 0);
  280. return m_ptText;
  281. }
  282. void CXTButton::CleanUpGDI()
  283. {
  284. if (m_pIcon)
  285. {
  286. m_pIcon->Refresh();
  287. }
  288. }
  289. BOOL CXTButton::SetIcon(CSize size, UINT nID, UINT nHotID/*= 0*/, BOOL bRedraw/*= TRUE*/)
  290. {
  291. return CXTButton::SetIcon(
  292. size, MAKEINTRESOURCE(nID), MAKEINTRESOURCE(nHotID), bRedraw);
  293. }
  294. BOOL CXTButton::SetIcon(CSize size, LPCTSTR lpszID, LPCTSTR lpszHotID/*= NULL*/, BOOL bRedraw/*= TRUE*/)
  295. {
  296. CXTPImageManagerIconHandle hIcon;
  297. CXTPImageManagerIconHandle hIconHot;
  298. hIcon.CreateIconFromResource(lpszID, size);
  299. // Return false if the icon handle is NULL.
  300. if (hIcon.IsEmpty())
  301. {
  302. TRACE0("Failed to load Icon resource.n");
  303. return FALSE;
  304. }
  305. // If we are using a pushed image as well...
  306. if (lpszHotID)
  307. {
  308. hIconHot.CreateIconFromResource(lpszHotID, size);
  309. // Return false if the icon handle is NULL.
  310. if (hIconHot.IsEmpty())
  311. {
  312. TRACE0("Failed to load Icon resource.n");
  313. return FALSE;
  314. }
  315. }
  316. return CXTButton::SetIcon(size, hIcon, hIconHot, bRedraw);
  317. }
  318. BOOL CXTButton::SetIcon(CSize size, CXTPImageManagerIcon* pIcon, BOOL bRedraw/*= TRUE*/)
  319. {
  320. m_sizeImage = size;
  321. // Construct the icon manager.
  322. CMDTARGET_RELEASE(m_pIcon);
  323. m_pIcon = pIcon;
  324. // Redraw the button.
  325. if (::IsWindow(m_hWnd) && bRedraw)
  326. Invalidate();
  327. return TRUE;
  328. }
  329. BOOL CXTButton::SetIcon(CSize size, CXTPImageManagerIconHandle hIcon, CXTPImageManagerIconHandle hIconHot, BOOL bRedraw/*= TRUE*/)
  330. {
  331. ASSERT(!hIcon.IsEmpty());
  332. // Save the image size and set the icon
  333. // handles to NULL.
  334. size = size != CSize(0) ? size : hIcon.GetExtent();
  335. CXTPImageManagerIcon* pIcon = new CXTPImageManagerIcon(0, size.cx, size.cy);
  336. pIcon->SetIcon(hIcon);
  337. if (!hIconHot.IsEmpty())
  338. pIcon->SetHotIcon(hIconHot);
  339. return SetIcon(size, pIcon, bRedraw);
  340. }
  341. BOOL CXTButton::SetIcon(CSize size, HICON hIcon, HICON hIconHot/*= NULL*/, BOOL bRedraw/*= TRUE*/)
  342. {
  343. return SetIcon(size, CXTPImageManagerIconHandle(hIcon), CXTPImageManagerIconHandle(hIconHot), bRedraw);
  344. }
  345. BOOL CXTButton::SetBitmap(CSize size, UINT nID, BOOL bRedraw/*= TRUE*/)
  346. {
  347. // Free previous resources (if any).
  348. CXTPImageManagerIconHandle hIconHandle;
  349. BOOL bAlphaBitmap = FALSE;
  350. HBITMAP hBitmap = CXTPImageManagerIcon::LoadBitmapFromResource(MAKEINTRESOURCE(nID), &bAlphaBitmap);
  351. if (!hBitmap)
  352. return FALSE;
  353. if (bAlphaBitmap)
  354. {
  355. hIconHandle = hBitmap; // Will call DeleteObject;
  356. }
  357. else
  358. {
  359. CBitmap bmpIcon;
  360. bmpIcon.Attach(hBitmap);
  361. // convert the bitmap to a transparent icon.
  362. HICON hIcon = CXTPTransparentBitmap(bmpIcon).ConvertToIcon();
  363. hIconHandle = hIcon; // Will call DestoyIcon;
  364. }
  365. if (hIconHandle.IsEmpty())
  366. return FALSE;
  367. return CXTButton::SetIcon(size, hIconHandle, CXTPImageManagerIconHandle(), bRedraw);
  368. }
  369. BOOL CXTButton::SetTextAndImagePos(CPoint ptImage, CPoint ptText, BOOL bRedraw/*= TRUE*/)
  370. {
  371. m_ptImage = ptImage;
  372. m_ptText = ptText;
  373. // Redraw the button.
  374. if (::IsWindow(m_hWnd) && bRedraw)
  375. Invalidate();
  376. m_bUserPosition = TRUE;
  377. return TRUE;
  378. }
  379. DWORD CXTButton::SetXButtonStyle(DWORD dwxStyle, BOOL bRedraw/*= TRUE*/)
  380. {
  381. DWORD dwOldStyle = m_dwxStyle;
  382. m_dwxStyle = dwxStyle;
  383. if ((m_dwxStyle & BS_XT_XPFLAT) == BS_XT_XPFLAT)
  384. SetTheme(new CXTButtonThemeOfficeXP());
  385. else if ((m_dwxStyle & BS_XT_FLAT) == BS_XT_FLAT)
  386. SetTheme(new CXTButtonTheme());
  387. // Redraw the button.
  388. if (::IsWindow(m_hWnd) && bRedraw)
  389. Invalidate();
  390. return dwOldStyle;
  391. }
  392. BOOL CXTButton::IsThemeValid() const
  393. {
  394. return (GetTheme() != NULL);
  395. }
  396. CXTPImageManagerIcon* CXTButton::GetIcon() const
  397. {
  398. return m_pIcon;
  399. }
  400. CString CXTButton::GetButtonText(BOOL bRemoveAmpersand)
  401. {
  402. CString strText;
  403. GetWindowText(strText);
  404. if (bRemoveAmpersand)
  405. XTPDrawHelpers()->StripMnemonics(strText);
  406. return strText;
  407. }
  408. void CXTButton::SetAlternateColors(COLORREF clr3DFace, COLORREF clr3DHilight, COLORREF clr3DShadow, COLORREF clrBtnText)
  409. {
  410. if (IsThemeValid())
  411. {
  412. GetTheme()->SetAlternateColors(
  413. clr3DFace, clr3DHilight, clr3DShadow, clrBtnText);
  414. }
  415. }
  416. void CXTButton::SetColorFace(COLORREF clrFace)
  417. {
  418. if (IsThemeValid())
  419. {
  420. GetTheme()->SetColorFace(clrFace);
  421. }
  422. }
  423. COLORREF CXTButton::GetColorFace()
  424. {
  425. if (IsThemeValid())
  426. {
  427. return GetTheme()->GetColorFace();
  428. }
  429. return GetXtremeColor(COLOR_3DFACE);
  430. }
  431. void CXTButton::SetColorHilite(COLORREF clrHilite)
  432. {
  433. if (IsThemeValid())
  434. {
  435. GetTheme()->SetColorHilite(clrHilite);
  436. }
  437. }
  438. void CXTButton::SetColorShadow(COLORREF clrShadow)
  439. {
  440. if (IsThemeValid())
  441. {
  442. GetTheme()->SetColorShadow(clrShadow);
  443. }
  444. }
  445. void CXTButton::SetColorText(COLORREF clrText)
  446. {
  447. if (IsThemeValid())
  448. {
  449. GetTheme()->SetColorText(clrText);
  450. }
  451. }
  452. void CXTButton::SetXPFlatColors(COLORREF clrBorder, COLORREF clrHighlight, COLORREF clrPressed)
  453. {
  454. if (IsThemeValid())
  455. {
  456. CXTButtonTheme* pButtonTheme = GetTheme();
  457. if (pButtonTheme->GetTheme() == xtThemeOfficeXP)
  458. {
  459. ((CXTButtonThemeOfficeXP*)pButtonTheme)->SetColorHilite(clrBorder);
  460. ((CXTButtonThemeOfficeXP*)pButtonTheme)->SetColorShadow(clrBorder);
  461. ((CXTButtonThemeOfficeXP*)pButtonTheme)->SetBackHiliteColor(clrHighlight);
  462. ((CXTButtonThemeOfficeXP*)pButtonTheme)->SetBackPushedColor(clrPressed);
  463. }
  464. }
  465. }
  466. void CXTButton::ResetImage()
  467. {
  468. if (IsThemeValid())
  469. {
  470. if (GetTheme()->IsIconVisible())
  471. {
  472. GetTheme()->ShowIcon(FALSE);
  473. }
  474. else
  475. {
  476. GetTheme()->ShowIcon(TRUE);
  477. }
  478. Invalidate();
  479. }
  480. }
  481. CFont* CXTButton::SetFontEx(CFont* pFont)
  482. {
  483. CFont* pOldFont = GetFont();
  484. CButton::SetFont(pFont);
  485. return pOldFont;
  486. }