C++作的仿Office风格的颜色选取框

 

 

用VC写了个颜色选取框,仿Office风格,没用MFC什么的框架,调用很简单指定显示位置POINT和默认颜色就可以 ,如:
POINT pt;
pt.x = 100; pt.y = 100;
CColorPicker *clrpk = new CColorPicker(&pt, HexClr(0xFF0000));

效果图:
C++作的仿Office风格的颜色选取框_第1张图片

代码:
ColorPicker.h

#define  HexClr(rgb) ((DWORD)(rgb>>16)|(rgb&0xFF00)|((rgb&0xFF)<<16))
#define  COLORPICKERWINNAME "ColorPickerWin"
#define  WM_COLORSELECTED WM_USER+2938

static  DWORD ColorMap[ 5 ][ 8 =  
{
    
{ HexClr(0x000000), HexClr(0x993300), HexClr(0x333300), HexClr(0x003300), HexClr(0x003366), HexClr(0x000080), HexClr(0x333399), HexClr(0x333333)},
    
{ HexClr(0x800000), HexClr(0xFF6600), HexClr(0x808000), HexClr(0x008000), HexClr(0x008080), HexClr(0x0000FF), HexClr(0x666699), HexClr(0x808080)},
    
{ HexClr(0xFF0000), HexClr(0xFF9900), HexClr(0x99CC00), HexClr(0x008080), HexClr(0x33CCCC), HexClr(0x3366FF), HexClr(0x800080), HexClr(0x999999)},
    
{ HexClr(0xFF00FF), HexClr(0xFFCC00), HexClr(0xFFFF00), HexClr(0x00FF00), HexClr(0x00FFFF), HexClr(0x00CCFF), HexClr(0x993366), HexClr(0xC0C0C0)},
    
{ HexClr(0xFF99CC), HexClr(0xFFCC99), HexClr(0xFFFF99), HexClr(0xCCFFCC), HexClr(0xCCFFFF), HexClr(0x99CCFF), HexClr(0xCC99FF), HexClr(0xFFFFFF)}
}
;

class  CColorPicker
{
public:
    HINSTANCE m_hInstance;  
//debug
    CColorPicker(POINT *pt, DWORD DefaultColor);
    
~CColorPicker();
    HWND GetHwnd();
    DWORD GetColor();
    
void OnPaint();
    
void OnLButtonDown(long x, long y);
    
void OnLButtonUp(long x, long y);
    
void OnMouseMove(long x, long y);
private:
    HWND m_hwnd;
    DWORD m_Color;
    
byte m_HotRow, m_HotCol;
    
bool m_bCustomColor;
    
bool m_bMouseDown;
    
void CreateColorPicker(POINT *pt);
    
void Draw(HDC hdc, byte row, byte col, bool hot, byte correction);
    
void ReDraw(byte row, byte col, bool hot);
}
;
ColorPicker.cpp
#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
  BLOG:  http://blog.csdn.net/nhconch
  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, 
00);
            
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, 0sizeof(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+121260, 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, 
false1);
            
if (m_Color == ColorMap[i][j]) m_bCustomColor = false;
        }


    
//绘自定义文字
    Draw(hdc, 50, m_HotRow==51);

    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(-12000400000, 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, 
00);
    
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, 
00);
    }

    
else if (m_HotRow<5 && m_HotCol<8)
    
{
        m_Color 
= ColorMap[m_HotRow][m_HotCol];
        PostMessage(m_hwnd, WM_CLOSE, 
00);
    }

}


void  CColorPicker::OnMouseMove( long  x,  long  y)
{
//作者:  彭国辉   2007-12-25 http://blog.csdn.net/nhconch
    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(
50true);
            }

        }

        
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);
        }

    }

}

你可能感兴趣的:(C++,null,Office,mfc,byte,border)