ColourPicker.cpp
上传用户:cqzhuye
上传日期:2007-01-01
资源大小:72k
文件大小: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. void AFXAPI DDX_ColourPicker(CDataExchange *pDX, int nIDC, COLORREF& crColour)
  39. {
  40.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  41.     ASSERT (hWndCtrl != NULL);                
  42.     
  43.     CColourPicker* pColourPicker = (CColourPicker*) CWnd::FromHandle(hWndCtrl);
  44.     if (pDX->m_bSaveAndValidate)
  45.     {
  46.         crColour = pColourPicker->GetColour();
  47.     }
  48.     else // initializing
  49.     {
  50.         pColourPicker->SetColour(crColour);
  51.     }
  52. }
  53. /////////////////////////////////////////////////////////////////////////////
  54. // CColourPicker
  55. CColourPicker::CColourPicker()
  56. {
  57.     SetBkColour(GetSysColor(COLOR_3DFACE));
  58.     SetTextColour(GetSysColor(COLOR_BTNTEXT));
  59.     m_bTrackSelection = FALSE;
  60.     m_nSelectionMode = CP_MODE_BK;
  61.     m_bActive = FALSE;
  62. }
  63. CColourPicker::~CColourPicker()
  64. {
  65. }
  66. IMPLEMENT_DYNCREATE(CColourPicker, CButton)
  67. BEGIN_MESSAGE_MAP(CColourPicker, CButton)
  68.     //{{AFX_MSG_MAP(CColourPicker)
  69.     ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
  70.     ON_WM_CREATE()
  71.     //}}AFX_MSG_MAP
  72.     ON_MESSAGE(CPN_SELENDOK,     OnSelEndOK)
  73.     ON_MESSAGE(CPN_SELENDCANCEL, OnSelEndCancel)
  74.     ON_MESSAGE(CPN_SELCHANGE,    OnSelChange)
  75. END_MESSAGE_MAP()
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CColourPicker message handlers
  78. LONG CColourPicker::OnSelEndOK(UINT lParam, LONG wParam)
  79. {
  80.     COLORREF crNewColour = (COLORREF) lParam;
  81.     m_bActive = FALSE;
  82.     SetColour(crNewColour);
  83.     CWnd *pParent = GetParent();
  84.     if (pParent) {
  85.         pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID());
  86.         pParent->SendMessage(CPN_SELENDOK, lParam, (WPARAM) GetDlgCtrlID());
  87.     }
  88.     if (crNewColour != GetColour())
  89.         if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
  90.     return TRUE;
  91. }
  92. LONG CColourPicker::OnSelEndCancel(UINT lParam, LONG wParam)
  93. {
  94.     m_bActive = FALSE;
  95.     SetColour((COLORREF) lParam);
  96.     CWnd *pParent = GetParent();
  97.     if (pParent) {
  98.         pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID());
  99.         pParent->SendMessage(CPN_SELENDCANCEL, lParam, (WPARAM) GetDlgCtrlID());
  100.     }
  101.     return TRUE;
  102. }
  103. LONG CColourPicker::OnSelChange(UINT lParam, LONG wParam)
  104. {
  105.     if (m_bTrackSelection) SetColour((COLORREF) lParam);
  106.     CWnd *pParent = GetParent();
  107.     if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
  108.     return TRUE;
  109. }
  110. int CColourPicker::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  111. {
  112.     if (CButton::OnCreate(lpCreateStruct) == -1)
  113.         return -1;
  114.     
  115.     SetWindowSize();    // resize appropriately
  116.     return 0;
  117. }
  118. // On mouse click, create and show a CColourPopup window for colour selection
  119. BOOL CColourPicker::OnClicked()
  120. {
  121.     m_bActive = TRUE;
  122.     CRect rect;
  123.     GetWindowRect(rect);
  124.     new CColourPopup(CPoint(rect.left, rect.bottom), GetColour(), this, 10, 
  125.                      _T("More..."));
  126.     CWnd *pParent = GetParent();
  127.     if (pParent)
  128.         pParent->SendMessage(CPN_DROPDOWN, (LPARAM)GetColour(), (WPARAM) GetDlgCtrlID());
  129.     // Docs say I should return FALSE to stop the parent also getting the message.
  130.     // HA! What a joke.
  131.     return TRUE;
  132. }
  133. void CColourPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
  134. {
  135.     ASSERT(lpDrawItemStruct);
  136.     
  137.     CDC*    pDC     = CDC::FromHandle(lpDrawItemStruct->hDC);
  138.     CRect   rect    = lpDrawItemStruct->rcItem;
  139.     UINT    state   = lpDrawItemStruct->itemState;
  140.     DWORD   dwStyle = GetStyle();
  141.     CString m_strText;
  142.     CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  143.     // Draw arrow
  144.     if (m_bActive) state |= ODS_SELECTED;
  145.     pDC->DrawFrameControl(&m_ArrowRect, DFC_SCROLL, DFCS_SCROLLDOWN  | 
  146.                           ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) |
  147.                           ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0));
  148.     pDC->DrawEdge(rect, EDGE_SUNKEN, BF_RECT);
  149.     // Must reduce the size of the "client" area of the button due to edge thickness.
  150.     rect.DeflateRect(Margins.cx, Margins.cy);
  151.     // Fill remaining area with colour
  152.     rect.right -= m_ArrowRect.Width();
  153.     CBrush brush((state & ODS_DISABLED)? ::GetSysColor(COLOR_3DFACE) : m_crColourBk);
  154.     CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
  155. pDC->SelectStockObject(NULL_PEN);
  156.     pDC->Rectangle(rect);
  157.     pDC->SelectObject(pOldBrush);
  158.     // Draw the window text (if any)
  159.     GetWindowText(m_strText);
  160.     if (m_strText.GetLength())
  161.     {
  162.         pDC->SetBkMode(TRANSPARENT);
  163.         if (state & ODS_DISABLED)
  164.         {
  165.             rect.OffsetRect(1,1);
  166.             pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
  167.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  168.             rect.OffsetRect(-1,-1);
  169.             pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
  170.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  171.         }
  172.         else
  173.         {
  174.             pDC->SetTextColor(m_crColourText);
  175.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  176.         }
  177.     }
  178.     // Draw focus rect
  179.     if (state & ODS_FOCUS) 
  180.     {
  181.         rect.DeflateRect(1,1);
  182.         pDC->DrawFocusRect(rect);
  183.     }
  184. }
  185. /////////////////////////////////////////////////////////////////////////////
  186. // CColourPicker overrides
  187. void CColourPicker::PreSubclassWindow() 
  188. {
  189.     ModifyStyle(0, BS_OWNERDRAW);        // Make it owner drawn
  190.     CButton::PreSubclassWindow();
  191.     SetWindowSize();                     // resize appropriately
  192. }
  193. /////////////////////////////////////////////////////////////////////////////
  194. // CColourPicker attributes
  195. void CColourPicker::SetBkColour(COLORREF crColourBk)
  196. {
  197.     m_crColourBk = crColourBk;
  198.     if (IsWindow(m_hWnd)) RedrawWindow();
  199. }
  200. void CColourPicker::SetTextColour(COLORREF crColourText)
  201. {
  202.     m_crColourText = crColourText;
  203.     if (IsWindow(m_hWnd)) RedrawWindow();
  204. }
  205. /////////////////////////////////////////////////////////////////////////////
  206. // CColourPicker implementation
  207. void CColourPicker::SetWindowSize()
  208. {
  209.     // Get size dimensions of edges
  210.     CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  211.     // Get size of dropdown arrow
  212.     int nArrowWidth = max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx);
  213.     int nArrowHeight = max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy);
  214.     CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight));
  215.     //ArrowSize = CSize(40,40); // for testing
  216.     // Get window size
  217.     CRect rect;
  218.     GetWindowRect(rect);
  219.     CWnd* pParent = GetParent();
  220.     if (pParent)
  221.         pParent->ScreenToClient(rect);
  222.     // Set window size at least as wide as 2 arrows, and as high as arrow + margins
  223.     int nWidth = max(rect.Width(), 2*ArrowSize.cx + 2*MarginSize.cx);
  224.     MoveWindow(rect.left, rect.top, nWidth, ArrowSize.cy+2*MarginSize.cy, TRUE);
  225.     // Get the new coords of this window
  226.     GetWindowRect(rect);
  227.     ScreenToClient(rect);
  228.     // Get the rect where the arrow goes, and convert to client coords.
  229.     m_ArrowRect.SetRect(rect.right - ArrowSize.cx - MarginSize.cx, 
  230.                         rect.top + MarginSize.cy, rect.right - MarginSize.cx,
  231.                         rect.bottom - MarginSize.cy);
  232. }