www.pudn.com > News Search3.01.rar > ColorPicker.cpp


// ColorPicker.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "ColorPicker.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
void AFXAPI DDX_ColorPicker(CDataExchange *pDX, int nIDC, COLORREF& crColor) 
{ 
    HWND hWndCtrl = pDX->PrepareCtrl(nIDC); 
    ASSERT (hWndCtrl != NULL);                 
     
    CColorPicker* pColorPicker = (CColorPicker*) CWnd::FromHandle(hWndCtrl); 
    if (pDX->m_bSaveAndValidate) 
    { 
        crColor = pColorPicker->GetColor(); 
    } 
    else // initializing 
    { 
        pColorPicker->SetColor(crColor); 
    } 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CColorPicker 
 
CColorPicker::CColorPicker() 
{ 
    SetBkColor(GetSysColor(COLOR_3DFACE)); 
    SetTextColor(GetSysColor(COLOR_BTNTEXT)); 
 
    m_bTrackSelection = FALSE; 
    m_nSelectionMode = CP_MODE_BK; 
    m_bActive = FALSE; 
 
    m_strDefaultText.LoadString(IDS_DEFAULT_TEXT); 
    m_strCustomText.LoadString(IDS_CUSTOM_TEXT); 
} 
 
CColorPicker::~CColorPicker() 
{ 
} 
 
IMPLEMENT_DYNCREATE(CColorPicker, CButton) 
 
BEGIN_MESSAGE_MAP(CColorPicker, CButton) 
	//{{AFX_MSG_MAP(CColorPicker) 
	ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked) 
	ON_WM_CREATE() 
	//}}AFX_MSG_MAP 
    ON_MESSAGE(CPN_SELENDOK,     OnSelEndOK) 
    ON_MESSAGE(CPN_SELENDCANCEL, OnSelEndCancel) 
    ON_MESSAGE(CPN_SELCHANGE,    OnSelChange) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CColorPicker message handlers 
 
LONG CColorPicker::OnSelEndOK(UINT lParam, LONG /*wParam*/) 
{ 
    COLORREF crNewColor = (COLORREF) lParam; 
    m_bActive = FALSE; 
    SetColor(crNewColor); 
 
    CWnd *pParent = GetParent(); 
    if (pParent) { 
        pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID()); 
        pParent->SendMessage(CPN_SELENDOK, lParam, (WPARAM) GetDlgCtrlID()); 
    } 
 
    if (crNewColor != GetColor()) 
        if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID()); 
 
    return TRUE; 
} 
 
LONG CColorPicker::OnSelEndCancel(UINT lParam, LONG /*wParam*/) 
{ 
    m_bActive = FALSE; 
    SetColor((COLORREF) lParam); 
 
    CWnd *pParent = GetParent(); 
    if (pParent) { 
        pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID()); 
        pParent->SendMessage(CPN_SELENDCANCEL, lParam, (WPARAM) GetDlgCtrlID()); 
    } 
 
    return TRUE; 
} 
 
LONG CColorPicker::OnSelChange(UINT lParam, LONG /*wParam*/) 
{ 
    if (m_bTrackSelection) SetColor((COLORREF) lParam); 
 
    CWnd *pParent = GetParent(); 
    if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID()); 
 
    return TRUE; 
} 
 
COLORREF CColorPicker::GetColor() 
{  
    return (m_nSelectionMode == CP_MODE_TEXT)?  
        GetTextColor(): GetBkColor();  
} 
 
void CColorPicker::SetColor(COLORREF crColor) 
{  
    (m_nSelectionMode == CP_MODE_TEXT)?  
        SetTextColor(crColor): SetBkColor(crColor);  
} 
 
void CColorPicker::SetBkColor(COLORREF crColorBk) 
{ 
    m_crColorBk = crColorBk; 
    if (IsWindow(m_hWnd)) 
        RedrawWindow(); 
} 
 
void CColorPicker::SetTextColor(COLORREF crColorText) 
{ 
    m_crColorText = crColorText; 
    if (IsWindow(m_hWnd))  
        RedrawWindow(); 
} 
 
void CColorPicker::SetDefaultText(LPCTSTR szDefaultText) 
{ 
    m_strDefaultText = (szDefaultText)? szDefaultText : _T(""); 
} 
 
void CColorPicker::SetCustomText(LPCTSTR szCustomText) 
{ 
    m_strCustomText = (szCustomText)? szCustomText : _T(""); 
} 
 
void CColorPicker::SetWindowSize() 
{ 
    // Get size dimensions of edges 
    CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE)); 
 
    // Get size of dropdown arrow 
    int nArrowWidth = max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx); 
    int nArrowHeight = max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy); 
    CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight)); 
 
    // Get window size 
    CRect rect; 
    GetWindowRect(rect); 
 
    CWnd* pParent = GetParent(); 
    if (pParent) 
        pParent->ScreenToClient(rect); 
 
    // Set window size at least as wide as 2 arrows, and as high as arrow + margins 
    int nWidth = max(rect.Width(), 2*ArrowSize.cx + 2*MarginSize.cx); 
    MoveWindow(rect.left, rect.top, nWidth, ArrowSize.cy+2*MarginSize.cy, TRUE); 
 
    // Get the new coords of this window 
    GetWindowRect(rect); 
    ScreenToClient(rect); 
 
    // Get the rect where the arrow goes, and convert to client coords. 
    m_ArrowRect.SetRect(rect.right - ArrowSize.cx - MarginSize.cx,  
                        rect.top + MarginSize.cy, rect.right - MarginSize.cx, 
                        rect.bottom - MarginSize.cy); 
} 
 
void CColorPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
	// TODO: Add your code to draw the specified item 
    ASSERT(lpDrawItemStruct); 
     
    CDC*    pDC     = CDC::FromHandle(lpDrawItemStruct->hDC); 
    CRect   rect    = lpDrawItemStruct->rcItem; 
    UINT    state   = lpDrawItemStruct->itemState; 
    CString m_strText; 
 
    CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE)); 
 
    // Draw arrow 
    if (m_bActive) state |= ODS_SELECTED; 
    pDC->DrawFrameControl(&m_ArrowRect, DFC_SCROLL, DFCS_SCROLLDOWN  |  
                          ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) | 
                          ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0)); 
 
    pDC->DrawEdge(rect, EDGE_SUNKEN, BF_RECT); 
 
    // Must reduce the size of the "client" area of the button due to edge thickness. 
    rect.DeflateRect(Margins.cx, Margins.cy); 
 
    // Fill remaining area with color 
    rect.right -= m_ArrowRect.Width(); 
 
	CRect rc = rect; 
	pDC->FillSolidRect(rc,::GetSysColor(COLOR_3DFACE)); 
	pDC->Draw3dRect(rc,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DHILIGHT)); 
	rc.SetRect(rc.left+6, rc.top+3, rc.right-6, rc.bottom-3); 
	pDC->Draw3dRect(rc,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DHILIGHT)); 
	rc.SetRect(rc.left+1, rc.top+1, rc.right-1, rc.bottom-1); 
	pDC->Draw3dRect(rc,::GetSysColor(COLOR_3DSHADOW),::GetSysColor(COLOR_3DSHADOW)); 
	rc.SetRect(rc.left+1, rc.top+1, rc.right-1, rc.bottom-1); 
 
	pDC->FillSolidRect(rc,m_crColorBk); 
 
    // Draw the window text (if any) 
    GetWindowText(m_strText); 
    if (m_strText.GetLength()) 
    { 
        pDC->SetBkMode(TRANSPARENT); 
        if (state & ODS_DISABLED) 
        { 
            rect.OffsetRect(1,1); 
            pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT)); 
            pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 
            rect.OffsetRect(-1,-1); 
            pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW)); 
            pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 
        } 
        else 
        { 
            pDC->SetTextColor((m_crColorText == CLR_DEFAULT)? 0 : m_crColorText); 
            pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 
        } 
    } 
 
    // Draw focus rect 
    if (state & ODS_FOCUS)  
    { 
        rect.DeflateRect(2,2); 
        pDC->DrawFocusRect(rect); 
    } 
} 
 
void CColorPicker::PreSubclassWindow()  
{ 
	// TODO: Add your specialized code here and/or call the base class 
    ModifyStyle(0, BS_OWNERDRAW);        // Make it owner drawn 
    CButton::PreSubclassWindow(); 
    SetWindowSize();                     // resize appropriately 
} 
 
BOOL CColorPicker::OnClicked()  
{ 
	// TODO: Add your control notification handler code here 
    m_bActive = TRUE; 
    CRect rect; 
    GetWindowRect(rect); 
    new CColorPopup(CPoint(rect.left, rect.bottom),    // Point to display popup 
                     GetColor(),                       // Selected color 
                     this,                              // parent 
                     m_strDefaultText,                  // "Default" text area 
                     m_strCustomText);                  // Custom Text 
 
    CWnd *pParent = GetParent(); 
    if (pParent) 
        pParent->SendMessage(CPN_DROPDOWN, (LPARAM)GetColor(), (WPARAM) GetDlgCtrlID()); 
 
    // Docs say I should return FALSE to stop the parent also getting the message. 
    // HA! What a joke. 
 
    return TRUE; 
} 
 
int CColorPicker::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CButton::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
    SetWindowSize();    // resize appropriately 
	 
	return 0; 
}