ColourPicker.cpp
上传用户:zhoushen
上传日期:2022-06-15
资源大小:84k
文件大小:10k
源码类别:

对话框与窗口

开发平台:

Visual C++

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