先看看TM2008的皮肤调色板:
虽然简单,也还是很漂亮的。
接下来,我将一步一步去(非完全)实现该调色板。
建立MFC工程
添加:
typedef struct {
COLORREF crColour;
TCHAR *szName;
} ColourTableEntry;
新建类 CColorPanel 继承CWnd;给该类添加一个变量:CRect m_WindowRect;用于保存该面板的大小;在添加CWnd* m_pParent; 用于保存父窗体指针。添加静态变量:
static ColourTableEntry m_crColours[];
ColourTableEntry CColorPanel::m_crColours[] ={
{RGB(147,210,247), _T("Blue") },
{RGB(137,184,224), _T("GrayBlue") },
{RGB(189,103,234), _T("Purple") },
{RGB(110,196,70), _T("Green") },
{RGB(233,173,112), _T("YellowBrown")},
{RGB(198,94,59), _T("Brown") },
{RGB(203,73,156), _T("Violet") },
{RGB(147,147,147), _T("Gray") }
};
我们再为该类添加一个新的构造函数:CColorPanel(CPoint p, CWnd *pParentWnd, COLORREF crColour)
所有代码如下:
ColorPanel.cpp
//
#include " stdafx.h "
#include " DoodlePanel.h "
#include " ColorPanel.h "
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/**/ /////
// CColorPanel
CColorPanel::CColorPanel()
... {
}
CColorPanel::CColorPanel(CPoint p, CWnd * pParentWnd, COLORREF crColour)
... {
m_nBoxSize=20;
CColorPanel::Create(p,pParentWnd,crColour);
}
CColorPanel:: ~ CColorPanel()
... {
}
BEGIN_MESSAGE_MAP(CColorPanel, CWnd)
// {{AFX_MSG_MAP(CColorPanel)
ON_WM_PAINT()
ON_WM_ACTIVATEAPP()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
// }}AFX_MSG_MAP
END_MESSAGE_MAP()
ColourTableEntry CColorPanel::m_crColours[] = ... {
...{RGB(147,210,247), _T("Blue") },
...{RGB(137,184,224), _T("GrayBlue") },
...{RGB(189,103,234), _T("Purple") },
...{RGB(110,196,70), _T("Green") },
...{RGB(233,173,112), _T("YellowBrown")},
...{RGB(198,94,59), _T("Brown") },
...{RGB(203,73,156), _T("Violet") },
...{RGB(147,147,147), _T("Gray") }
} ;
/**/ /////
// CColorPanel message handlers
// 创建调色板
BOOL CColorPanel::Create(CPoint p, CWnd * pParentWnd, COLORREF crColour)
... {
ASSERT(pParentWnd && ::IsWindow(pParentWnd->GetSafeHwnd()));
m_pParent=pParentWnd;
CString szClassName=AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW,
0,
(HBRUSH)(COLOR_BTNFACE+1),
0
);
if(!CWnd::CreateEx(0,szClassName,_T(""),WS_VISIBLE|WS_POPUP,
p.x,p.y,115,120,
pParentWnd->GetSafeHwnd(),0,NULL
))
return FALSE;
//面板保存大小
CRect rect;
GetWindowRect(rect);
m_WindowRect.SetRect(rect.left, rect.top, rect.right,rect.bottom);
//CClientDC dc(this);
//DrawSliderBar(&dc,0);
CreateToolTips();
SetCapture();
return TRUE;
}
void CColorPanel::OnPaint()
... {
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CWnd::OnPaint() for painting messages
//绘制面板边框
CRect rect;
GetClientRect(rect);
//dc.DrawEdge(rect, EDGE_RAISED, BF_RECT);
//Top Line
dc.FillSolidRect(rect,RGB(37,135,14));
dc.FillSolidRect(rect.left+1,rect.top+1,rect.Width()-2,rect.Height()-2,RGB(211,236,185));
dc.FillSolidRect(rect.left+2, rect.top+2,rect.Width()-4, rect.Height()-4,RGB(189,237,176));
for(int i=0;i<8;i++)
DrawCell(&dc,i);
// for(i=0;i<3;i++)
// DrawSliderBar(&dc,i);
}
void CColorPanel::OnActivateApp(BOOL bActive, HTASK hTask)
... {
CWnd::OnActivateApp(bActive, hTask);
// TODO: Add your message handler code here
if(!bActive)
DestroyWindow();
}
void CColorPanel::OnLButtonUp(UINT nFlags, CPoint point)
... {
// TODO: Add your message handler code here and/or call default
CWnd::OnLButtonUp(nFlags, point);
DWORD pos = GetMessagePos();
point = CPoint(LOWORD(pos), HIWORD(pos));
if(!m_WindowRect.PtInRect(point))
DestroyWindow();
}
// 绘制默认色块
void CColorPanel::DrawCell(CDC * pDC, int nIndex)
... {
CRect rect;
if(!GetCellRect(nIndex,rect))return;
pDC->FillSolidRect(rect,RGB(0,0,0));
pDC->FillSolidRect(rect.left+1,rect.top+1,rect.Width()-2,rect.Height()-2,m_crColours[nIndex].crColour);
}
BOOL CColorPanel::GetCellRect( int nIndex, const LPRECT & rect)
... {
if (nIndex < 0 || nIndex >= 8)
return FALSE;
rect->top=nIndex<=3?5:30;
rect->top+=5;
rect->bottom=rect->top+m_nBoxSize;
rect->left=5*(nIndex+1)+m_nBoxSize*nIndex;
if(nIndex>3)
rect->left-=100;
rect->left+=5;
rect->right=rect->left+m_nBoxSize;
return TRUE;
}
BOOL CColorPanel::PreTranslateMessage(MSG * pMsg)
... {
// TODO: Add your specialized code here and/or call the base class
m_ToolTip.RelayEvent(pMsg);
if (GetCapture()->GetSafeHwnd() != m_hWnd)...{
SetCapture();
}
return CWnd::PreTranslateMessage(pMsg);
}
void CColorPanel::CreateToolTips()
... {
if (!m_ToolTip.Create(this)) return;
// Add a tool for each cell
for (int i = 0; i < 8; i++)
...{
CRect rect;
if (!GetCellRect(i, rect)) continue;
m_ToolTip.AddTool(this, m_crColours[i].szName, rect, 1);
}
}
void CColorPanel::OnMouseMove(UINT nFlags, CPoint point)
... {
// TODO: Add your message handler code here and/or call default
CWnd::OnMouseMove(nFlags, point);
}
void CColorPanel::DrawSliderBar(CDC * pDc, int nRGB)
... {
CRect rect;
if(!GetSilderRGBRect(nRGB,rect))
return;
m_rSlider.Create(WS_CHILD|WS_VISIBLE,rect,this,123);
// pDc->FillSolidRect(rect.left,rect.top-1,rect.Width(),rect.Height(),::GetSysColor(COLOR_3DSHADOW));
// pDc->FillSolidRect(rect,::GetSysColor(COLOR_3DHILIGHT));
// pDc->FillSolidRect(rect.left,rect.top+1,rect.Width(),rect.Height(),::GetSysColor(COLOR_3DSHADOW));
}
BOOL CColorPanel::GetSilderRGBRect( int nRGB, const LPRECT & rect)
... {
if(nRGB<0 || nRGB>=3)
return FALSE;
rect->left=10;
rect->right=105;
rect->top=(nRGB+1)*15+50;
rect->bottom=rect->top+20;
return TRUE;
}
ColorPanel.h
#define AFX_COLORPANEL_H__6AC0AF39_0C13_4238_8018_82651474D77E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ColorPanel.h : header file
//
#include " NewSlider.h "
/**/ /////
// CColorPanel window
typedef struct ... {
COLORREF crColour;
TCHAR *szName;
} ColourTableEntry;
class CColorPanel : public CWnd
... {
// Construction
public:
CColorPanel();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorPanel)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Implementation
public:
CColorPanel(CPoint p, CWnd *pParentWnd, COLORREF crColour);
virtual ~CColorPanel();
// Generated message map functions
protected:
CNewSlider m_rSlider;
BOOL GetSilderRGBRect(int nRGB,const LPRECT &rect);
void DrawSliderBar(CDC* pDc,int nRGB);
void CreateToolTips();
CToolTipCtrl m_ToolTip;
int m_nBoxSize;
BOOL GetCellRect(int nIndex, const LPRECT& rect);
void DrawCell(CDC* pDC, int nIndex);
static ColourTableEntry m_crColours[];
CRect m_WindowRect;
CWnd* m_pParent;
BOOL Create(CPoint p, CWnd *pParentWnd, COLORREF crColour);
//{{AFX_MSG(CColorPanel)
afx_msg void OnPaint();
afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
} ;
/**/ /////
// {{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORPANEL_H__6AC0AF39_0C13_4238_8018_82651474D77E__INCLUDED_)
Demo:
m_btnTest.GetWindowRect(rect);
new CColorPanel(CPoint(rect.left,rect.bottom), this ,RGB( 255 , 0 , 0 ));