GME
13
|
00001 // ColourPicker.cpp : implementation file 00002 // 00003 // ColourPicker is a drop-in colour picker control. Check out the 00004 // header file or the accompanying HTML doc file for details. 00005 // 00006 // Written by Chris Maunder (chrismaunder@codeguru.com) 00007 // Extended by Alexander Bischofberger (bischofb@informatik.tu-muenchen.de) 00008 // Copyright (c) 1998. 00009 // 00010 // This code may be used in compiled form in any way you desire. This 00011 // file may be redistributed unmodified by any means PROVIDING it is 00012 // not sold for profit without the authors written consent, and 00013 // providing that this notice and the authors name is included. If 00014 // the source code in this file is used in any commercial application 00015 // then a simple email would be nice. 00016 // 00017 // This file is provided "as is" with no expressed or implied warranty. 00018 // The author accepts no liability if it causes any damage to your 00019 // computer, causes your pet cat to fall ill, increases baldness or 00020 // makes you car start emitting strange noises when you start it up. 00021 // 00022 // Expect bugs. 00023 // 00024 // Please use and enjoy. Please let me know of any bugs/mods/improvements 00025 // that you have found/implemented and I will fix/incorporate them into this 00026 // file. 00027 // 00028 // Updated 16 May 1998 00029 // 31 May 1998 - added Default text (CJM) 00030 // 9 Jan 1999 - minor vis update 00031 00032 #include "stdafx.h" 00033 #include "ColourPopup.h" 00034 #include "ColourPicker.h" 00035 00036 #ifdef _DEBUG 00037 #define new DEBUG_NEW 00038 #undef THIS_FILE 00039 static char THIS_FILE[] = __FILE__; 00040 #endif 00041 00042 void AFXAPI DDX_ColourPicker(CDataExchange *pDX, int nIDC, COLORREF& crColour) 00043 { 00044 HWND hWndCtrl = pDX->PrepareCtrl(nIDC); 00045 ASSERT (hWndCtrl != NULL); 00046 00047 CColourPicker* pColourPicker = (CColourPicker*) CWnd::FromHandle(hWndCtrl); 00048 if (pDX->m_bSaveAndValidate) 00049 { 00050 crColour = pColourPicker->GetColour(); 00051 } 00052 else // initializing 00053 { 00054 pColourPicker->SetColour(crColour); 00055 } 00056 } 00057 00059 // CColourPicker 00060 00061 CColourPicker::CColourPicker() 00062 { 00063 SetBkColour(GetSysColor(COLOR_3DFACE)); 00064 SetTextColour(GetSysColor(COLOR_BTNTEXT)); 00065 00066 m_bTrackSelection = FALSE; 00067 m_nSelectionMode = CP_MODE_BK; 00068 m_bActive = FALSE; 00069 00070 m_strDefaultText = _T("Default"); 00071 m_strCustomText = _T("More Colors..."); 00072 } 00073 00074 CColourPicker::~CColourPicker() 00075 { 00076 } 00077 00078 IMPLEMENT_DYNCREATE(CColourPicker, CButton) 00079 00080 BEGIN_MESSAGE_MAP(CColourPicker, CButton) 00081 //{{AFX_MSG_MAP(CColourPicker) 00082 ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked) 00083 ON_WM_CREATE() 00084 //}}AFX_MSG_MAP 00085 ON_MESSAGE(CPN_SELENDOK, OnSelEndOK) 00086 ON_MESSAGE(CPN_SELENDCANCEL, OnSelEndCancel) 00087 ON_MESSAGE(CPN_SELCHANGE, OnSelChange) 00088 END_MESSAGE_MAP() 00089 00091 // CColourPicker message handlers 00092 00093 LONG CColourPicker::OnSelEndOK(UINT lParam, LONG /*wParam*/) 00094 { 00095 COLORREF crNewColour = (COLORREF) lParam; 00096 m_bActive = FALSE; 00097 SetColour(crNewColour); 00098 00099 CWnd *pParent = GetParent(); 00100 if (pParent) { 00101 pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID()); 00102 pParent->SendMessage(CPN_SELENDOK, lParam, (WPARAM) GetDlgCtrlID()); 00103 } 00104 00105 if (crNewColour != GetColour()) 00106 if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID()); 00107 00108 return TRUE; 00109 } 00110 00111 LONG CColourPicker::OnSelEndCancel(UINT lParam, LONG /*wParam*/) 00112 { 00113 m_bActive = FALSE; 00114 SetColour((COLORREF) lParam); 00115 00116 CWnd *pParent = GetParent(); 00117 if (pParent) { 00118 pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID()); 00119 pParent->SendMessage(CPN_SELENDCANCEL, lParam, (WPARAM) GetDlgCtrlID()); 00120 } 00121 00122 return TRUE; 00123 } 00124 00125 LONG CColourPicker::OnSelChange(UINT lParam, LONG /*wParam*/) 00126 { 00127 if (m_bTrackSelection) SetColour((COLORREF) lParam); 00128 00129 CWnd *pParent = GetParent(); 00130 if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID()); 00131 00132 return TRUE; 00133 } 00134 00135 int CColourPicker::OnCreate(LPCREATESTRUCT lpCreateStruct) 00136 { 00137 if (CButton::OnCreate(lpCreateStruct) == -1) 00138 return -1; 00139 00140 SetWindowSize(); // resize appropriately 00141 return 0; 00142 } 00143 00144 // On mouse click, create and show a CColourPopup window for colour selection 00145 BOOL CColourPicker::OnClicked() 00146 { 00147 m_bActive = TRUE; 00148 CRect rect; 00149 GetWindowRect(rect); 00150 new CColourPopup(CPoint(rect.left, rect.bottom), // Point to display popup 00151 GetColour(), // Selected colour 00152 this, // parent 00153 m_strDefaultText, // "Default" text area 00154 m_strCustomText); // Custom Text 00155 00156 CWnd *pParent = GetParent(); 00157 if (pParent) 00158 pParent->SendMessage(CPN_DROPDOWN, (LPARAM)GetColour(), (WPARAM) GetDlgCtrlID()); 00159 00160 // Docs say I should return FALSE to stop the parent also getting the message. 00161 // HA! What a joke. 00162 00163 return TRUE; 00164 } 00165 00166 void CColourPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 00167 { 00168 ASSERT(lpDrawItemStruct); 00169 00170 CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); 00171 CRect rect = lpDrawItemStruct->rcItem; 00172 UINT state = lpDrawItemStruct->itemState; 00173 CString m_strText; 00174 00175 CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE)); 00176 00177 // Draw arrow 00178 if (m_bActive) state |= ODS_SELECTED; 00179 pDC->DrawFrameControl(&m_ArrowRect, DFC_SCROLL, DFCS_SCROLLDOWN | 00180 ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) | 00181 ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0)); 00182 00183 // @T. L. pDC->DrawEdge(rect, EDGE_SUNKEN, BF_RECT); 00184 00185 // Must reduce the size of the "client" area of the button due to edge thickness. 00186 // rect.DeflateRect(Margins.cx, Margins.cy); 00187 00188 // Fill remaining area with colour 00189 rect.right -= m_ArrowRect.Width(); 00190 00191 CBrush brush( ((state & ODS_DISABLED) || m_crColourBk == CLR_DEFAULT)? 00192 ::GetSysColor(COLOR_3DFACE) : m_crColourBk); 00193 CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush); 00194 pDC->SelectStockObject(NULL_PEN); 00195 pDC->Rectangle(rect); 00196 pDC->SelectObject(pOldBrush); 00197 00198 // Draw the window text (if any) 00199 GetWindowText(m_strText); 00200 if (m_strText.GetLength()) 00201 { 00202 pDC->SetBkMode(TRANSPARENT); 00203 if (state & ODS_DISABLED) 00204 { 00205 rect.OffsetRect(1,1); 00206 pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT)); 00207 pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 00208 rect.OffsetRect(-1,-1); 00209 pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW)); 00210 pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 00211 } 00212 else 00213 { 00214 pDC->SetTextColor((m_crColourText == CLR_DEFAULT)? 0 : m_crColourText); 00215 pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 00216 } 00217 } 00218 00219 // Draw focus rect 00220 if (state & ODS_FOCUS) 00221 { 00222 rect.DeflateRect(1,1); 00223 pDC->DrawFocusRect(rect); 00224 } 00225 } 00226 00228 // CColourPicker overrides 00229 00230 void CColourPicker::PreSubclassWindow() 00231 { 00232 ModifyStyle(0, BS_OWNERDRAW); // Make it owner drawn 00233 CButton::PreSubclassWindow(); 00234 SetWindowSize(); // resize appropriately 00235 } 00236 00238 // CColourPicker attributes 00239 00240 COLORREF CColourPicker::GetColour() 00241 { 00242 return (m_nSelectionMode == CP_MODE_TEXT)? 00243 GetTextColour(): GetBkColour(); 00244 } 00245 00246 void CColourPicker::SetColour(COLORREF crColour) 00247 { 00248 (m_nSelectionMode == CP_MODE_TEXT)? 00249 SetTextColour(crColour): SetBkColour(crColour); 00250 } 00251 00252 void CColourPicker::SetBkColour(COLORREF crColourBk) 00253 { 00254 m_crColourBk = crColourBk; 00255 if (IsWindow(m_hWnd)) 00256 RedrawWindow(); 00257 } 00258 00259 void CColourPicker::SetTextColour(COLORREF crColourText) 00260 { 00261 m_crColourText = crColourText; 00262 if (IsWindow(m_hWnd)) 00263 RedrawWindow(); 00264 } 00265 00266 void CColourPicker::SetDefaultText(LPCTSTR szDefaultText) 00267 { 00268 m_strDefaultText = (szDefaultText)? szDefaultText : _T(""); 00269 } 00270 00271 void CColourPicker::SetCustomText(LPCTSTR szCustomText) 00272 { 00273 m_strCustomText = (szCustomText)? szCustomText : _T(""); 00274 } 00275 00277 // CColourPicker implementation 00278 00279 void CColourPicker::SetWindowSize() 00280 { 00281 // Get size dimensions of edges 00282 CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE)); 00283 00284 // Get size of dropdown arrow 00285 // @ Tihamer Levendovszky 00286 // int nArrowWidth = 14;//max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx); 00287 // int nArrowHeight = 14;//max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy); 00288 //CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight)); 00289 00290 // Get window size 00291 CRect rect; 00292 GetWindowRect(rect); 00293 00294 // Set Arrow size @Tihamer Levendovszky 00295 CSize ArrowSize(rect.Height(),rect.Height()); 00296 00297 CWnd* pParent = GetParent(); 00298 if (pParent) 00299 pParent->ScreenToClient(rect); 00300 00301 // Set window size at least as wide as 2 arrows, and as high as arrow + margins 00302 int nWidth = max(rect.Width(), 2*ArrowSize.cx + 2*MarginSize.cx); 00303 00304 // @Tihamer Levendovszky 00305 //MoveWindow(rect.left, rect.top, nWidth, ArrowSize.cy+2*MarginSize.cy, TRUE); 00306 MoveWindow(rect.left, rect.top, nWidth, rect.Height(), TRUE); 00307 00308 // Get the new coords of this window 00309 GetWindowRect(rect); 00310 ScreenToClient(rect); 00311 00312 // Get the rect where the arrow goes, and convert to client coords. 00313 /* m_ArrowRect.SetRect(rect.right - ArrowSize.cx - MarginSize.cx, 00314 rect.top + MarginSize.cy, rect.right - MarginSize.cx, 00315 rect.bottom - MarginSize.cy); 00316 */ 00317 // @Tihamer Levendovszky 00318 m_ArrowRect.SetRect(rect.right - ArrowSize.cx,rect.top-1,rect.right,rect.bottom-1 ); 00319 }