#include <stdafx.h> #include "ColorPicker.h"
WNDPROC ColorPickerWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CColorPicker* lpColorPicker = (CColorPicker*)GetWindowLong(hwnd, GWL_USERDATA); if (!lpColorPicker) return (WNDPROC)DefWindowProc(hwnd, msg, wParam, lParam); /*======================================================================== 作者: 彭国辉 DATE: 2007-12-25 EMAIL: kacarton( at )sohu.com 文章为作者原创,转载前请先与本人联系,转载请注明文章出处、保留作者信息,谢谢支持! =========================================================================*/ switch (msg) { case WM_PAINT: lpColorPicker->OnPaint(); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_LBUTTONDOWN: lpColorPicker->OnLButtonDown(LOWORD(lParam), HIWORD(lParam)); break; case WM_LBUTTONUP: lpColorPicker->OnLButtonUp(LOWORD(lParam), HIWORD(lParam)); break; case WM_MOUSEMOVE: lpColorPicker->OnMouseMove(LOWORD(lParam), HIWORD(lParam)); break; case WM_KEYDOWN: if (wParam==VK_ESCAPE) { PostMessage(hwnd, WM_CLOSE, 0, 0); break; } default: return (WNDPROC)DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
CColorPicker::CColorPicker(POINT *pt, DWORD DefaultColor) { m_hwnd = NULL; m_Color = DefaultColor; m_HotRow = m_HotCol = 255; m_bCustomColor = true; m_bMouseDown = false; CreateColorPicker(pt); }
CColorPicker::~CColorPicker() { ReleaseCapture(); }
void CColorPicker::CreateColorPicker(POINT *pt) { WNDCLASS wndclass; //注册窗体类名 if (GetClassInfo(m_hInstance, COLORPICKERWINNAME, &wndclass) == 0) { memset(&wndclass, 0, sizeof(WNDCLASS)); wndclass.style = CS_VREDRAW | CS_HREDRAW; wndclass.lpfnWndProc = (WNDPROC)ColorPickerWndProc; wndclass.hInstance = m_hInstance; wndclass.hbrBackground = (HBRUSH)GetStockObject(COLOR_WINDOW); //wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.lpszClassName = COLORPICKERWINNAME; RegisterClass(&wndclass); }
//创建工具栏窗体,定位于主窗口上方 RECT rc; GetWindowRect(AfxGetMainWnd()->m_hWnd, &rc); m_hwnd = CreateWindowEx(0, COLORPICKERWINNAME, "颜色拾取窗", WS_POPUP | WS_BORDER | WS_TABSTOP, pt->x, pt->y, 8*18+12, 126, 0, NULL, /**//*AfxGetInstanceHandle()*/m_hInstance, NULL); if (!m_hwnd) return; SetWindowLong(m_hwnd, GWL_USERDATA, (LONG)this);
//显示窗体,进入消息循环 ShowWindow(m_hwnd, SW_SHOW); UpdateWindow(m_hwnd); SetCapture(m_hwnd);
MSG msg; while (GetMessage (&msg, NULL, 0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
HWND CColorPicker::GetHwnd() ...{return m_hwnd;} DWORD CColorPicker::GetColor() ...{return m_Color;} //响应WM_PAINT重画整个窗口 void CColorPicker::OnPaint() { PAINTSTRUCT ps; RECT rc; HBRUSH hb;
HDC hdc = BeginPaint(m_hwnd, &ps); GetClientRect(m_hwnd, &rc); hb = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); FillRect(hdc, &rc, hb); DeleteObject(hb); //绘制色块 for (byte i=0; i<5; i++) for (byte j=0; j<8; j++) { Draw(hdc, i, j, false, 1); if (m_Color == ColorMap[i][j]) m_bCustomColor = false; }
//绘自定义文字 Draw(hdc, 5, 0, m_HotRow==5, 1);
EndPaint(m_hwnd, &ps); }
//根据参数画指定区域 //窗体重绘与局部刷新竟相差了一个点,correction参数用于校正 void CColorPicker::Draw(HDC hdc, byte row, byte col, bool hot, byte correction) { RECT rc; HGDIOBJ hpen, holdpen, hbold; HBRUSH hb; if (row<5 && col<8) { rc.left = col*18 + 5 - correction; rc.top = row*18 + 5 - correction; rc.right = rc.left + 18; rc.bottom = rc.top + 18;
//显示选中热区 if (hot || ColorMap[row][col] == m_Color) { hb = CreateSolidBrush(GetSysColor(m_bMouseDown ? COLOR_HIGHLIGHT : COLOR_INACTIVECAPTIONTEXT)); hpen = CreatePen(PS_SOLID, 1, GetSysColor(m_bMouseDown ? COLOR_WINDOWFRAME : COLOR_INACTIVECAPTION)); hbold = SelectObject(hdc, hb); holdpen = SelectObject(hdc, hpen); Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); SelectObject(hdc, holdpen); SelectObject(hdc, hbold); DeleteObject(hb); DeleteObject(hpen); } else FillRect(hdc, &rc, NULL); //GetSysColorBrush //显示颜色 InflateRect(&rc, -3, -3); hb = CreateSolidBrush(ColorMap[row][col]); hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_ACTIVEBORDER)); hbold = SelectObject(hdc, hb); holdpen = SelectObject(hdc, hpen); Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); SelectObject(hdc, holdpen); SelectObject(hdc, hbold); DeleteObject(hb); DeleteObject(hpen); } else if (row==5) { //绘自定义文字 GetClientRect(m_hwnd, &rc); if (correction) OffsetRect(&rc, -correction, -correction); //校正位置 InflateRect(&rc, -5, -5); rc.top = 5*18+10; if (hot) { hb = CreateSolidBrush(GetSysColor(m_bMouseDown ? COLOR_HIGHLIGHT : COLOR_INACTIVECAPTIONTEXT)); hpen = CreatePen(PS_SOLID, 1, GetSysColor(m_bMouseDown ? COLOR_WINDOWFRAME : COLOR_INACTIVECAPTION)); hbold = SelectObject(hdc, hb); holdpen = SelectObject(hdc, hpen); Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); SelectObject(hdc, holdpen); SelectObject(hdc, hbold); DeleteObject(hb); DeleteObject(hpen); } else FillRect(hdc, &rc, NULL); //if (b_CustomColor) rc.right = 7*18; SetBkMode(hdc, TRANSPARENT); HFONT m_Font = CreateFont(-12, 0, 0, 0, 400, 0, 0, 0, GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "宋体"); HGDIOBJ m_OldFont = SelectObject(hdc, m_Font); DrawText(hdc, "其他颜色...", -1, &rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE); SelectObject(hdc, m_OldFont); DeleteObject(m_Font); if (m_bCustomColor) { rc.right = 8*18+3; rc.left = 7*18; rc.top += 2; rc.bottom = rc.top + 15;
hb = CreateSolidBrush(m_Color); hbold = SelectObject(hdc, hb); Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); //SelectObject(hdc, holdpen); DeleteObject(hb); } } }
//重绘指定区域 void CColorPicker::ReDraw(byte row, byte col, bool hot) { HDC hdc = GetWindowDC(m_hwnd); Draw(hdc, row, col, hot, 0); ReleaseDC(m_hwnd, hdc); } void CColorPicker::OnLButtonDown(long x, long y) { //POINT pt; RECT rc; //pt.x = x; pt.y = y; //ClientToScreen(m_hwnd, &pt); GetClientRect(m_hwnd, &rc); //if (!PtInRect(&rc, pt)) if (x<rc.left || x>rc.right || y<rc.top || y>rc.bottom) PostMessage(m_hwnd, WM_CLOSE, 0, 0); else { m_bMouseDown = true; ReDraw(m_HotRow, m_HotCol, true); } }
void CColorPicker::OnLButtonUp(long x, long y) { m_bMouseDown = false; ReDraw(m_HotRow, m_HotCol, true); if (y>=5*18+10 && m_HotRow==5) { ShowWindow(m_hwnd, SW_HIDE); CColorDialog * crDlg = new CColorDialog(m_Color, CC_FULLOPEN | CC_ANYCOLOR); int nResult = crDlg->DoModal(); m_Color = crDlg->GetColor(); PostMessage(m_hwnd, WM_CLOSE, 0, 0); } else if (m_HotRow<5 && m_HotCol<8) { m_Color = ColorMap[m_HotRow][m_HotCol]; PostMessage(m_hwnd, WM_CLOSE, 0, 0); } }
void CColorPicker::OnMouseMove(long x, long y) {
RECT rc; GetClientRect(m_hwnd, &rc); InflateRect(&rc, -2, -2); if (x<rc.left || x>rc.right || y<rc.top || y>rc.bottom) { if (m_HotRow != 255) { ReDraw(m_HotRow, m_HotCol, false); m_HotRow = 255; } } else { if (y>=5*18+10) { if (m_HotRow != 5) { ReDraw(m_HotRow, m_HotCol, false); m_HotRow = 5; ReDraw(5, 0, true); } } else if (((byte)(y-2) / 18)!=m_HotRow || ((byte)(x-2) / 18)!=m_HotCol) { ReDraw(m_HotRow, m_HotCol, false); m_HotRow = (byte)(y-2) / 18; m_HotCol = (byte)(x-2) / 18; ReDraw(m_HotRow, m_HotCol, true); } } }
|