Click here to Skip to main content
15,887,676 members
Articles / Desktop Programming / MFC

A color picker dialog with a color dropper like Photoshop and Frontpage 2000

Rate me:
Please Sign up or sign in to vote.
4.83/5 (10 votes)
23 Jan 20022 min read 94.9K   4.3K   29  
A color picker and dropper that extends the standard Windows dialogs to behave like Photoshop or Frontpage 2000
// Copyright UCanCode Software Technology Inc, All Rights Reserved
// You can contact us.
// Support@UCanCode.net
// http://www.ucancode.net
/********************************************************************/
// FOColorDialog.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "FOColorDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CFOColorDialog dialog


CFOColorDialog::CFOColorDialog(CWnd* pParent /*=NULL*/)
	: CDialog(CFOColorDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFOColorDialog)
	m_strValue = _T("");
	//}}AFX_DATA_INIT
	m_bCapturing = FALSE;
	crColor = RGB(255,255,255);
	m_bPalette = TRUE;
}


void CFOColorDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFOColorDialog)
	DDX_Control(pDX, IDC_NEWVERSION, m_newVersion);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CFOColorDialog, CDialog)
	//{{AFX_MSG_MAP(CFOColorDialog)
	ON_WM_DESTROY()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_BN_CLICKED(IDC_FO_COLOR_CUSTOM, OnFoColorCustom)
	ON_WM_SYSCOLORCHANGE()
	ON_WM_QUERYNEWPALETTE()
	ON_WM_PALETTECHANGED()
	//}}AFX_MSG_MAP
ON_MESSAGE(WM_FO_SELECTCOLOROK, OnSelectDayOK)
ON_MESSAGE(WM_FO_SELECTCOLORCUSTOM, OnSelectCustom)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFOColorDialog message handlers

BOOL CFOColorDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	if (gfxData.m_nBitsPerPixel < 8)	// 16 colors, call standard dialog
	{
		CColorDialog dlg (crColor, CC_FULLOPEN | CC_ANYCOLOR);
		int nResult = dlg.DoModal ();
		crColor = dlg.GetColor ();
		EndDialog (nResult);

		return TRUE;
	}
	m_staticColor.AttachStatic(IDC_FO_SELECTCOLOR,this);
	m_staticColor.InsertImage(IDB_FO_COLOR_BITMAP,-1,RGB(255,255,255));
	m_newVersion.SetURL(_T("http://www.ucancode.net/"));
	
	CRect theRect;
	GetDlgItem(IDC_FO_COLORS)->GetWindowRect( &theRect );
	ScreenToClient(&theRect);	
	m_wndColor.Create(WS_CHILD|WS_VISIBLE,theRect, this,4232,RGB(255,255,255));
	m_wndColor.GetColorControl()->SetBorderType(BORDER_ETCHED);
	m_wndColor.GetColorControl()->SetCustomBar(FALSE);
	m_wndColor.GetColorControl()->InitColorPalette();

	m_btnColor.Attach(IDC_FO_BUTTON_PREVIEW,this);

	m_wndColor.GetColorControl()->SetRGB(crColor);
	m_btnColor.SetButtonColor(crColor);
	m_btnColor.SetOldColor(crColor);
	CString strValue;
	strValue.Format("%u,%u,%u",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
	GetDlgItem(IDC_FO_COLOR_VALUE)->SetWindowText(strValue);

	strValue.Format("%02X%02X%02X",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
	GetDlgItem(IDC_FO_COLOR_HEX_VALUE)->SetWindowText(strValue);

	CWinApp* pApp = AfxGetApp();
	ASSERT(pApp);
	if (pApp)
	{
		m_hCursor = pApp->LoadCursor(IDC_FO_SELECTCOLOR_CURSOR);
	}
	return TRUE; 
}

LONG CFOColorDialog::OnSelectDayOK(UINT wParam, LONG lParam)
{
	lParam;
	COLORREF crNewColor = (COLORREF) wParam;
	m_btnColor.SetButtonColor(crNewColor);
	SetColor(crNewColor);
	CString strValue;
	strValue.Format("%u,%u,%u",GetRValue(crNewColor),GetGValue(crNewColor),GetBValue(crNewColor));
	GetDlgItem(IDC_FO_COLOR_VALUE)->SetWindowText(strValue);
	
	strValue.Format("%02X%02X%02X",GetRValue(crNewColor),GetGValue(crNewColor),GetBValue(crNewColor));
	GetDlgItem(IDC_FO_COLOR_HEX_VALUE)->SetWindowText(strValue);

	return 0L;
}

LONG CFOColorDialog::OnSelectCustom(UINT wParam, LONG lParam)
{
	wParam;
	lParam;
	CColorDialog dlg(m_wndColor.GetColorControl()->GetRGB(), CC_FULLOPEN | CC_ANYCOLOR);
	if(dlg.DoModal() == IDOK)
	{
		m_wndColor.GetColorControl()->SetRGB(dlg.GetColor());
		m_btnColor.SetButtonColor(dlg.GetColor());
		m_wndColor.GetColorControl()->UpdateCustom();
		SetColor(dlg.GetColor());
		CString strValue;
		strValue.Format("%u,%u,%u",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
		GetDlgItem(IDC_FO_COLOR_VALUE)->SetWindowText(strValue);
		
		strValue.Format("%02X%02X%02X",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
		GetDlgItem(IDC_FO_COLOR_HEX_VALUE)->SetWindowText(strValue);
	}
	return 0L;
}

void CFOColorDialog::StopCapture()
{
	if (m_bCapturing)
	{
		ReleaseCapture();
		m_bCapturing = FALSE;

		SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
	}
}
BOOL CFOColorDialog::PreTranslateMessage(MSG* pMsg) 
{
	BOOL bHandledMsg = FALSE;

	switch (pMsg->message)
	{                      
		case WM_KEYDOWN:
		{
			switch (pMsg->wParam)
			{
				// hitting escape while searching for password edits
				// should only stop the search for password edits and 
				// not kill app 
				case VK_ESCAPE:
					if (m_bCapturing)
					{
						StopCapture();
						bHandledMsg = TRUE;
					}
				break;
				
				default: break;
			} // switch (pMsg->wParam)
		}
		break;
		
		default: break;			
	} // switch (pMsg->message)                  

	return (bHandledMsg ? TRUE : CDialog::PreTranslateMessage(pMsg));
}

void CFOColorDialog::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CWnd* pWnd = ChildWindowFromPoint(point);
	if (pWnd  && pWnd->GetSafeHwnd() == m_staticColor.GetSafeHwnd())
	{
		SetCapture();
		SetCursor(m_hCursor);

		m_bCapturing = TRUE;
	}

	CDialog::OnLButtonDown(nFlags, point);
}

void CFOColorDialog::OnLButtonUp(UINT nFlags, CPoint point) 
{
	nFlags;
	point;
	if (m_bCapturing)
	{
		StopCapture();
	}
}

void CFOColorDialog::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (m_bCapturing)
	{
		ClientToScreen(&point);
		HDC hScreenDC = ::GetDC(NULL);			
		crColor = ::GetPixel(hScreenDC,point.x,point.y);
		m_btnColor.SetButtonColor(crColor);
		m_wndColor.GetColorControl()->SetRGB(crColor);
		CString strValue;
		strValue.Format("%u,%u,%u",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
		GetDlgItem(IDC_FO_COLOR_VALUE)->SetWindowText(strValue);
		
		strValue.Format("%02X%02X%02X",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
		GetDlgItem(IDC_FO_COLOR_HEX_VALUE)->SetWindowText(strValue);
		::ReleaseDC(NULL,hScreenDC);

		UpdateData(FALSE);
	}

	CDialog::OnMouseMove(nFlags, point);
}

void CFOColorDialog::OnDestroy() 
{
	if(m_Palette.GetSafeHandle()!=NULL)
		m_Palette.DeleteObject();
	CDialog::OnDestroy();
}

void CFOColorDialog::OnFoColorCustom() 
{
	// TODO: Add your control notification handler code here
	CColorDialog dlg(GetColor(), CC_FULLOPEN | CC_ANYCOLOR);
	if(dlg.DoModal() == IDOK)
	{
		m_wndColor.GetColorControl()->SetRGB(dlg.GetColor());
		m_btnColor.SetButtonColor(dlg.GetColor());
		SetColor(dlg.GetColor());
		CString strValue;
		strValue.Format("%u,%u,%u",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
		GetDlgItem(IDC_FO_COLOR_VALUE)->SetWindowText(strValue);
		
		strValue.Format("%02X%02X%02X",GetRValue(crColor),GetGValue(crColor),GetBValue(crColor));
		GetDlgItem(IDC_FO_COLOR_HEX_VALUE)->SetWindowText(strValue);
	}
}

void CFOColorDialog::OnSysColorChange() 
{
	CDialog::OnSysColorChange();

	gfxData.OnSysColorChange();
	
	if (m_bPalette)
	{
		if (gfxData.m_nBitsPerPixel < 8)
		{
			ShowWindow (SW_HIDE);

			CColorDialog dlg (crColor, CC_FULLOPEN | CC_ANYCOLOR);
			int nResult = dlg.DoModal ();
			crColor = dlg.GetColor ();
			EndDialog (nResult);
		}
		else
		{
			CreatePalette();
			Invalidate();
			UpdateWindow();
		}
	}
}

void CFOColorDialog::CreatePalette(BOOL bRedraw)
{
	bRedraw;
	// Create palette:
	CPaintDC dc (this);

	CDC *pDC = &dc;
	
	if(pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
	{
		LOGPALETTE *pPal=(LOGPALETTE *)new unsigned char[sizeof(LOGPALETTE)+257*sizeof(PALETTEENTRY)];
	
		pPal->palVersion=0x300;
		pPal->palNumEntries=256;

		for(int i=0;i<256;i++)
		{
			pPal->palPalEntry[i].peRed=(unsigned char)(255 * (i & 0x07) / 7 );
			pPal->palPalEntry[i].peGreen=(unsigned char)(255 * ((i >> 3) & 0x07)/ 7 );
			pPal->palPalEntry[i].peBlue=(unsigned char)(255 * ((i >> 6) & 0x03) / 3 );
			pPal->palPalEntry[i].peFlags = 0;
		}

		m_Palette.CreatePalette(pPal);//Halftone

		pDC->SelectPalette(&m_Palette,FALSE);
		pDC->RealizePalette();

		delete pPal;
	}
}

BOOL CFOColorDialog::OnQueryNewPalette() 
{
	if(m_Palette.GetSafeHandle()!=NULL)
	{
		CPaintDC dc(this);
		CDC *pDC=&dc;
		CPalette *pOldPal=(CPalette *)pDC->SelectPalette(&m_Palette,FALSE);
		pDC->RealizePalette();
		pDC->SelectPalette(pOldPal,FALSE);
		return TRUE;
	}
	return CWnd::OnQueryNewPalette();
}


void CFOColorDialog::OnPaletteChanged(CWnd* pFocusWnd) 
{
	if(pFocusWnd==this)
		return;

	if(m_Palette.GetSafeHandle()!=NULL)
	{
		CPaintDC dc(this);
		CDC *pDC=&dc;
		CPalette *pOldPal=(CPalette *)pDC->SelectPalette(&m_Palette,FALSE);
		pDC->RealizePalette();
		pDC->SelectPalette(pOldPal,FALSE);
	}
	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
jack Mesic is the president of UCanCode Software Technology,Inc..

Comments and Discussions