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

对话框与窗口

开发平台:

Visual C++

  1. // XTColorPicker.cpp : implementation of the CXTColorPicker 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/XTPDrawHelpers.h"
  23. #include "XTDefines.h"
  24. #include "XTGlobal.h"
  25. #include "XTButton.h"
  26. #include "XTColorRef.h"
  27. #include "XTColorSelectorCtrl.h"
  28. #include "XTColorPopup.h"
  29. #include "XTColorPicker.h"
  30. #include "XTMemDC.h"
  31. #include "XTThemeManager.h"
  32. #include "XTButtonTheme.h"
  33. #include "XTHelpers.h"
  34. #ifdef _DEBUG
  35. #define new DEBUG_NEW
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39. const UINT WM_XT_SHOWPOPUP = (WM_XTP_CONTROLS_BASE + 29);
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CXTColorPickerTheme
  42. /////////////////////////////////////////////////////////////////////////////
  43. class CXTColorPickerTheme : public CXTButtonTheme
  44. {
  45. protected:
  46. virtual COLORREF GetTextColor (UINT nState, CXTButton* pButton);
  47. virtual BOOL DrawWinThemeBackground(LPDRAWITEMSTRUCT lpDIS, CXTButton* pButton);
  48. virtual BOOL DrawButtonThemeBackground(LPDRAWITEMSTRUCT lpDIS, CXTButton* pButton);
  49. virtual void DrawButtonText (CDC* pDC, UINT nState, CRect& rcItem, CXTButton* pButton);
  50. virtual void DrawFocusRect (CDC* pDC, UINT nState, CRect& rcItem, CXTButton* pButton);
  51. private:
  52. void DrawArrow(CDC* pDC, CRect& rcArrow, COLORREF crArrow);
  53. void DrawColorPicker(LPDRAWITEMSTRUCT lpDIS, CXTColorPicker* pColorPicker);
  54. };
  55. COLORREF CXTColorPickerTheme::GetTextColor(UINT nState, CXTButton* pButton)
  56. {
  57. CXTColorPicker* pColorPicker = DYNAMIC_DOWNCAST(CXTColorPicker, pButton);
  58. ASSERT_VALID(pColorPicker);
  59. if (nState & ODS_DISABLED)
  60. return m_crTextDisabled;
  61. COLORREF clr;
  62. if (pColorPicker->IsTextInColor())
  63. clr = pColorPicker->GetColor();
  64. else
  65. clr = pColorPicker->GetContrastColor();
  66. return clr;
  67. }
  68. void CXTColorPickerTheme::DrawButtonText(CDC* pDC, UINT nState, CRect& rcItem, CXTButton* pButton)
  69. {
  70. CXTColorPicker* pColorPicker = DYNAMIC_DOWNCAST(CXTColorPicker, pButton);
  71. ASSERT_VALID(pColorPicker);
  72. // Draw the window text (if any)
  73. if (pColorPicker->IsTextShown())
  74. CXTButtonTheme::DrawButtonText(pDC, nState, rcItem, pButton);
  75. }
  76. void CXTColorPickerTheme::DrawFocusRect(CDC* pDC, UINT /*nState*/, CRect& rcItem, CXTButton* pButton)
  77. {
  78. if (!UseWinXPThemes(pButton))
  79. {
  80. CXTContextTextColorHandler foreHandler(pDC, m_crText);
  81. pButton->GetClientRect(&rcItem);
  82. rcItem.DeflateRect(3, 3);
  83. pDC->DrawFocusRect(rcItem);
  84. }
  85. }
  86. void CXTColorPickerTheme::DrawArrow(CDC* pDC, CRect& rcArrow, COLORREF crArrow)
  87. {
  88. POINT ptsArrow[3];
  89. int x = rcArrow.CenterPoint().x;
  90. int y = rcArrow.CenterPoint().y;
  91. ptsArrow[0].x = x-4;
  92. ptsArrow[0].y = y-2;
  93. ptsArrow[1].x = x + 4;
  94. ptsArrow[1].y = y-2;
  95. ptsArrow[2].x = x;
  96. ptsArrow[2].y = y + 2;
  97. CXTPBrushDC dcBrush(pDC->GetSafeHdc(), crArrow);
  98. CXTPPenDC dcPen(pDC->GetSafeHdc(), crArrow);
  99. pDC->SetPolyFillMode(WINDING);
  100. pDC->Polygon(ptsArrow, 3);
  101. }
  102. void CXTColorPickerTheme::DrawColorPicker(LPDRAWITEMSTRUCT lpDIS, CXTColorPicker* pColorPicker)
  103. {
  104. // draw the button arrow.
  105. CRect rcArrow(lpDIS->rcItem);
  106. rcArrow.left = rcArrow.right-XTAuxData().cxHThumb - 2;
  107. if (lpDIS->itemState & ODS_SELECTED)
  108. {
  109. rcArrow.OffsetRect(1, 1);
  110. }
  111. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  112. DrawArrow(pDC, rcArrow, CXTButtonTheme::GetTextColor(lpDIS->itemState, pColorPicker));
  113. // draw the color box.
  114. CRect rcItem;
  115. rcItem.left = lpDIS->rcItem.left + 5;
  116. rcItem.right = lpDIS->rcItem.right - XTAuxData().cxHThumb;
  117. rcItem.top = lpDIS->rcItem.top + 5;
  118. rcItem.bottom = lpDIS->rcItem.bottom - 5;
  119. if ((lpDIS->itemState & ODS_SELECTED) || (pColorPicker->GetCheck() == 1))
  120. rcItem.OffsetRect(1, 1);
  121. // create and select the brush for the rectangle background.
  122. COLORREF clrRect = (lpDIS->itemState & ODS_DISABLED) ? GetXtremeColor(COLOR_3DFACE) : pColorPicker->GetColor();
  123. if (pColorPicker->IsTextShown() && pColorPicker->IsTextInColor())
  124. clrRect = pColorPicker->GetContrastColor();
  125. CXTPBrushDC dcBrush(pDC->m_hDC, clrRect);
  126. // create and select the pen for the rectangle border.
  127. COLORREF crPen = (lpDIS->itemState & ODS_DISABLED) ? GetXtremeColor(COLOR_3DSHADOW) : RGB(0, 0, 0);
  128. CXTPPenDC dcPen(pDC->m_hDC, crPen);
  129. // draw the color rectangle.
  130. pDC->Rectangle(rcItem);
  131. lpDIS->rcItem = rcItem;
  132. }
  133. BOOL CXTColorPickerTheme::DrawWinThemeBackground(LPDRAWITEMSTRUCT lpDIS, CXTButton* pButton)
  134. {
  135. CXTColorPicker* pColorPicker = DYNAMIC_DOWNCAST(CXTColorPicker, pButton);
  136. ASSERT_VALID(pColorPicker);
  137. // set display flags based on state.
  138. if (pColorPicker->m_bPopupActive)
  139. lpDIS->itemState |= ODS_SELECTED;
  140. if (!CXTButtonTheme::DrawWinThemeBackground(lpDIS, pButton))
  141. return FALSE;
  142. DrawColorPicker(lpDIS, pColorPicker);
  143. return TRUE;
  144. }
  145. BOOL CXTColorPickerTheme::DrawButtonThemeBackground(LPDRAWITEMSTRUCT lpDIS, CXTButton* pButton)
  146. {
  147. CXTColorPicker* pColorPicker = DYNAMIC_DOWNCAST(CXTColorPicker, pButton);
  148. ASSERT_VALID(pColorPicker);
  149. // set display flags based on state.
  150. if (pColorPicker->m_bPopupActive)
  151. lpDIS->itemState |= ODS_SELECTED;
  152. if (!CXTButtonTheme::DrawButtonThemeBackground(lpDIS, pButton))
  153. return FALSE;
  154. DrawColorPicker(lpDIS, pColorPicker);
  155. return TRUE;
  156. }
  157. /////////////////////////////////////////////////////////////////////////////
  158. // DDX Routines
  159. _XTP_EXT_CLASS void AFXAPI DDX_XTColorPicker(CDataExchange *pDX, int nIDC, COLORREF& value)
  160. {
  161. HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  162. ASSERT (hWndCtrl != NULL);
  163. CXTColorPicker* pColorPicker = (CXTColorPicker*) CWnd::FromHandle(hWndCtrl);
  164. if (pDX->m_bSaveAndValidate)
  165. {
  166. value = pColorPicker->GetColor();
  167. }
  168. else
  169. {
  170. pColorPicker->SetColor(value);
  171. }
  172. }
  173. /////////////////////////////////////////////////////////////////////////////
  174. // CXTColorPicker
  175. CXTColorPicker::CXTColorPicker()
  176. : m_dwPopup(CPS_XT_EXTENDED | CPS_XT_MORECOLORS)
  177. , m_clrSelected(CLR_DEFAULT)
  178. , m_clrDefault(CLR_DEFAULT)
  179. , m_bShowText(FALSE)
  180. , m_bColorText(FALSE)
  181. , m_bPopupActive(FALSE)
  182. {
  183. m_dwxStyle = BS_XT_SHOWFOCUS | BS_XT_WINXP_COMPAT;
  184. SetTheme(new CXTColorPickerTheme);
  185. m_nCols = 8;
  186. m_pExtendedColors = 0;
  187. m_nExtendedColors = 0;
  188. }
  189. CXTColorPicker::~CXTColorPicker()
  190. {
  191. }
  192. IMPLEMENT_DYNAMIC(CXTColorPicker, CXTButton)
  193. BEGIN_MESSAGE_MAP(CXTColorPicker, CXTButton)
  194. //{{AFX_MSG_MAP(CXTColorPicker)
  195. //}}AFX_MSG_MAP
  196. ON_MESSAGE(CPN_XT_SELCHANGE, OnSelChange)
  197. ON_MESSAGE(CPN_XT_DROPDOWN, OnDropDown)
  198. ON_MESSAGE(CPN_XT_CLOSEUP, OnCloseUp)
  199. ON_MESSAGE(CPN_XT_SELENDOK, OnSelEndOK)
  200. ON_MESSAGE(CPN_XT_SELENDCANCEL, OnSelEndCancel)
  201. ON_MESSAGE(CPN_XT_SELNOFILL, OnSelNoFill)
  202. ON_MESSAGE_VOID(WM_XT_SHOWPOPUP, OnShowPopup)
  203. END_MESSAGE_MAP()
  204. /////////////////////////////////////////////////////////////////////////////
  205. // CXTColorPicker message handlers
  206. LRESULT CXTColorPicker::OnSelChange(WPARAM /*wParam*/, LPARAM /*lParam*/)
  207. {
  208. CWnd* pOwner = GetOwner();
  209. ASSERT_VALID(pOwner);
  210. if (pOwner != NULL)
  211. {
  212. // Notify of selection change.
  213. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  214. CPN_XT_SELCHANGE), (LPARAM)m_hWnd);
  215. }
  216. return 0;
  217. }
  218. LRESULT CXTColorPicker::OnDropDown(WPARAM /*wParam*/, LPARAM /*lParam*/)
  219. {
  220. CWnd* pOwner = GetOwner();
  221. ASSERT_VALID(pOwner);
  222. if (pOwner != NULL)
  223. {
  224. // Notify of popup activation.
  225. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  226. CPN_XT_DROPDOWN), (LPARAM)m_hWnd);
  227. }
  228. return 0;
  229. }
  230. LRESULT CXTColorPicker::OnCloseUp(WPARAM /*wParam*/, LPARAM /*lParam*/)
  231. {
  232. m_bPopupActive = FALSE;
  233. CWnd* pOwner = GetOwner();
  234. ASSERT_VALID(pOwner);
  235. if (pOwner != NULL)
  236. {
  237. // Notify of popup close up.
  238. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  239. CPN_XT_CLOSEUP), (LPARAM)m_hWnd);
  240. }
  241. ReleaseCapture();
  242. SetFocus();
  243. Invalidate();
  244. return 0;
  245. }
  246. LRESULT CXTColorPicker::OnSelEndOK(WPARAM wParam, LPARAM /*lParam*/)
  247. {
  248. CWnd* pOwner = GetOwner();
  249. ASSERT_VALID(pOwner);
  250. if (pOwner != NULL)
  251. {
  252. SetColor((COLORREF)wParam);
  253. // Notify of popup close up.
  254. // NB: doing so may destroy the picker so lets copy off
  255. // the window handle/control ID for safety
  256. HWND hWndSender = m_hWnd;
  257. int nControlID = GetDlgCtrlID();
  258. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(nControlID,
  259. CPN_XT_CLOSEUP), (LPARAM)hWndSender);
  260. // Notify of selection made.
  261. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(nControlID,
  262. CPN_XT_SELENDOK), (LPARAM)hWndSender);
  263. }
  264. return 0;
  265. }
  266. LRESULT CXTColorPicker::OnSelEndCancel(WPARAM /*wParam*/, LPARAM /*lParam*/)
  267. {
  268. CWnd* pOwner = GetOwner();
  269. ASSERT_VALID(pOwner);
  270. if (pOwner != NULL)
  271. {
  272. // Notify of popup close up.
  273. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  274. CPN_XT_CLOSEUP), (LPARAM)m_hWnd);
  275. // Notify of cancel.
  276. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  277. CPN_XT_SELENDCANCEL), (LPARAM)m_hWnd);
  278. }
  279. return 0;
  280. }
  281. LRESULT CXTColorPicker::OnSelNoFill(WPARAM wParam, LPARAM /*lParam*/)
  282. {
  283. CWnd* pOwner = GetOwner();
  284. ASSERT_VALID(pOwner);
  285. if (pOwner != NULL)
  286. {
  287. SetColor((COLORREF)wParam);
  288. // Notify of no fill press.
  289. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  290. CPN_XT_SELNOFILL), (LPARAM)m_hWnd);
  291. }
  292. return 0;
  293. }
  294. bool CXTColorPicker::Init()
  295. {
  296. if (!CXTButton::Init())
  297. return false;
  298. // Set the font.
  299. SetFont(&XTAuxData().font);
  300. return true;
  301. }
  302. void CXTColorPicker::SetColor(COLORREF clr)
  303. {
  304. if (clr != GetColor())
  305. {
  306. m_clrSelected = clr;
  307. RedrawWindow();
  308. }
  309. }
  310. COLORREF CXTColorPicker::GetContrastColor() const
  311. {
  312. double Intensity = CXTColorRef(GetColor()).getIntensity();
  313. return Intensity > 128 ? CXTColorRef::BLACK : CXTColorRef::WHITE;
  314. }
  315. void CXTColorPicker::ShowPopupWindow()
  316. {
  317. m_bPopupActive = TRUE;
  318. // Make sure that we have input focus.
  319. if (GetFocus() != this)
  320. {
  321. SetFocus();
  322. }
  323. // Post a message instead of displaying right away - this will take care
  324. // of asynchronous focusing issues
  325. PostMessage(WM_XT_SHOWPOPUP);
  326. }
  327. void CXTColorPicker::OnShowPopup()
  328. {
  329. // Get the size of the picker button.
  330. CRect rcWindow;
  331. GetWindowRect(&rcWindow);
  332. // Create the color popup window.
  333. CXTColorPopup *pColorPopup = new CXTColorPopup(TRUE);
  334. if (m_pExtendedColors)
  335. {
  336. pColorPopup->SetColors(m_pExtendedColors, m_nExtendedColors, m_nCols);
  337. }
  338. pColorPopup->Create(rcWindow, this, m_dwPopup, GetColor(), GetDefaultColor());
  339. pColorPopup->SetFocus();
  340. }
  341. BOOL CXTColorPicker::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  342. {
  343. if (!m_bPopupActive)
  344. {
  345. if (message == WM_LBUTTONDOWN)
  346. {
  347. ShowPopupWindow();
  348. // in this case the message is not "swallowed" so the button will
  349. // get it and display itself in a recessed state
  350. }
  351. else if (message == WM_KEYDOWN &&
  352. (wParam == VK_RETURN ||
  353. wParam == VK_SPACE ||
  354. wParam == VK_DOWN))
  355. {
  356. ShowPopupWindow();
  357. return TRUE;  // swallow message
  358. }
  359. }
  360. return CXTButton::OnWndMsg(message, wParam, lParam, pResult);
  361. }