ColourPicker.cpp
上传用户:wujian85
上传日期:2010-04-08
资源大小:227k
文件大小:9k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // ColourPicker.cpp : implementation file
  2. //
  3. //
  4. // ColourPicker is a drop-in colour picker control. Check out the 
  5. // header file or the accompanying HTML doc file for details.
  6. //
  7. // Written by Chris Maunder (Chris.Maunder@cbr.clw.csiro.au)
  8. // Extended by Alexander Bischofberger (bischofb@informatik.tu-muenchen.de)
  9. // Copyright (c) 1998.
  10. //
  11. // This code may be used in compiled form in any way you desire. This
  12. // file may be redistributed unmodified by any means PROVIDING it is 
  13. // not sold for profit without the authors written consent, and 
  14. // providing that this notice and the authors name is included. If 
  15. // the source code in  this file is used in any commercial application 
  16. // then a simple email would be nice.
  17. //
  18. // This file is provided "as is" with no expressed or implied warranty.
  19. // The author accepts no liability if it causes any damage to your
  20. // computer, causes your pet cat to fall ill, increases baldness or
  21. // makes you car start emitting strange noises when you start it up.
  22. //
  23. // Expect bugs.
  24. // 
  25. // Please use and enjoy. Please let me know of any bugs/mods/improvements 
  26. // that you have found/implemented and I will fix/incorporate them into this
  27. // file. 
  28. //
  29. // Updated 16 May 1998
  30. #include "stdafx.h"
  31. #include "ColourPopup.h"
  32. #include "ColourPicker.h"
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. extern bool bLockingProperty;
  39. void AFXAPI DDX_ColourPicker(CDataExchange *pDX, int nIDC, COLORREF& crColour)
  40. {
  41.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  42.     ASSERT (hWndCtrl != NULL);                
  43.     
  44.     CColourPicker* pColourPicker = (CColourPicker*) CWnd::FromHandle(hWndCtrl);
  45.     if (pDX->m_bSaveAndValidate)
  46.     {
  47.         crColour = pColourPicker->GetColour();
  48.     }
  49.     else // initializing
  50.     {
  51.         pColourPicker->SetColour(crColour);
  52.     }
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CColourPicker
  56. CColourPicker::CColourPicker()
  57. {
  58.     SetBkColour(GetSysColor(COLOR_3DFACE));
  59.     SetTextColour(GetSysColor(COLOR_BTNTEXT));
  60.     m_bTrackSelection = FALSE;
  61.     m_nSelectionMode = CP_MODE_BK;
  62.     m_bActive = FALSE;
  63. }
  64. CColourPicker::~CColourPicker()
  65. {
  66. }
  67. IMPLEMENT_DYNCREATE(CColourPicker, CButton)
  68. BEGIN_MESSAGE_MAP(CColourPicker, CButton)
  69.     //{{AFX_MSG_MAP(CColourPicker)
  70.     ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
  71.     ON_WM_CREATE()
  72.     //}}AFX_MSG_MAP
  73.     ON_MESSAGE(CPN_SELENDOK,     OnSelEndOK)
  74.     ON_MESSAGE(CPN_SELENDCANCEL, OnSelEndCancel)
  75.     ON_MESSAGE(CPN_SELCHANGE,    OnSelChange)
  76. END_MESSAGE_MAP()
  77. /////////////////////////////////////////////////////////////////////////////
  78. // CColourPicker message handlers
  79. LONG CColourPicker::OnSelEndOK(UINT lParam, LONG wParam)
  80. {
  81.     COLORREF crNewColour = (COLORREF) lParam;
  82.     m_bActive = FALSE;
  83.     SetColour(crNewColour);
  84.     CWnd *pParent = GetParent();
  85.     if (pParent) {
  86.         pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID());
  87.         pParent->SendMessage(CPN_SELENDOK, lParam, (WPARAM) GetDlgCtrlID());
  88.     }
  89.     if (crNewColour != GetColour())
  90.         if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
  91.     return TRUE;
  92. }
  93. LONG CColourPicker::OnSelEndCancel(UINT lParam, LONG wParam)
  94. {
  95.     m_bActive = FALSE;
  96.     SetColour((COLORREF) lParam);
  97.     CWnd *pParent = GetParent();
  98.     if (pParent) {
  99.         pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID());
  100.         pParent->SendMessage(CPN_SELENDCANCEL, lParam, (WPARAM) GetDlgCtrlID());
  101.     }
  102.     return TRUE;
  103. }
  104. LONG CColourPicker::OnSelChange(UINT lParam, LONG wParam)
  105. {
  106.     if (m_bTrackSelection) SetColour((COLORREF) lParam);
  107.     CWnd *pParent = GetParent();
  108.     if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
  109.     return TRUE;
  110. }
  111. int CColourPicker::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  112. {
  113.     if (CButton::OnCreate(lpCreateStruct) == -1)
  114.         return -1;
  115.     
  116.     SetWindowSize();    // resize appropriately
  117.     return 0;
  118. }
  119. // On mouse click, create and show a CColourPopup window for colour selection
  120. BOOL CColourPicker::OnClicked()
  121. {
  122. bLockingProperty = true;
  123.     m_bActive = TRUE;
  124.     CRect rect;
  125.     GetWindowRect(rect);
  126.     new CColourPopup(CPoint(rect.left, rect.bottom), GetColour(), this, 10, 
  127.                      _T("More..."));
  128.     CWnd *pParent = GetParent();
  129.     if (pParent)
  130.         pParent->SendMessage(CPN_DROPDOWN, (LPARAM)GetColour(), (WPARAM) GetDlgCtrlID());
  131.     // Docs say I should return FALSE to stop the parent also getting the message.
  132.     // HA! What a joke.
  133.     return TRUE;
  134. }
  135. void CColourPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
  136. {
  137.     ASSERT(lpDrawItemStruct);
  138.     
  139.     CDC*    pDC     = CDC::FromHandle(lpDrawItemStruct->hDC);
  140.     CRect   rect    = lpDrawItemStruct->rcItem;
  141.     UINT    state   = lpDrawItemStruct->itemState;
  142.     DWORD   dwStyle = GetStyle();
  143.     CString m_strText;
  144.     CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  145.     // Draw arrow
  146.     if (m_bActive) state |= ODS_SELECTED;
  147.     pDC->DrawFrameControl(&m_ArrowRect, DFC_SCROLL, DFCS_SCROLLDOWN  | 
  148.                           ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) |
  149.                           ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0));
  150.     pDC->DrawEdge(rect, EDGE_SUNKEN, BF_RECT);
  151.     // Must reduce the size of the "client" area of the button due to edge thickness.
  152.     rect.DeflateRect(Margins.cx, Margins.cy);
  153.     // Fill remaining area with colour
  154.     rect.right -= m_ArrowRect.Width();
  155.     CBrush brush((state & ODS_DISABLED)? ::GetSysColor(COLOR_3DFACE) : m_crColourBk);
  156.     CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
  157. pDC->SelectStockObject(NULL_PEN);
  158.     pDC->Rectangle(rect);
  159.     pDC->SelectObject(pOldBrush);
  160.     // Draw the window text (if any)
  161.     GetWindowText(m_strText);
  162.     if (m_strText.GetLength())
  163.     {
  164.         pDC->SetBkMode(TRANSPARENT);
  165.         if (state & ODS_DISABLED)
  166.         {
  167.             rect.OffsetRect(1,1);
  168.             pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
  169.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  170.             rect.OffsetRect(-1,-1);
  171.             pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
  172.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  173.         }
  174.         else
  175.         {
  176.             pDC->SetTextColor(m_crColourText);
  177.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  178.         }
  179.     }
  180.     // Draw focus rect
  181.     if (state & ODS_FOCUS) 
  182.     {
  183.         rect.DeflateRect(1,1);
  184.         pDC->DrawFocusRect(rect);
  185.     }
  186. }
  187. /////////////////////////////////////////////////////////////////////////////
  188. // CColourPicker overrides
  189. void CColourPicker::PreSubclassWindow() 
  190. {
  191.     ModifyStyle(0, BS_OWNERDRAW);        // Make it owner drawn
  192.     CButton::PreSubclassWindow();
  193.     SetWindowSize();                     // resize appropriately
  194. }
  195. /////////////////////////////////////////////////////////////////////////////
  196. // CColourPicker attributes
  197. void CColourPicker::SetBkColour(COLORREF crColourBk)
  198. {
  199.     m_crColourBk = crColourBk;
  200.     if (IsWindow(m_hWnd)) RedrawWindow();
  201. }
  202. void CColourPicker::SetTextColour(COLORREF crColourText)
  203. {
  204.     m_crColourText = crColourText;
  205.     if (IsWindow(m_hWnd)) RedrawWindow();
  206. }
  207. /////////////////////////////////////////////////////////////////////////////
  208. // CColourPicker implementation
  209. void CColourPicker::SetWindowSize()
  210. {
  211.     // Get size dimensions of edges
  212.     CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  213.     // Get size of dropdown arrow
  214.     int nArrowWidth = max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx);
  215.     int nArrowHeight = max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy);
  216.     CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight));
  217.     //ArrowSize = CSize(40,40); // for testing
  218.     // Get window size
  219.     CRect rect;
  220.     GetWindowRect(rect);
  221.     CWnd* pParent = GetParent();
  222.     if (pParent)
  223.         pParent->ScreenToClient(rect);
  224.     // Set window size at least as wide as 2 arrows, and as high as arrow + margins
  225.     int nWidth = max(rect.Width(), 2*ArrowSize.cx + 2*MarginSize.cx);
  226.     MoveWindow(rect.left, rect.top, nWidth, ArrowSize.cy+2*MarginSize.cy, TRUE);
  227.     // Get the new coords of this window
  228.     GetWindowRect(rect);
  229.     ScreenToClient(rect);
  230.     // Get the rect where the arrow goes, and convert to client coords.
  231.     m_ArrowRect.SetRect(rect.right - ArrowSize.cx - MarginSize.cx, 
  232.                         rect.top + MarginSize.cy, rect.right - MarginSize.cx,
  233.                         rect.bottom - MarginSize.cy);
  234. }