ColourPicker.cpp
上传用户:yangzi5763
上传日期:2007-01-02
资源大小:239k
文件大小:10k
源码类别:

ActiveX/DCOM/ATL

开发平台:

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. #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.     m_strDefaultText = _T("Automatic");
  63.     m_strCustomText  = _T("More Colours...");
  64. m_pWndColor = NULL;
  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.     m_pWndColor = 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.     DWORD   dwStyle = GetStyle();
  147.     CString m_strText;
  148.     CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  149.     // Draw arrow
  150.     if (m_bActive) state |= ODS_SELECTED;
  151.     pDC->DrawFrameControl(&m_ArrowRect, DFC_SCROLL, DFCS_SCROLLDOWN  | 
  152.                           ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) |
  153.                           ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0));
  154.     pDC->DrawEdge(rect, EDGE_SUNKEN, BF_RECT);
  155.     // Must reduce the size of the "client" area of the button due to edge thickness.
  156.     rect.DeflateRect(Margins.cx, Margins.cy);
  157.     // Fill remaining area with colour
  158.     rect.right -= m_ArrowRect.Width();
  159.     CBrush brush( ((state & ODS_DISABLED) || m_crColourBk == CLR_DEFAULT)? 
  160.                   ::GetSysColor(COLOR_3DFACE) : m_crColourBk);
  161.     CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
  162. pDC->SelectStockObject(NULL_PEN);
  163.     pDC->Rectangle(rect);
  164.     pDC->SelectObject(pOldBrush);
  165.     // Draw the window text (if any)
  166.     GetWindowText(m_strText);
  167.     if (m_strText.GetLength())
  168.     {
  169.         pDC->SetBkMode(TRANSPARENT);
  170.         if (state & ODS_DISABLED)
  171.         {
  172.             rect.OffsetRect(1,1);
  173.             pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
  174.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  175.             rect.OffsetRect(-1,-1);
  176.             pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
  177.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  178.         }
  179.         else
  180.         {
  181.             pDC->SetTextColor((m_crColourText == CLR_DEFAULT)? 0 : m_crColourText);
  182.             pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  183.         }
  184.     }
  185.     // Draw focus rect
  186.     if (state & ODS_FOCUS) 
  187.     {
  188.         rect.DeflateRect(1,1);
  189.         pDC->DrawFocusRect(rect);
  190.     }
  191. }
  192. /////////////////////////////////////////////////////////////////////////////
  193. // CColourPicker overrides
  194. void CColourPicker::PreSubclassWindow() 
  195. {
  196.     ModifyStyle(0, BS_OWNERDRAW);        // Make it owner drawn
  197.     CButton::PreSubclassWindow();
  198.     SetWindowSize();                     // resize appropriately
  199. }
  200. /////////////////////////////////////////////////////////////////////////////
  201. // CColourPicker attributes
  202. COLORREF CColourPicker::GetColour()
  203.     return (m_nSelectionMode == CP_MODE_TEXT)? 
  204.         GetTextColour(): GetBkColour(); 
  205. }
  206. void CColourPicker::SetColour(COLORREF crColour)
  207.     (m_nSelectionMode == CP_MODE_TEXT)? 
  208.         SetTextColour(crColour): SetBkColour(crColour); 
  209. }
  210. void CColourPicker::SetBkColour(COLORREF crColourBk)
  211. {
  212.     m_crColourBk = crColourBk;
  213.     if (IsWindow(m_hWnd)) RedrawWindow();
  214. }
  215. void CColourPicker::SetTextColour(COLORREF crColourText)
  216. {
  217.     m_crColourText = crColourText;
  218.     if (IsWindow(m_hWnd)) RedrawWindow();
  219. }
  220. void CColourPicker::SetDefaultText(LPCTSTR szDefaultText)
  221. {
  222.     m_strDefaultText = (szDefaultText)? szDefaultText : _T("");
  223. }
  224. void CColourPicker::SetCustomText(LPCTSTR szCustomText)
  225. {
  226.     m_strCustomText = (szCustomText)? szCustomText : _T("");
  227. }
  228. /////////////////////////////////////////////////////////////////////////////
  229. // CColourPicker implementation
  230. void CColourPicker::SetWindowSize()
  231. {
  232.     // Get size dimensions of edges
  233.     CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  234.     // Get size of dropdown arrow
  235.     int nArrowWidth = max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx);
  236.     int nArrowHeight = max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy);
  237.     CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight));
  238.     // Get window size
  239.     CRect rect;
  240.     GetWindowRect(rect);
  241.     CWnd* pParent = GetParent();
  242.     if (pParent)
  243.         pParent->ScreenToClient(rect);
  244.     // Set window size at least as wide as 2 arrows, and as high as arrow + margins
  245.     int nWidth = max(rect.Width(), 2*ArrowSize.cx + 2*MarginSize.cx);
  246.     MoveWindow(rect.left, rect.top, nWidth, ArrowSize.cy+2*MarginSize.cy, TRUE);
  247.     // Get the new coords of this window
  248.     GetWindowRect(rect);
  249.     ScreenToClient(rect);
  250.     // Get the rect where the arrow goes, and convert to client coords.
  251.     m_ArrowRect.SetRect(rect.right - ArrowSize.cx - MarginSize.cx, 
  252.                         rect.top + MarginSize.cy, rect.right - MarginSize.cx,
  253.                         rect.bottom - MarginSize.cy);
  254. }