拾色器
拾色器类
#pragma once
class CClrPickerCtrl : public SWindow
{
DEF_SOBJECT(SWindow, L"clrpicker")
public:
CClrPickerCtrl(void);
~CClrPickerCtrl(void);
//跟solider控件设置色调
void SetSliderPos(int nPos);
//获取选取位置的颜色
COLORREF GetColor();
protected:
LRESULT OnCreate(LPVOID);
void OnPaint(IRenderTarget* pRT);
void OnLButtonDown(UINT nFlags, SOUI::CPoint pt);
void OnLButtonUp(UINT nFlags, SOUI::CPoint pt);
void OnMouseMove(UINT nFlags, SOUI::CPoint point);
SOUI_MSG_MAP_BEGIN()
MSG_WM_CREATE(OnCreate)
MSG_WM_PAINT_EX(OnPaint)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_LBUTTONUP(OnLButtonUp)
MSG_WM_MOUSEMOVE(OnMouseMove)
SOUI_MSG_MAP_END()
SOUI_ATTRS_BEGIN()
SOUI_ATTRS_END()
protected:
//将HSV色彩模型转为RGB颜色值
COLORREF HSV2RGB(const double hsv[3]);
private:
SOUI::CPoint m_point;
int m_nSoliderPos;
COLORREF m_clrSelect;
};
#include "stdafx.h"
#include "CClrPickerCtrl.h"
CClrPickerCtrl::CClrPickerCtrl()
{
m_nSoliderPos = 0;
}
CClrPickerCtrl::~CClrPickerCtrl()
{
}
LRESULT CClrPickerCtrl::OnCreate(LPVOID)
{
SetMsgHandled(FALSE);
return __super::OnCreate(NULL);
}
COLORREF CClrPickerCtrl::HSV2RGB(const double hsv[3])
{
//RGB的0.0-1.0表示
double r = 0.0;
double g = 0.0;
double b = 0.0;
int h_i = (int)abs(hsv[0] / 60.0);
double f = hsv[0] / 60.0 - h_i;
double p = hsv[2] * (1 - hsv[1]);
double q = hsv[2] * (1 - f * hsv[1]);
double t = hsv[2] * (1 - (1 - f) * hsv[1]);
switch (h_i) {
case 0:
r = hsv[2]; g = t; b = p;
break;
case 1:
r = q; g = hsv[2]; b = p;
break;
case 2:
r = p; g = hsv[2]; b = t;
break;
case 3:
r = p; g = q; b = hsv[2];
break;
case 4:
r = t; g = p; b = hsv[2];
break;
case 5:
r = hsv[2]; g = p; b = q;
break;
}
//转换成0-255
int R = (int)(r * 255 + 0.5);
int G = (int)(g * 255 + 0.5);
int B = (int)(b * 255 + 0.5);
return RGBA(R, G, B, 255);
}
void CClrPickerCtrl::OnPaint(IRenderTarget* pRT)
{
SetMsgHandled(FALSE);
pRT->SetAntiAlias(TRUE);
CRect rcClient = GetWindowRect();
int nStep = rcClient.Width() / 100;
for (int i = 0; i < 100; i++)
{
double hsv[3] = { m_nSoliderPos, (double)i / 100, 1};
COLORREF crUp = HSV2RGB(hsv);
COLORREF crDown = RGBA(0, 0, 0, 255);
CRect rcDraw = { rcClient.left + nStep * i, rcClient.top, rcClient.left + nStep * (i + 1), rcClient.bottom };
GradientItem gradients[2] = { crUp, 0.0f, crDown, 1.0f };
pRT->DrawGradientRect(rcDraw, TRUE, CPoint(), gradients, 2, 0xff);
}
m_clrSelect = pRT->GetPixel(m_point.x, m_point.y);
//绘制鼠标选中区域
CAutoRefPtr<IPen> pen, oldpen;
COLORREF clrBorder = RGBA(255,255,255,255);
pRT->CreatePen(PS_SOLID | PS_ENDCAP_SQUARE, clrBorder, 2, &pen);
pRT->SelectObject(pen, (IRenderObj**)&oldpen);
CRect rcClrArea;
rcClrArea.top = m_point.y;
rcClrArea.left = m_point.x;
rcClrArea.right = m_point.x + 6;
rcClrArea.bottom = m_point.y + 6;
pRT->DrawRectangle(rcClrArea);
pRT->SelectObject(oldpen, NULL);
}
void CClrPickerCtrl::OnLButtonDown(UINT nFlags, SOUI::CPoint pt)
{
SetMsgHandled(FALSE);
m_point = pt;
Invalidate();
}
void CClrPickerCtrl::OnLButtonUp(UINT nFlags, SOUI::CPoint pt)
{
SetMsgHandled(FALSE);
//将颜色通过事件传递至上层
Invalidate();
}
void CClrPickerCtrl::OnMouseMove(UINT nFlags, SOUI::CPoint point)
{
SetMsgHandled(FALSE);
CRect rcClient = GetClientRect();
if ((nFlags & MK_LBUTTON))
{
m_point = point;
if (point.x < rcClient.left) m_point.x = rcClient.left;
else if (point.x > rcClient.right) m_point.x = rcClient.right;
if (point.y < rcClient.top) m_point.y = rcClient.top;
else if (point.y > rcClient.bottom) m_point.y = rcClient.bottom;
}
Invalidate();
}
void CClrPickerCtrl::SetSliderPos(int nPos)
{
m_nSoliderPos = 359 - nPos;
Invalidate();
}
COLORREF CClrPickerCtrl::GetColor()
{
return m_clrSelect;
}
控件使用:
1、注册控件
m_theApp->RegisterWindowClass<CClrPickerCtrl>();
2、在布局中使用
<clrpicker name="clrpick" pos="100,[10,@450,@250" colorBkgnd="#FFFFFF" />
<sliderbar name ="sliderbar" vertical="1" thumbInRail="1" pos="[-30,{0,@16,@250" thumbSkin="skin_color_pick_thum" posSkin="skin_null" bkgndSkin="skin_color_pick_bk" min="0" max="359"/>
3、效果
在solider控件更改滑块位置时需要通知拾色器控件
//函数定义
void OnSilderChange(EventArgs* pEvt);
//事件关联
EVENT_NAME_HANDLER(L"sliderbar", EventSliderPos::EventID, OnSilderChange)
//函数实现
void CMainDlg::OnSilderChange(EventArgs* pEvt)
{
EventSliderPos* evt = (EventSliderPos*)pEvt;
if (evt)
{
SSliderBar* pSliderbar = FindChildByName2<SSliderBar>(L"sliderbar");
CClrPickerCtrl* pClrPick = FindChildByName2<CClrPickerCtrl>(L"clrpick");
SASSERT(pClrPick);
pClrPick->SetSliderPos(evt->nPos);
pClrPick->Invalidate();
}
}