www.pudn.com > 44757463.rar > ColorSelect.cpp
#include "stdafx.h"
#include "ColorSelect.h"
#include "GraphSoftView.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define LPARAM_X(lp) ((int)(short)LOWORD(lp))
#define LPARAM_Y(lp) ((int)(short)HIWORD(lp))
#define WM_SETCOLOR WM_USER+1
#define WM_COLORDLG WM_USER+2
#define IDC_COLORDLG_BUTTON 100
/////////////////////////////////////////////////////////////////////////////
// CColorSelect
CColorSelect::CColorSelect()
{
int cxCursor = ::GetSystemMetrics(SM_CXCURSOR);
int cyCursor = ::GetSystemMetrics(SM_CYCURSOR);
m_hCursorStraw = NULL;
m_CurrentColor = RGB(0,0,0);
m_hPaletteWnd = NULL;
m_bPaletteWndActive = FALSE;
}
CColorSelect::~CColorSelect()
{
::DestroyCursor(m_hCursorStraw);
}
BEGIN_MESSAGE_MAP(CColorSelect, CButton)
//{{AFX_MSG_MAP(CColorSelect)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_SETCURSOR()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CColorSelect message handlers
void CColorSelect::OnLButtonDown(UINT nFlags, CPoint point)
{
// CButton::OnLButtonDown(nFlags, point);
if(m_rectSel.PtInRect(point))//如果点中的是右边箭头部分
{
::ClientToScreen(this->m_hWnd,&point);
if(CreatePaletteWindow())
{
nFlags = (UINT)m_CurrentColor;
::PostMessage(m_hPaletteWnd,WM_LBUTTONDOWN,nFlags,MAKELPARAM(point.x,point.y));
}
HWND hwndParent = GetParent()->m_hWnd;
if(hwndParent)
{
POINT p1,p2;
RECT rect;
::GetWindowRect(m_hWnd,&rect);
p1.x = rect.left;
p1.y = rect.top;
p2.x = rect.right;
p2.y = rect.bottom;
::ScreenToClient(hwndParent,&p1);
::ScreenToClient(hwndParent,&p2);
rect.left = p1.x;
rect.top = p1.y;
rect.right = p2.x;
rect.bottom = p2.y;
::InvalidateRect(hwndParent,&rect,TRUE);
}
}
else
{
//如果点中的是左边部分。。。
CPaintDC dc(this); // device context for painting
dc.DrawEdge(&m_rectFill,BDR_SUNKENINNER,BF_RECT);
}
}
void CColorSelect::OnLButtonUp(UINT nFlags, CPoint point)
{
if(NULL!=m_hPaletteWnd){
if((COLORREF)nFlags != m_CurrentColor){
SetColor((COLORREF)nFlags);
}
DestroyPaletteWindow();
}
Invalidate();
}
LONG FAR PASCAL CColorSelect::PaletteWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
POINT point;
CRect crtColorRect(5,87,50,103);
static POINT oldPoint;
static BOOL bMouseMoved = FALSE;
static HWND hwndParent;
static HWND hwndColorBtn;
static HFONT hFont = NULL;
static COLORREF crtColor,oldColor;
static int iActiveRect = -1;
CPen pen3DDKShadow(PS_SOLID,1,::GetSysColor(COLOR_3DDKSHADOW));
CPen penW(PS_SOLID,1,RGB(0xff,0xff,0xff));
CPen penB(PS_SOLID,1,RGB(0,0,0));
CRect rectColorBtn(135,90,151,106);
static int nDrawColorBtnFlag; //1----sunken
//2----raised
switch(nMsg)
{
case WM_CREATE:
{
hwndParent = ((LPCREATESTRUCT)lParam)->hwndParent;
crtColor = ::GetSysColor(COLOR_3DFACE);
LOGFONT logFont;
ZeroMemory((void*)&logFont,sizeof(logFont));
strcpy(logFont.lfFaceName,"宋体");
logFont.lfHeight = -12;
logFont.lfWeight = 400;
logFont.lfCharSet = GB2312_CHARSET;
logFont.lfOutPrecision = 3;
logFont.lfClipPrecision = 2;
logFont.lfQuality = 1;
logFont.lfPitchAndFamily = 2;
hFont = ::CreateFontIndirect(&logFont);
////色彩对话框按钮
hwndColorBtn = ::CreateWindow("BUTTON","",WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,rectColorBtn.left ,rectColorBtn.top,rectColorBtn.Width(),rectColorBtn.Height(),hWnd,HMENU(IDC_COLORDLG_BUTTON),::AfxGetInstanceHandle(),NULL);
if(hwndColorBtn)
::ShowWindow(hwndColorBtn,SW_SHOW);
nDrawColorBtnFlag=1;
}
break;
case WM_DESTROY:
::DeleteObject(hFont);
break;
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam;
if(lpDis->CtlID == IDC_COLORDLG_BUTTON)
{
CRect rect=lpDis->rcItem;
::FillRect(lpDis->hDC,&rect,(HBRUSH)::GetStockObject(BLACK_BRUSH));
::Rectangle(lpDis->hDC,rect.left+1,rect.top+1,rect.right-1,rect.bottom-1);
::SetBkColor(lpDis->hDC, RGB(0xff,0,0));
::ExtTextOut(lpDis->hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
rect.left+=4;
rect.top+=4;
::Rectangle(lpDis->hDC,rect.left+1,rect.top+1,rect.right-1,rect.bottom-1);
::SetBkColor(lpDis->hDC, RGB(0,0xff,0));
::ExtTextOut(lpDis->hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
rect.left+=4;
rect.top+=4;
::Rectangle(lpDis->hDC,rect.left+1,rect.top+1,rect.right-1,rect.bottom-1);
::SetBkColor(lpDis->hDC, RGB(0,0,0xff));
::ExtTextOut(lpDis->hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
rect=lpDis->rcItem;
//::DrawEdge(lpDis->hDC,&rect,BDR_RAISEDINNER,BF_RECT);
}
}
break;
case WM_SETCOLOR:
crtColor = (COLORREF)wParam;
oldColor = crtColor;
break;
case WM_COMMAND:
::PostMessage(hwndParent,WM_COLORDLG,NULL,NULL);
break;
case WM_MOUSEMOVE:
{
BOOL bInCtrlArea = FALSE;
point.x = LPARAM_X(lParam);
point.y = LPARAM_Y(lParam);
::ClientToScreen(hWnd,&point);
HWND hwndPoint = ::WindowFromPoint(point);
//::ScreenToClient(hWnd,&point);
//{
// if(hwndPoint==hwndColorBtn){// &&nDrawColorBtnFlag==2
// HDC hDC;
// hDC = ::GetWindowDC(hwndPoint);
// CRect rect(0,0,16,16);
// ::DrawEdge(hDC,&rect,BDR_SUNKENINNER,BF_RECT);
// nDrawColorBtnFlag=1;
// TRACE("hwndColorBtn:%d\n",hwndColorBtn);
// }else if(hwndPoint==hWnd&&nDrawColorBtnFlag!=1&&rectColorBtn.PtInRect(point)){
// HDC hDC;
// hDC = ::GetWindowDC(hwndPoint);
// ::DrawEdge(hDC,&rectColorBtn,BDR_SUNKENINNER,BF_RECT);
// nDrawColorBtnFlag=1;
// TRACE("hwndColorBtn:%d\n",hwndColorBtn);
// }else if(hwndPoint==hWnd&&nDrawColorBtnFlag==1){
// HDC hDC;
// hDC = ::GetWindowDC(hwndPoint);
// ::DrawEdge(hDC,&rectColorBtn,BDR_RAISEDINNER,BF_RECT);
// nDrawColorBtnFlag=2;
// }
// TRACE("hwndpoind :%d, hwndParent:%d,hwndColorBtn:%d\n",hwndPoint,hWnd,hwndColorBtn);
//}
//::ClientToScreen(hWnd,&point);
if(point.x != oldPoint.x || point.y != oldPoint.y)
{
bMouseMoved = TRUE;
if(hwndPoint)
{
COLORREF crtTMPColor;
CRect rect;
HDC hDC;
hDC = ::GetWindowDC(hwndPoint);
::GetWindowRect(hwndPoint,&rect);
int i=0,j=0;
i=(point.x-rect.left)/20;
j=(point.y-rect.top)/10;
crtTMPColor = GetPixel(hDC,i*20 + 5,j*10+5);
::ReleaseDC(hWnd,hDC);
RECT redrawRect;
redrawRect.left = 0;
redrawRect.right = 160;
redrawRect.top = 80;
redrawRect.bottom = 110;
::GetWindowRect(hWnd,&rect);
rect.bottom = rect.top + 80;
int iCurrentActiveRect;
//
if(rect.PtInRect(point))///判断鼠标是否在当前窗口的色彩区域
{
////计算位于哪个方框内////
point.x -= rect.left;
point.y -= rect.top;
if(point.x%20 != 0 && point.y%10 != 0)
iCurrentActiveRect = point.y/10*8 + point.x/20;
else
iCurrentActiveRect = -1;
}else{
iCurrentActiveRect = -1;
crtColor = oldColor;
if(hwndColorBtn == hwndPoint)
::ReleaseCapture();
else
bInCtrlArea = TRUE;
}
if(iCurrentActiveRect != iActiveRect)
{
///清除原焦点
CRect ActiveRect;
ActiveRect.left = iActiveRect%8*20;
ActiveRect.top = iActiveRect/8*10;
ActiveRect.right = ActiveRect.left + 20;
ActiveRect.bottom = ActiveRect.top + 10;
::InvalidateRect(hWnd,&ActiveRect,TRUE);
///新焦点
if(iCurrentActiveRect != -1)
{
crtColor = crtTMPColor;
ActiveRect.left = iCurrentActiveRect%8*20;
ActiveRect.top = iCurrentActiveRect/8*10;
ActiveRect.right = ActiveRect.left + 20;
ActiveRect.bottom = ActiveRect.top + 10;
::InvalidateRect(hWnd,&ActiveRect,TRUE);
}
::InvalidateRect(hWnd,&redrawRect,TRUE);
iActiveRect = iCurrentActiveRect;
}
}
}
if(bInCtrlArea)
::PostMessage(hwndParent,WM_SETCURSOR,NULL,MAKELPARAM(1,0));
else
::PostMessage(hwndParent,WM_SETCURSOR,NULL,NULL);
}
break;
case WM_ACTIVATE:
if(LOWORD(wParam) != WA_INACTIVE)
break;
case WM_LBUTTONUP:
point.x = LPARAM_X(lParam);
point.y = LPARAM_Y(lParam);
if(bMouseMoved || ( point.x == oldPoint.x && point.y == oldPoint.y ))
::PostMessage(hwndParent,WM_LBUTTONUP,(UINT)crtColor,lParam);
break;
case WM_LBUTTONDOWN:
oldPoint.x = LPARAM_X(lParam);
oldPoint.y = LPARAM_Y(lParam);
bMouseMoved = FALSE;
::InvalidateRect(hWnd,&crtColorRect,TRUE);
break;
case WM_ERASEBKGND:
{
hDC = (HDC)wParam;
HPEN oldPen = (HPEN)::SelectObject(hDC,penB);
for(int i=0;i<=8;i++)
{
::MoveToEx(hDC,i*20,0,NULL);
::LineTo(hDC,i*20,80);
}
for(i=0;i<=8;i++)
{
::MoveToEx(hDC,0,i*10,NULL);
::LineTo(hDC,160,i*10);
}
CRect btmRect(0,80,160,110);
::FillRect(hDC,btmRect,(HBRUSH)::GetStockObject(LTGRAY_BRUSH));
::Rectangle(hDC,crtColorRect.left-1,crtColorRect.top-1,crtColorRect.right + 1,crtColorRect.bottom + 1);
::SelectObject(hDC,oldPen);
}
break;
case WM_PAINT:
{
hDC = ::BeginPaint(hWnd,&ps);
CDC dc;
dc.Attach(hDC);
CRect rect;
int x1,y1,i,j,k;
UCHAR R=0,G=0,B=0;
//xgl 2004.3.11
//初始颜色的配置:分R,G,B三块,4*4为基元,先行后列,B 增加;基元内:R按行增加,G按列增加
for(j = 0;j < 8;j++)
for(i = 0;i < 8;i++)
{
x1 = j*20;
y1 = i*10;
//85=256/3;
R=85*(i%4);
G=85*(j%4);
B=((i/4)*2+j/4)*85;
rect.SetRect(x1,y1,x1+20,y1+10);
dc.FillSolidRect(rect,RGB(0,200,200));
rect.SetRect(x1+2,y1+1,x1+18,y1+9);
dc.FillSolidRect(rect,RGB(10,10,10));
rect.SetRect(x1+3,y1+2,x1+17,y1+8);
dc.FillSolidRect(rect,RGB(R,G,B));
}
if(iActiveRect != -1)
{
CRect ActiveRect;
ActiveRect.left = iActiveRect%8*20;
ActiveRect.top = iActiveRect/8*10;
ActiveRect.right = ActiveRect.left + 20;
ActiveRect.bottom = ActiveRect.top + 10;
dc.DrawFocusRect(ActiveRect);
}
rect.SetRect(0,81,160,82);
dc.FillSolidRect(rect,RGB(0,0,0));
rect.SetRect(0,82,160,110);
dc.FillSolidRect(rect,RGB(12,180,180));
dc.FillSolidRect(crtColorRect.left-2,crtColorRect.top-2,crtColorRect.Width()+4,crtColorRect.Height()+4,RGB(0,0,0));
dc.FillSolidRect(crtColorRect,crtColor);
char strColor[8]="#";
sprintf(strColor+1,"%02X%02X%02X",GetRValue(crtColor),GetGValue(crtColor),GetBValue(crtColor));
HFONT hOldFont = (HFONT)dc.SelectObject(hFont);
dc.SetBkMode(TRANSPARENT);
dc.TextOut(80,90,strColor,7);
dc.SelectObject(hOldFont);
dc.Detach();
::EndPaint(hWnd,&ps);
}
break;
default:
return(::DefWindowProc(hWnd,nMsg,wParam,lParam));
}
return NULL;
}
BOOL CColorSelect::CreatePaletteWindow()
{
if(!m_bPaletteWndActive)
{
// 创建调色板子窗口
WNDCLASS wndcls;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = PaletteWndProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = ::AfxGetInstanceHandle();
wndcls.hIcon = NULL;
wndcls.hCursor = NULL;
wndcls.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = "ColorPalette";
if (!::RegisterClass(&wndcls))
AfxThrowResourceException();
HDC hDC = ::GetDC(m_hWnd);
int scrWidth = ::GetDeviceCaps(hDC,HORZRES);
int scrHeight = ::GetDeviceCaps(hDC,VERTRES);
::ReleaseDC(m_hWnd,hDC);
CRect rect;
GetWindowRect(rect);
rect.top = rect.bottom - 1;
if(rect.left > scrWidth-160)
rect.left = scrWidth-160;
else if(rect.left < 0)
rect.left = 0;
if(rect.top > scrHeight-110)
rect.top = rect.top-110;
rect.bottom = rect.top + 110;
rect.right = rect.left + 160;
if(!(m_hPaletteWnd = ::CreateWindowEx(WS_EX_TOPMOST,"ColorPalette","Palatte",WS_POPUP|WS_BORDER|WS_VISIBLE,rect.left,rect.top,rect.Width(),rect.Height(),m_hWnd,NULL,wndcls.hInstance,NULL)))
return FALSE;
}
::PostMessage(m_hPaletteWnd,WM_SETCOLOR,(WPARAM)m_CurrentColor,NULL);
::ShowWindow(m_hPaletteWnd,SW_SHOW);
::SetCapture(m_hPaletteWnd);
m_bPaletteWndActive = TRUE;
return TRUE;
}
void CColorSelect::DestroyPaletteWindow()
{
::DestroyWindow(m_hPaletteWnd);
::UnregisterClass("ColorPalette",::AfxGetInstanceHandle());
m_bPaletteWndActive = FALSE;
m_hPaletteWnd = NULL;
}
BOOL CColorSelect::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(m_bPaletteWndActive && m_hCursorStraw && nHitTest != 1)
::SetCursor(m_hCursorStraw);
else
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
return TRUE;
}
void CColorSelect::GetColor(CString& strColor)
{
char cColor[8]="#";
sprintf(cColor+1,"%02X%02X%02X",GetRValue(m_CurrentColor),GetGValue(m_CurrentColor),GetBValue(m_CurrentColor));
strColor = cColor;
}
COLORREF CColorSelect::GetColor()
{
return m_CurrentColor;
}
LRESULT CColorSelect::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_COLORDLG)
{
DestroyPaletteWindow();
CColorDialog dlg;
//dlg.m_cc.Flags |= CC_FULLOPEN;
if(dlg.DoModal() == IDOK){
SetColor(dlg.GetColor());
}
return TRUE;
}
else
return CButton::DefWindowProc(message, wParam, lParam);
}
void CColorSelect::SetColor(COLORREF ref)
{
m_CurrentColor = ref;
((CGraphSoftView*)((CMainFrame*)AfxGetApp()->GetMainWnd())->GetActiveView())->m_clrCurrentColor=ref;
Invalidate();
}
void CColorSelect::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
//xiagl@fnst 2004.3.10(add_start)
//Draw the left half of ColorPicker
dc.FillSolidRect(m_rectFill,RGB(((int)GetRValue(m_CurrentColor)+128)%256,((int)GetGValue(m_CurrentColor)+128)%256,((int)GetBValue(m_CurrentColor)+128)%256));
CPen pen1,*m_poldPen;
LOGBRUSH m_logbr1;
m_logbr1.lbStyle=BS_SOLID;
m_logbr1.lbColor=m_CurrentColor;
pen1.CreatePen(PS_GEOMETRIC, m_rectFill.Height()/8, &m_logbr1);
m_poldPen=dc.SelectObject(&pen1);
dc.MoveTo(m_rectFill.left+m_rectFill.Width()/8,m_rectFill.top+m_rectFill.Height()*7/8);
dc.LineTo(m_rectFill.Width()/2,m_rectFill.top+m_rectFill.Height()/8);
dc.LineTo(m_rectFill.left+m_rectFill.Width()*7/8,m_rectFill.top+m_rectFill.Height()*7/8);
dc.LineTo(m_rectFill.left+m_rectFill.Width()*7/8-2,m_rectFill.top+m_rectFill.Height()*7/8-2);
dc.MoveTo(m_rectFill.left+m_rectFill.Width()*5/16,m_rectFill.top+m_rectFill.Height()/2);
dc.LineTo(m_rectFill.left+m_rectFill.Width()*11/16,m_rectFill.top+m_rectFill.Height()/2);
dc.SelectObject(m_poldPen);
//Draw the right half of ColorPicker
CPoint points[3];
points[0].x=m_rectSel.left+m_rectSel.Width()*1.0/4;
points[0].y=m_rectSel.Height()*0.5;
points[1].x=m_rectSel.left+m_rectSel.Width()*1.0/2;
points[1].y=m_rectSel.Height()*0.7;
points[2].x=m_rectSel.left+m_rectSel.Width()*3.0/4+1;
points[2].y=m_rectSel.Height()*0.5;
CRgn rgn;
rgn.CreatePolygonRgn(points,3,1);
CBrush brush,*p_oldbr;
brush.CreateSolidBrush(RGB(0,0,0));
p_oldbr=dc.SelectObject(&brush);
dc.FillRgn(&rgn,&brush);
dc.SelectObject(p_oldbr);
//xiagl@fnst 2004.3.10(add_start)
// Do not call CButton::OnPaint() for painting messages
}
void CColorSelect::SetFillRect(CRect rect)
{
this->m_rectFill.left=rect.left;
this->m_rectFill.right=rect.right;
this->m_rectFill.top=rect.top;
this->m_rectFill.bottom=rect.bottom;
}
void CColorSelect::SetFillRect(int left,int top,int right,int bottom)
{
this->m_rectFill.left=left;
this->m_rectFill.right=right;
this->m_rectFill.top=top;
this->m_rectFill.bottom=bottom;
}
CRect CColorSelect::GetFillRect()
{
return this->m_rectFill;
}
void CColorSelect::SetSelRect(CRect rect)
{
this->m_rectSel.left=rect.left;
this->m_rectSel.right=rect.right;
this->m_rectSel.top=rect.top;
this->m_rectSel.bottom=rect.bottom;
}
void CColorSelect::SetSelRect(int left,int top,int right,int bottom)
{
this->m_rectSel.left=left;
this->m_rectSel.right=right;
this->m_rectSel.top=top;
this->m_rectSel.bottom=bottom;
}
CRect CColorSelect::GetSelRect()
{
return this->m_rectSel;
}
void CColorSelect::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
_TrackMouseEvent(&tme);
CClientDC dc(this);
if(m_rectFill.PtInRect(point)){
dc.DrawEdge(&m_rectFill,BDR_RAISEDINNER,BF_RECT);
dc.DrawEdge(&m_rectSel,BDR_RAISEDINNER,BF_RECT);
}else if(m_rectSel.PtInRect(point)){
dc.DrawEdge(&m_rectFill,BDR_RAISEDINNER,BF_RECT);
dc.DrawEdge(&m_rectSel,BDR_RAISEDINNER,BF_RECT);
}
CButton::OnMouseMove(nFlags, point);
}
LRESULT CColorSelect::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
HWND hwndParent = GetParent()->m_hWnd;
if(hwndParent)
{
POINT p1,p2;
RECT rect;
::GetWindowRect(m_hWnd,&rect);
p1.x = rect.left;
p1.y = rect.top;
p2.x = rect.right;
p2.y = rect.bottom;
::ScreenToClient(hwndParent,&p1);
::ScreenToClient(hwndParent,&p2);
rect.left = p1.x;
rect.top = p1.y;
rect.right = p2.x;
rect.bottom = p2.y;
::InvalidateRect(hwndParent,&rect,TRUE);
}
return 0;
}
LRESULT CColorSelect::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
return 0;
}
void CColorSelect::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//CButton::OnLButtonDblClk(nFlags, point);
}