CJColorPicker.cpp
上传用户:xmgzsj
上传日期:2007-01-01
资源大小:46k
文件大小:11k
源码类别:

组合框控件

开发平台:

Visual C++

  1. // CJColorPicker.cpp : implementation file
  2. //
  3. // CJColorPicker is a drop-in Color 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 "CJColorPopup.h"
  33. #include "CJColorPicker.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_CJColorPicker(CDataExchange *pDX, int nIDC, COLORREF& crColor)
  40. {
  41.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  42.     ASSERT (hWndCtrl != NULL);                
  43.     
  44.     CCJColorPicker* pColorPicker = (CCJColorPicker*) CWnd::FromHandle(hWndCtrl);
  45.     if (pDX->m_bSaveAndValidate)
  46.     {
  47.         crColor = pColorPicker->GetColor();
  48.     }
  49.     else // initializing
  50.     {
  51.         pColorPicker->SetColor(crColor);
  52.     }
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CCJColorPicker
  56. CCJColorPicker::CCJColorPicker()
  57. {
  58.     SetBkColor(GetSysColor(COLOR_3DFACE));
  59.     SetTextColor(GetSysColor(COLOR_BTNTEXT));
  60.     m_bTrackSelection = FALSE;
  61.     m_nSelectionMode = CP_MODE_BK;
  62.     m_bActive = FALSE;
  63. ////////////////////////////////////////
  64. // 1999-06-11 begin mods Kirk Stowell
  65. ////////////////////////////////////////
  66. m_strDefaultText = "Automatic";
  67. m_strCustomText  = "Custmize...";
  68. ////////////////////////////////////////
  69. // 1999-06-11 end mods Kirk Stowell
  70. ////////////////////////////////////////
  71. }
  72. CCJColorPicker::~CCJColorPicker()
  73. {
  74. }
  75. IMPLEMENT_DYNCREATE(CCJColorPicker, CButton)
  76. BEGIN_MESSAGE_MAP(CCJColorPicker, CButton)
  77.     //{{AFX_MSG_MAP(CCJColorPicker)
  78.     ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
  79.     ON_WM_CREATE()
  80. //}}AFX_MSG_MAP
  81.     ON_MESSAGE(CPN_SELENDOK,     OnSelEndOK)
  82.     ON_MESSAGE(CPN_SELENDCANCEL, OnSelEndCancel)
  83.     ON_MESSAGE(CPN_SELCHANGE,    OnSelChange)
  84. END_MESSAGE_MAP()
  85. /////////////////////////////////////////////////////////////////////////////
  86. // CCJColorPicker message handlers
  87. LONG CCJColorPicker::OnSelEndOK(UINT lParam, LONG /*wParam*/)
  88. {
  89.     COLORREF crNewColor = (COLORREF) lParam;
  90.     m_bActive = FALSE;
  91.     SetColor(crNewColor);
  92.     CWnd *pParent = GetParent();
  93.     if (pParent) {
  94.         pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID());
  95.         pParent->SendMessage(CPN_SELENDOK, lParam, (WPARAM) GetDlgCtrlID());
  96.     }
  97.     if (crNewColor != GetColor())
  98.         if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
  99.     return TRUE;
  100. }
  101. LONG CCJColorPicker::OnSelEndCancel(UINT lParam, LONG /*wParam*/)
  102. {
  103.     m_bActive = FALSE;
  104.     SetColor((COLORREF) lParam);
  105.     CWnd *pParent = GetParent();
  106.     if (pParent) {
  107.         pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID());
  108.         pParent->SendMessage(CPN_SELENDCANCEL, lParam, (WPARAM) GetDlgCtrlID());
  109.     }
  110.     return TRUE;
  111. }
  112. LONG CCJColorPicker::OnSelChange(UINT lParam, LONG /*wParam*/)
  113. {
  114.     if (m_bTrackSelection) SetColor((COLORREF) lParam);
  115.     CWnd *pParent = GetParent();
  116.     if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
  117.     return TRUE;
  118. }
  119. int CCJColorPicker::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  120. {
  121.     if (CButton::OnCreate(lpCreateStruct) == -1)
  122.         return -1;
  123.     
  124.     SetWindowSize();    // resize appropriately
  125.     return 0;
  126. }
  127. // On mouse click, create and show a CJColorPopup window for Color selection
  128. BOOL CCJColorPicker::OnClicked()
  129. {
  130.     m_bActive = TRUE;
  131.     CRect rect;
  132.     GetWindowRect(rect);
  133.     new CCJColorPopup(CPoint(rect.left, rect.bottom),    // Point to display popup
  134.                      GetColor(),                       // Selected Color
  135.                      this,                              // parent
  136.                      m_strDefaultText,                  // "Default" text area
  137.                      m_strCustomText);                  // Custom Text
  138.     CWnd *pParent = GetParent();
  139.     if (pParent)
  140.         pParent->SendMessage(CPN_DROPDOWN, (LPARAM)GetColor(), (WPARAM) GetDlgCtrlID());
  141.     // Docs say I should return FALSE to stop the parent also getting the message.
  142.     // HA! What a joke.
  143.     return TRUE;
  144. }
  145. ////////////////////////////////////////
  146. // 1999-06-11 begin mods Kirk Stowell
  147. ////////////////////////////////////////
  148. void CCJColorPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
  149. {
  150. CDC* pDC = CDC::FromHandle( lpDrawItemStruct->hDC );
  151.     UINT itemState = lpDrawItemStruct->itemState;
  152. CRect rcItem = lpDrawItemStruct->rcItem;
  153. DWORD dwState = EDGE_RAISED;
  154. DWORD dwArrow = DFCS_SCROLLDOWN;
  155. // erase everything....
  156. pDC->FillRect( rcItem, CBrush::FromHandle(::GetSysColorBrush( COLOR_3DFACE )));
  157. // set display flags based on state.
  158. if((itemState & ODS_SELECTED) || (m_bActive == TRUE)) {
  159. dwState = EDGE_SUNKEN;
  160. dwArrow = DFCS_SCROLLDOWN|DFCS_PUSHED;
  161. }
  162. if(itemState & ODS_DISABLED) {
  163. dwArrow = DFCS_SCROLLDOWN|DFCS_INACTIVE;
  164. }
  165. // Draw the drop arrow.
  166. CRect rcArrow( rcItem );
  167. rcArrow.left = rcArrow.Width()-::GetSystemMetrics( SM_CXHTHUMB );
  168.     pDC->DrawFrameControl( &rcArrow, DFC_SCROLL, dwArrow );
  169. pDC->Draw3dRect( rcArrow, ::GetSysColor( COLOR_3DFACE ), ::GetSysColor( COLOR_3DFACE ));
  170. rcArrow.DeflateRect( 1,1 );
  171. pDC->Draw3dRect( rcArrow, ::GetSysColor( COLOR_3DFACE ), ::GetSysColor( COLOR_3DFACE ));
  172. if((itemState & ODS_SELECTED) || (m_bActive == TRUE))
  173. rcArrow.OffsetRect( 1,1 );
  174. // draw the seperator line.
  175. CPen penShadow( PS_SOLID, 1, ::GetSysColor( COLOR_3DSHADOW  ));
  176. pDC->SelectObject( &penShadow );
  177. pDC->MoveTo( rcArrow.left-1, rcArrow.top+2 );
  178. pDC->LineTo( rcArrow.left-1, rcArrow.bottom-2 );
  179. CPen penHilite( PS_SOLID, 1, ::GetSysColor( COLOR_3DHILIGHT ));
  180. pDC->SelectObject( &penHilite );
  181. pDC->MoveTo( rcArrow.left, rcArrow.top+2 );
  182. pDC->LineTo( rcArrow.left, rcArrow.bottom-2 );
  183. // draw the control border.
  184.     pDC->DrawEdge( rcItem, dwState, BF_RECT );
  185. // draw the focus rect.
  186. rcItem.DeflateRect( 2, 2 );
  187. pDC->Draw3dRect( rcItem, ::GetSysColor( COLOR_3DFACE ), ::GetSysColor( COLOR_3DFACE ) );
  188. if( itemState & ODS_FOCUS ) {
  189. pDC->DrawFocusRect( rcItem );
  190. }
  191. // draw the color box.
  192. if((itemState & ODS_SELECTED) || (m_bActive == TRUE))
  193. rcItem.OffsetRect( 1,1 );
  194. rcItem.DeflateRect( 2, 2 );
  195. rcItem.right = rcArrow.left-4;
  196.     CBrush brush((( itemState & ODS_DISABLED ) || m_crColorBk == CLR_DEFAULT ) ? 
  197. ::GetSysColor( COLOR_3DFACE ) : m_crColorBk );
  198.     CBrush* pOldBrush = ( CBrush* )pDC->SelectObject( &brush );
  199. pDC->SelectStockObject(( itemState & ODS_DISABLED )?WHITE_PEN:BLACK_PEN );
  200. pDC->Rectangle( rcItem );
  201.     pDC->SelectObject( pOldBrush );
  202.     // Draw the window text (if any)
  203. CString strText;
  204.     GetWindowText(strText);
  205.     if (strText.GetLength())
  206.     {
  207.         pDC->SetBkMode(TRANSPARENT);
  208.         if (itemState & ODS_DISABLED)
  209.         {
  210.             rcItem.OffsetRect(1,1);
  211.             pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
  212.             pDC->DrawText(strText, rcItem, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  213.             rcItem.OffsetRect(-1,-1);
  214.             pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
  215.             pDC->DrawText(strText, rcItem, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  216.         }
  217.         else
  218.         {
  219.             pDC->SetTextColor((m_crColorText == CLR_DEFAULT)? 0 : m_crColorText);
  220.             pDC->DrawText(strText, rcItem, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  221.         }
  222.     }
  223. }
  224. ////////////////////////////////////////
  225. // 1999-06-11 end mods Kirk Stowell
  226. ////////////////////////////////////////
  227. /////////////////////////////////////////////////////////////////////////////
  228. // CCJColorPicker overrides
  229. void CCJColorPicker::PreSubclassWindow() 
  230. {
  231.     ModifyStyle(0, BS_OWNERDRAW);        // Make it owner drawn
  232.     CButton::PreSubclassWindow();
  233.     SetWindowSize();                     // resize appropriately
  234. }
  235. /////////////////////////////////////////////////////////////////////////////
  236. // CCJColorPicker attributes
  237. COLORREF CCJColorPicker::GetColor()
  238.     return (m_nSelectionMode == CP_MODE_TEXT)? 
  239.         GetTextColor(): GetBkColor(); 
  240. }
  241. void CCJColorPicker::SetColor(COLORREF crColor)
  242.     (m_nSelectionMode == CP_MODE_TEXT)? 
  243.         SetTextColor(crColor): SetBkColor(crColor); 
  244. }
  245. void CCJColorPicker::SetBkColor(COLORREF crColorBk)
  246. {
  247.     m_crColorBk = crColorBk;
  248.     if (IsWindow(m_hWnd)) RedrawWindow();
  249. }
  250. void CCJColorPicker::SetTextColor(COLORREF crColorText)
  251. {
  252.     m_crColorText = crColorText;
  253.     if (IsWindow(m_hWnd)) RedrawWindow();
  254. }
  255. void CCJColorPicker::SetDefaultText(LPCTSTR szDefaultText)
  256. {
  257.     m_strDefaultText = (szDefaultText)? szDefaultText : _T("");
  258. }
  259. void CCJColorPicker::SetCustomText(LPCTSTR szCustomText)
  260. {
  261.     m_strCustomText = (szCustomText)? szCustomText : _T("");
  262. }
  263. /////////////////////////////////////////////////////////////////////////////
  264. // CCJColorPicker implementation
  265. void CCJColorPicker::SetWindowSize()
  266. {
  267.     // Get size dimensions of edges
  268.     CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  269.     // Get size of dropdown arrow
  270.     int nArrowWidth = max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx);
  271.     int nArrowHeight = max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy);
  272.     CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight));
  273.     // Get window size
  274.     CRect rect;
  275.     GetWindowRect(rect);
  276.     CWnd* pParent = GetParent();
  277.     if (pParent)
  278.         pParent->ScreenToClient(rect);
  279.     // Set window size at least as wide as 2 arrows, and as high as arrow + margins
  280.     int nWidth = max(rect.Width(), 2*ArrowSize.cx + 2*MarginSize.cx);
  281.     MoveWindow(rect.left, rect.top, nWidth, ArrowSize.cy+2*MarginSize.cy, TRUE);
  282.     // Get the new coords of this window
  283.     GetWindowRect(rect);
  284.     ScreenToClient(rect);
  285.     // Get the rect where the arrow goes, and convert to client coords.
  286.     m_ArrowRect.SetRect(rect.right - ArrowSize.cx - MarginSize.cx, 
  287.                         rect.top + MarginSize.cy, rect.right - MarginSize.cx,
  288.                         rect.bottom - MarginSize.cy);
  289. }