// ButtonXP.cpp: implementation of the CButtonXP class. // ////////////////////////////////////////////////////////////////////// /**************以下设置必需包含在每个子类中**********************/ //头部 //////////////////////////////////////////////////////////////////////////////////////////////////// // 编译预处理 #if _WIN32_WINNT < 0x0400 #define _WIN32_WINNT 0x0400 #endif // 强制使用 C 语言方式编译 #ifdef __cplusplus extern "C" { #endif // __cplusplus #include "ButtonXP.h" ////////////////////////////////////////////////////////////////////////////////////////////////// // 全局变量 extern HHOOK g_hPrevHookXP ; // 窗口消息 HOOK 句柄 extern PCLASSXP g_pClassXP ; // 窗口的 CLASSXP 结构指针 extern COLORREF g_crDialogbkColor; // 窗口背景颜色 //各颜色均为全局变量 //gChecks:CheckBox和RadioBox共用, 禁止时画白刷 //CheckBox:0=CXPS_PRESSED 1=CXPS_HOTLIGHT 2=正常 //RadioBox:0=CXPS_PRESSED 1=CXPS_HOTLIGHT 3=选中 static COLORREF gChecks_crGradientXP[][4] = { {0x00A5B2B5, 0x00CED7D6, 0x00CED7D6, 0x00DEEFF7}, {0x00CEF3FF, 0x0063CBFF, 0x0063CBFF, 0x0031B2FF}, {0x00D6DFDE, 0x00EFF3F7, 0x00EFF3F7, 0x00FFFFFF}, {0x0021A221, 0x0021A221, 0x00187A18, 0x00187A18}, }; //按钮 0=PRESSED 1=HOTLIGHT 2=正常 3=禁止 4=其它 /* static COLORREF gButtons_crGradientXP[][4] = { {RGB( 220, 214, 194 ), RGB( 245, 244, 235 ), 0,0}, {RGB( 255, 255, 255 ), RGB( 226, 223, 214 ), 0, 0}, {RGB( 252, 252, 251 ), RGB( 236, 235, 230 ), 0, 0}, }; COLORREF bkColorStart = ; COLORREF bkColorEnd = ; COLORREF FaceColorStart = ; COLORREF FaceColorEnd = ; COLORREF TextColorStart = ; COLORREF TextColorEnd = ; */ ////////////////////////////////////////////////////////////// /****************************************************************/ //按钮设置转成文本设置 UINT ButtonStyle2Format(DWORD style) { UINT uFormat = 0; if((style & BS_MULTILINE) != BS_MULTILINE) uFormat |= DT_SINGLELINE; if((style & BS_TOP) == BS_TOP) uFormat |= DT_TOP; else if((style & BS_BOTTOM) == BS_BOTTOM) uFormat |= DT_BOTTOM; else uFormat |= DT_VCENTER | DT_SINGLELINE; if((style & BS_LEFT) == BS_LEFT) uFormat |= DT_LEFT; else if((style & BS_RIGHT) == BS_RIGHT) uFormat |= DT_RIGHT; else uFormat |= DT_CENTER; uFormat |= DT_END_ELLIPSIS; return uFormat; } ///////////////////////////////////////////////////////////// //设置图标 LRESULT ButtonOnSetIcon(PCLASSXP pCxp, WPARAM wParam, LPARAM lParam) { //生成灰度禁止图标 if (pCxp->hIconDisabled) DeleteObject(pCxp->hIconDisabled); pCxp->hIconDisabled =(HICON)CopyImage((HICON)lParam, IMAGE_ICON, 0,0,LR_MONOCHROME|LR_COPYRETURNORG); //设置使能图标 LRESULT nRet = CallWindowProc(pCxp->wpPrev, pCxp->hWnd, WM_SETICON, wParam, lParam); // if(IsWindow(pCxp->hWnd)) // 重画窗口 // RedrawWindow(pCxp->hWnd, NULL, NULL,RDW_UPDATENOW|RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ERASENOW); return nRet; } //////////////////////////////////////////////// //绘制按钮2 /* VOID WINAPI ButtonDrawPushButtonXP(PCLASSXP pCxp) { RECT Rect, rc; MEMDCXP Mdcxp; HBRUSH hBrush; HANDLE hHandle; DWORD dwStyle; DWORD pID = NULL; HPEN pen1, pen2, pen3, pen4; int nSaveDC; TRIVERTEX vert[2] ; GRADIENT_RECT gRect; COLORREF bkColorStart = RGB( 220, 214, 194 ); COLORREF bkColorEnd = RGB( 245, 244, 235 ); COLORREF FaceColorStart = RGB( 255, 255, 255 ); COLORREF FaceColorEnd = RGB( 226, 223, 214 ); COLORREF TextColorStart = RGB( 252, 252, 251 ); COLORREF TextColorEnd = RGB( 236, 235, 230 ); // 获取内存兼容设备场景 Mdcxp.hWnd = pCxp->hWnd; Mdcxp.bTransfer = FALSE; Mdcxp.hBitmap = NULL; GetMemDCXP(&Mdcxp); // 获取窗口大小 GetWindowRect(pCxp->hWnd, &Rect); Rect.right -= Rect.left; Rect.bottom -= Rect.top; Rect.left = Rect.top = 0; rc = Rect; pen1 = CreatePen( PS_SOLID, 0, RGB(226, 222, 203) ); // 最左边的一条竖线 pen2 = CreatePen( PS_SOLID, 0, RGB(248, 247, 242) ); // 最底部的一条横线 nSaveDC = SaveDC(Mdcxp.hMemDC); dwStyle = (DWORD)GetWindowLong(pCxp->hWnd, GWL_STYLE); if (pCxp->dwState & CXPS_DISABLED) { pen3= CreatePen( PS_SOLID, 0, RGB(216, 213, 199) ); // 圆角矩形(4,4) pen4= CreatePen( PS_SOLID, 0, RGB(201, 199, 186) ); // 圆角矩形(6,6) } else { pen3 = CreatePen( PS_SOLID, 0, RGB(122, 149, 168) ); // 圆角矩形(4,4) pen4 = CreatePen( PS_SOLID, 0, RGB(0, 60, 116) ); // 圆角矩形(6,6) } // bkColor = GetPixel(GetDC(pCxp->hWnd), rc.right-1, rc.top ); // nSaveDC = SaveDC(Mdcxp.hMemDC); //背景色填充 hBrush = CreateSolidBrush(g_crDialogbkColor); SelectObject(Mdcxp.hMemDC, hBrush); FillRect(Mdcxp.hMemDC, &rc, (HBRUSH)hBrush); DeleteObject(hBrush); //空的背景色 SelectObject(Mdcxp.hMemDC, GetStockObject(NULL_BRUSH)); // 画最左边的一条竖线和最底部的一条横线 if (!(pCxp->dwState & CXPS_DISABLED)) { SelectObject(Mdcxp.hMemDC , pen1); MoveToEx(Mdcxp.hMemDC, rc.left, rc.top+1,NULL); LineTo(Mdcxp.hMemDC, rc.left, rc.bottom-1 ); SelectObject(Mdcxp.hMemDC, pen2 ); MoveToEx(Mdcxp.hMemDC, rc.left+2, rc.bottom-1, NULL); LineTo(Mdcxp.hMemDC, rc.right-1, rc.bottom-1 ); } // 画最底层背景 vert [0].y = Rect.top; vert [0].x = Rect.left+1; vert [0].Red = ((COLOR16)GetRValue( bkColorStart )) << 8; vert [0].Green = ((COLOR16)GetGValue( bkColorStart ))<< 8; vert [0].Blue = ((COLOR16)GetBValue( bkColorStart )) << 8; vert [0].Alpha = 0x0000; vert [1].y = Rect.bottom-1; vert [1].x = Rect.right; vert [1].Red = ((COLOR16)GetRValue( bkColorEnd )) << 8; vert [1].Green = ((COLOR16)GetGValue( bkColorEnd )) << 8; vert [1].Blue = ((COLOR16)GetBValue( bkColorEnd )) << 8; vert [1].Alpha = 0xFF00; gRect.UpperLeft = 0; gRect.LowerRight = 1; if (!(pCxp->dwState & CXPS_DISABLED)) GradientFill(Mdcxp.hMemDC , vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V ); // 如果有焦点 if ((pCxp->dwState & CXPS_FOCUS)|| (pCxp->dwState & CXPS_DEFAULT)) { FaceColorStart = RGB(235, 160, 5 ); FaceColorEnd = RGB( 251, 192, 73 ); //平面充型 if(dwStyle & BS_FLAT) { TextColorStart = RGB( 251, 192, 73 ); TextColorEnd = RGB(235, 160, 5 ); } Rect = rc; Rect.left += 2; } // 如果是高亮 if (pCxp->dwState & CXPS_HOTLIGHT) { FaceColorStart = RGB( 255, 240, 207 ); FaceColorEnd = RGB( 229, 151, 0 ); Rect = rc; Rect.left += 2; } // 如果被按下 if (pCxp->dwState & CXPS_PRESSED) { FaceColorStart = RGB( 209, 204, 193 ); FaceColorEnd = RGB( 242, 241, 238 ); TextColorStart = RGB( 229, 228, 221 ); TextColorEnd = RGB( 226, 226, 218 ); Rect = rc; Rect.left += 2; } // 如果被禁止 if (pCxp->dwState & CXPS_DISABLED) { FaceColorStart = RGB( 245, 244, 234 ); FaceColorEnd = FaceColorStart; TextColorStart = FaceColorStart; TextColorEnd = FaceColorStart; Rect = rc; Rect.left += 2; } // 画 BUTTON 内部所有区域背景 vert [0].y = rc.top + 2; vert [0].x = rc.left + 2; vert [0].Red = ((COLOR16)GetRValue( FaceColorStart )) << 8; vert [0].Green = ((COLOR16) GetGValue( FaceColorStart)) << 8; vert [0].Blue = ((COLOR16) GetBValue( FaceColorStart)) << 8; vert [1].y = rc.bottom - 2 ; vert [1].x = rc.right - 2; vert [1].Red = ((COLOR16) GetRValue( FaceColorEnd )) << 8; vert [1].Green = ((COLOR16) GetGValue( FaceColorEnd )) << 8; vert [1].Blue = ((COLOR16) GetBValue( FaceColorEnd )) << 8; GradientFill(Mdcxp.hMemDC , vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V ); // 画 BUTTON 内部有效区域背景 vert [0].y = Rect.top + 4; vert [0].x = Rect.left + 2; vert [0].Red = ((COLOR16) GetRValue( TextColorStart )) << 8; vert [0].Green = ((COLOR16) GetGValue( TextColorStart )) << 8; vert [0].Blue = ((COLOR16) GetBValue( TextColorStart )) << 8; vert [1].y = Rect.bottom - 4; vert [1].x = Rect.right - 4; vert [1].Red = ((COLOR16) GetRValue( TextColorEnd )) << 8 ; vert [1].Green = ((COLOR16) GetGValue( TextColorEnd )) << 8 ; vert [1].Blue = ((COLOR16) GetBValue( TextColorEnd )) << 8 ; GradientFill(Mdcxp.hMemDC , vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V ); // 如果有焦点 if (pCxp->dwState & CXPS_FOCUS) { Rect = rc; InflateRect(&Rect, -3, -3); DrawFocusRect(Mdcxp.hMemDC, &Rect); } // 画椭圆形外框 Rect = rc; InflateRect(&Rect, -1, -1); //Rect.DeflateRect( 1, 1 ); hHandle = SelectObject(Mdcxp.hMemDC, pen3); RoundRect(Mdcxp.hMemDC, Rect.left, Rect.top , Rect.right , Rect.bottom , 4,4 ); hHandle = SelectObject(Mdcxp.hMemDC, pen4); RoundRect(Mdcxp.hMemDC, Rect.left, Rect.top , Rect.right , Rect.bottom , 6,6); // 去除右上角的多余点 SetPixel(Mdcxp.hMemDC, rc.right-1, rc.top, g_crDialogbkColor); ButtonDrawPushText(pCxp,Mdcxp.hMemDC,rc); RestoreDC(Mdcxp.hMemDC, nSaveDC ); DeleteObject(pen1); DeleteObject(pen2); DeleteObject(pen3); DeleteObject(pen4); Mdcxp.bTransfer = TRUE; ReleaseMemDCXP(&Mdcxp); } // End of OnDrawBackground */ //////////////////////////////////////////////////////////////////////////////////////////////////// // 绘制按钮文本 VOID WINAPI ButtonDrawPushText(PCLASSXP pCxp, HDC hDC, RECT rc) { RECT rcIcon, rcText; HANDLE hHandle; char szTemp[256]; HICON hIcon; DWORD dwStyle;//, pID = NULL; ICONINFO piconinfo; UINT uFormat; dwStyle = (DWORD)GetWindowLong(pCxp->hWnd, GWL_STYLE); //新增画图标 if (pCxp->dwState & CXPS_DISABLED) hIcon = pCxp->hIconDisabled; else hIcon =(HICON) SendMessage(pCxp->hWnd, WM_GETICON, ICON_SMALL, 0); rcText = rc; if (hIcon)//有图标 { GetIconInfo(hIcon,&piconinfo); //取图标信息 rcIcon = rc; if (dwStyle & BS_TOP) //文字置顶 { //rcIcon.left = rc.left + (rc.right - rc.left)/2 - piconinfo.xHotspot; rcIcon.top = rc.bottom - piconinfo.yHotspot*2 - 4; rcText.bottom -= piconinfo.yHotspot*2 ; } else if (dwStyle & BS_VCENTER)//文字置中 { //rcIcon.left = rc.left + (rc.right - rc.left)/2 - piconinfo.xHotspot; rcIcon.top = (rc.bottom-rc.top)/2-piconinfo.yHotspot; //rcText.top += piconinfo.yHotspot*2 ; } else //if(dwStyle & BS_BOTTOM)//文字置底 { //rcIcon.left = rc.left + (rc.right - rc.left)/2 - piconinfo.xHotspot; rcIcon.top = rc.top+4; rcText.top += piconinfo.yHotspot*2 + 4; } if (dwStyle & BS_RIGHT) //文字置右 { rcIcon.left = 4; //rcIcon.top = Rect.top+2; rcText.left += piconinfo.yHotspot*2 + 2; } else if(dwStyle & BS_LEFT)//文字置左 { rcIcon.left = rc.right - (piconinfo.yHotspot*2 + 4); //rcIcon.top = Rect.top+2; rcText.right -= (piconinfo.yHotspot*2 + 2); } else { rcIcon.left = (rc.right - rc.left)/2-piconinfo.yHotspot + 2; //rcIcon.top = Rect.top+2; //rcText.right -= (piconinfo.yHotspot*2 + 2); } DrawIcon(hDC, rcIcon.left,rcIcon.top, hIcon); } // 画文字 uFormat = ButtonStyle2Format(dwStyle); if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp))) { if (pCxp->dwState & CXPS_PRESSED) OffsetRect(&rcText, 1, 1); SetTextColor(hDC, ((pCxp->dwState & CXPS_INDETERMINATE) || (pCxp->dwState & CXPS_DISABLED)) ? 0x0094A2A5: 0x00000000); hHandle = (HANDLE) SelectObject(hDC, (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0)); //DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER); DrawText(hDC, szTemp, -1, &rcText, uFormat); SelectObject(hDC, (HGDIOBJ) hHandle); } } //////////////////////////////////////////////////////////////////////////////////////////////////// // 绘制按钮1 VOID WINAPI ButtonDrawPushButtonXP(PCLASSXP pCxp) { int i; RECT Rect, rc; MEMDCXP Mdcxp; HANDLE hHandle; COLORREF crColor; HDC hDC; static COLORREF s_crGradientXP[][4] = { {0x00C1CCD1, 0x00C1CCD1, 0x00EEF1F2, 0xFFEEF1F2}, {0x00CFF0FF, 0x00CFF0FF, 0x000097E5, 0xFF0097E5}, {0x00BDCBD6, 0x00C6CFD6, 0x00EFF3F7, 0xFFEFF3F7}, {0x00FFE7CE, 0x00FFE7CE, 0x00EE8269, 0xFFEE8269}, {0x00FFFFFF, 0x00FFFFFF, 0x00D6DFE2, 0xFFD6DFE2}, {0x00DEE3E7, 0x00E7E7E7, 0x00DEE3E7, 0xFFDEE3E7}, {0x00FBFCFC, 0x00FBFCFC, 0x00E6EBEC, 0xFFE6EBEC}, }; // 获取内存兼容设备场景 Mdcxp.hWnd = pCxp->hWnd; Mdcxp.bTransfer = FALSE; Mdcxp.hBitmap = NULL; GetMemDCXP(&Mdcxp); hDC = Mdcxp.hMemDC; // 获取窗口大小 GetWindowRect(pCxp->hWnd, &Rect); Rect.right -= Rect.left; Rect.bottom -= Rect.top; Rect.left = Rect.top = 0; rc = Rect; // 画最外面的框,颜色与系统按钮颜色一直 hHandle = (HANDLE) CreateSolidBrush(g_crDialogbkColor); FrameRect(hDC, &Rect, (HBRUSH) hHandle); DeleteObject((HGDIOBJ) hHandle); // 画最第二层边框 InflateRect(&Rect, -1, -1); hHandle = (HANDLE) CreateSolidBrush( (pCxp->dwState & CXPS_DISABLED) ? (g_crDialogbkColor - 0x00202020) : 0x00733C00); FrameRect(hDC, &Rect, (HBRUSH) hHandle); DeleteObject((HGDIOBJ) hHandle); // 画热点框渐变背景 InflateRect(&Rect, -1, -1); if (pCxp->dwState & CXPS_DISABLED) { i = -1; //hHandle = (HANDLE) CreateSolidBrush(0x00EAF4F5); hHandle = (HANDLE) CreateSolidBrush(g_crDialogbkColor); FillRect(hDC, &Rect, (HBRUSH) hHandle); DeleteObject((HGDIOBJ) hHandle); } else { if (pCxp->dwState & CXPS_PRESSED) i = 0; else if (pCxp->dwState & CXPS_HOTLIGHT) i = 1; else if ((pCxp->dwState & CXPS_CHECKED) || (pCxp->dwState & CXPS_INDETERMINATE)) i = 2; else if ((pCxp->dwState & CXPS_FOCUS) || (pCxp->dwState & CXPS_DEFAULT)) i = 3; else i = 4; GradientRectXP(hDC, &Rect, s_crGradientXP[i]); } // 画文字区域渐变背景 InflateRect(&Rect, -2, -2); if ((pCxp->dwState & CXPS_PRESSED) || (pCxp->dwState & CXPS_CHECKED) || (pCxp->dwState & CXPS_INDETERMINATE)) i = 5; else if (!(pCxp->dwState & CXPS_DISABLED)) i = 6; if ((i == 5) || (i == 6)) GradientRectXP(hDC, &Rect, s_crGradientXP[i]); // 用与系统按钮一直的颜色第二层边框的四角像素 // crColor = GetSysColor(COLOR_BTNFACE); crColor = g_crDialogbkColor; SetPixel(hDC, 1, 1, crColor); SetPixel(hDC, 1, Rect.bottom + 2, crColor); SetPixel(hDC, Rect.right + 2, Rect.bottom + 2, crColor); SetPixel(hDC, Rect.right + 2, 1, crColor); // 画第二层边框的拐角像素,太罗嗦了,千万别仔细看:) // crColor = (pCxp->dwState & CXPS_DISABLED) ? // (GetSysColor(COLOR_BTNFACE) - 0x00151515) : 0x00A57D52; crColor = (pCxp->dwState & CXPS_DISABLED) ? (g_crDialogbkColor - 0x00151515) : g_crDialogbkColor-0x00A57D52; SetPixel(hDC, 2, 2, crColor); SetPixel(hDC, 2, Rect.bottom + 1, crColor); SetPixel(hDC, Rect.right + 1, Rect.bottom + 1, crColor); SetPixel(hDC, Rect.right + 1, 2, crColor); // crColor = (pCxp->dwState & CXPS_DISABLED) ? // (GetSysColor(COLOR_BTNFACE) - 0x00111111) : 0x00AD967B; crColor = (pCxp->dwState & CXPS_DISABLED) ? (g_crDialogbkColor - 0x00111111) : g_crDialogbkColor-0x00AD967B; SetPixel(hDC, 1, 2, crColor); SetPixel(hDC, 2, 1, crColor); SetPixel(hDC, Rect.right + 1, 1, crColor); SetPixel(hDC, Rect.right + 2, 2, crColor); SetPixel(hDC, Rect.right + 1, Rect.bottom + 2, crColor); SetPixel(hDC, Rect.right + 2, Rect.bottom + 1, crColor); SetPixel(hDC, 2, Rect.bottom + 2, crColor); SetPixel(hDC, 1, Rect.bottom + 1, crColor); // 如果有焦点,画出焦点框 if (pCxp->dwState & CXPS_FOCUS) { InflateRect(&Rect, 1, 1); DrawFocusRect(hDC, &Rect); } ButtonDrawPushText(pCxp,hDC,rc); Mdcxp.bTransfer = TRUE; ReleaseMemDCXP(&Mdcxp); } //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // 绘制复选框 VOID WINAPI ButtonDrawCheckBoxXP(PCLASSXP pCxp) { int i; RECT Rect, rcText; MEMDCXP Mdcxp; HANDLE hHandle; char szTemp[256]; COLORREF crColor; DWORD dwStyle; HDC hDC; /* static COLORREF s_crGradientXP[][4] = { {0x00A5B2B5, 0x00CED7D6, 0x00CED7D6, 0x00DEEFF7}, {0x00CEF3FF, 0x0063CBFF, 0x0063CBFF, 0x0031B2FF}, {0x00D6DFDE, 0x00EFF3F7, 0x00EFF3F7, 0x00FFFFFF} }; */ // 获取内存兼容设备场景 Mdcxp.hWnd = pCxp->hWnd; Mdcxp.bTransfer = FALSE; Mdcxp.hBitmap = NULL; GetMemDCXP(&Mdcxp); hDC = Mdcxp.hMemDC; // 获取窗口大小 GetWindowRect(pCxp->hWnd, &Rect); Rect.right -= Rect.left; Rect.bottom -= Rect.top; Rect.left = Rect.top = 0; // 填充背景 // FillRect(hDC, &Rect, GetSysColorBrush(g_crDialogbkColor)); hHandle = CreateSolidBrush(g_crDialogbkColor); FillRect(hDC,&Rect, (HBRUSH)hHandle); DeleteObject(hHandle); //按显示模式调整位置 dwStyle = GetWindowLong(pCxp->hWnd, GWL_STYLE); if (dwStyle & BS_LEFTTEXT) { rcText = Rect; rcText.right -= 18; Rect.left = Rect.right - 13; Rect.top = (Rect.bottom - 13) / 2; Rect.bottom = Rect.top + 13; } else { rcText = Rect; rcText.left += 18; Rect.left = 0; Rect.right = 13; Rect.top = (Rect.bottom - 13) / 2; Rect.bottom = Rect.top + 13; } // 画最外面的框 hHandle = (HANDLE) CreateSolidBrush( (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00845118); FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle); DeleteObject((HGDIOBJ) hHandle); // 画热点框渐变背景 InflateRect(&Rect, -1, -1); if (!(pCxp->dwState & CXPS_DISABLED)) // FillRect(hDC, &Rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); // else { if (pCxp->dwState & CXPS_PRESSED) i = 0; else if (pCxp->dwState & CXPS_HOTLIGHT) i = 1; else i = 2; GradientRectXP(hDC, &Rect, gChecks_crGradientXP[i]); } // 画内框 InflateRect(&Rect, -2, -2); if ((pCxp->dwState & CXPS_INDETERMINATE) || ((pCxp->dwState & CXPS_HOTLIGHT) && (!(pCxp->dwState & CXPS_PRESSED)))) { if (pCxp->dwState & CXPS_INDETERMINATE) { if (pCxp->dwState & CXPS_DISABLED) crColor = 0x00BDCBCE; else if (pCxp->dwState & CXPS_PRESSED) crColor = 0x00188A18; else if (pCxp->dwState & CXPS_HOTLIGHT) crColor = 0x0021A221; else crColor = 0x0073C373; } else if (pCxp->dwState & CXPS_CHECKED) crColor = 0x00F7F7F7; else crColor = 0x00E7E7E7; hHandle = (HANDLE) CreateSolidBrush(crColor); FillRect(hDC, &Rect, (HBRUSH) hHandle); DeleteObject((HGDIOBJ) hHandle); } // 画框内选中标志 if (pCxp->dwState & CXPS_CHECKED) { hHandle = (HANDLE) SelectObject(hDC, CreatePen(PS_SOLID, 1, (pCxp->dwState & CXPS_DISABLED) ? 0x000BDCBCE : 0x0021A221)); for (i = 3; i < 10; i++) { MoveToEx(hDC, Rect.left+i-3, Rect.top + ((i < 6) ? i - 1 : (9 - i)), NULL); LineTo(hDC, Rect.left+i-3, Rect.top + ((i < 6) ? i + 2 : (12 - i))); } DeleteObject(SelectObject(hDC,(HGDIOBJ) hHandle)); } // 写文字 if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp))) { SetTextColor(hDC, GetSysColor((pCxp->dwState & CXPS_DISABLED) ? COLOR_GRAYTEXT: COLOR_BTNTEXT)); hHandle = (HANDLE) SelectObject(hDC, (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0)); rcText.bottom = rcText.top + 1 + DrawText(hDC, szTemp, -1, &rcText, DT_CALCRECT | DT_SINGLELINE | DT_VCENTER); DrawText(hDC, szTemp, -1, &rcText, DT_SINGLELINE | DT_VCENTER); SelectObject(hDC, (HGDIOBJ) hHandle); // 如果有焦点,画出焦点框 if (pCxp->dwState & CXPS_FOCUS) { InflateRect(&rcText, 0, -1); DrawFocusRect(hDC, &rcText); } } Mdcxp.bTransfer = TRUE; ReleaseMemDCXP(&Mdcxp); } //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // 绘制单选框 VOID WINAPI ButtonDrawRadioBoxXP(PCLASSXP pCxp) { RECT Rect,rc, rcText; MEMDCXP Mdcxp; HANDLE hHandle, hPen; char szTemp[256]; COLORREF crColor; DWORD dwStyle; // UINT uFormat; HDC hDC; /* static COLORREF s_crGradientXP[][4] = { {0x00A5B2B5, 0x00CED7D6, 0x00CED7D6, 0x00DEEFF7}, {0x00CEF3FF, 0x0063CBFF, 0x0063CBFF, 0x0031B2FF}, {0x00D6DFDE, 0x00EFF3F7, 0x00EFF3F7, 0x00FFFFFF}, {0x0021A221, 0x0021A221, 0x00187A18, 0x00187A18}, {0x00FFEBE7, 0x00F7CBAD, 0x00FF350B, 0x00F7CBAD}, }; */ // 获取内存兼容设备场景 Mdcxp.hWnd = pCxp->hWnd; Mdcxp.bTransfer = FALSE; Mdcxp.hBitmap = NULL; GetMemDCXP(&Mdcxp); hDC = Mdcxp.hMemDC; // 获取窗口大小 GetWindowRect(pCxp->hWnd, &Rect); Rect.right -= Rect.left; Rect.bottom -= Rect.top; Rect.left = Rect.top = 0; // 填充背景 // FillRect(hDC, &Rect, GetSysColorBrush(g_crDialogbkColor)); hHandle = CreateSolidBrush(g_crDialogbkColor); FillRect(hDC,&Rect, (HBRUSH)hHandle); DeleteObject(hHandle); //按显示模式调整位置 dwStyle = GetWindowLong(pCxp->hWnd, GWL_STYLE); if (dwStyle & BS_LEFTTEXT) { rcText = Rect; rcText.right -= 15; Rect.left = Rect.right-15; Rect.top = (Rect.bottom -15)/2; Rect.bottom = Rect.top + 15; rc = Rect; } else { rcText = Rect; rcText.left += 15; Rect.right = 15; Rect.top = (Rect.bottom -15)/2; Rect.bottom = Rect.top + 15; rc = Rect; } // 画热点框渐变背景 if (!(pCxp->dwState & CXPS_DISABLED)) // FillRect(hDC, &rc,(HBRUSH)GetStockObject(WHITE_BRUSH)); // else { if (pCxp->dwState & CXPS_PRESSED) GradientRectXP(hDC, &rc, gChecks_crGradientXP[0]); else if (pCxp->dwState & CXPS_HOTLIGHT) GradientRectXP(hDC, &rc, gChecks_crGradientXP[1]); } // 画内框 InflateRect(&rc, -2, -2); if ((pCxp->dwState & CXPS_INDETERMINATE) || ((pCxp->dwState & CXPS_HOTLIGHT) && (!(pCxp->dwState & CXPS_PRESSED)))) { if (pCxp->dwState & CXPS_INDETERMINATE) { if (pCxp->dwState & CXPS_DISABLED) crColor = 0x00BDCBCE; else if (pCxp->dwState & CXPS_PRESSED) crColor = 0x00188A18; else if (pCxp->dwState & CXPS_HOTLIGHT) crColor = 0x0021A221; else crColor = 0x0073C373; } else if (pCxp->dwState & CXPS_CHECKED) crColor = 0x00F7F7F7; else crColor = 0x00E7E7E7; hHandle = (HANDLE) CreateSolidBrush(crColor); FillRect(hDC, &rc, (HBRUSH) hHandle); DeleteObject((HGDIOBJ) hHandle); } //空的背景色 hHandle = SelectObject(hDC, GetStockObject(NULL_BRUSH)); // 画框内选中标志 if (pCxp->dwState & CXPS_CHECKED) { GradientRectXP(hDC, &rc, gChecks_crGradientXP[3]); hPen = SelectObject(hDC, CreatePen(PS_SOLID, 1, g_crDialogbkColor)); Ellipse(hDC, Rect.left+3, Rect.top+3,Rect.left+12,Rect.top+12); Ellipse(hDC, Rect.left+4, Rect.top+4,Rect.left+11,Rect.top+11); DeleteObject(SelectObject(hDC,hPen)); } //填充圆形背景色 if (!(pCxp->dwState & CXPS_HOTLIGHT)) { hPen = SelectObject(hDC,CreatePen(PS_SOLID, 3, g_crDialogbkColor)); Ellipse(hDC, Rect.left, Rect.top,Rect.left+14,Rect.top+14); DeleteObject(SelectObject(hDC,hPen)); } //画圆 hPen = SelectObject(hDC, CreatePen(PS_SOLID, 1, (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00845118)); Ellipse(hDC, Rect.left+2, Rect.top+2,Rect.left+13,Rect.top+13); DeleteObject(SelectObject(hDC,hPen)); //恢复背景色 SelectObject(hDC, hHandle); // 画文字 // uFormat = ButtonStyle2Format(dwStyle); if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp))) { SetTextColor(hDC, GetSysColor((pCxp->dwState & CXPS_DISABLED) ? COLOR_GRAYTEXT: COLOR_BTNTEXT)); hHandle = (HANDLE) SelectObject(hDC, (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0)); DrawText(hDC, szTemp, -1, &rcText, dwStyle); SelectObject(hDC, (HGDIOBJ) hHandle); // 如果有焦点,画出焦点框 if (pCxp->dwState & CXPS_FOCUS) { InflateRect(&rcText, -1, -1); DrawFocusRect(hDC, &rcText); } } //释放句柄 Mdcxp.bTransfer = TRUE; ReleaseMemDCXP(&Mdcxp); } //////////////////////////////////////////////// //绘制组合框 VOID WINAPI ButtonDrawGroupBoxXP(PCLASSXP pCxp) { RECT Rect; char szTemp[256]; HANDLE hHandle,hBrush; DWORD dwStyle; //取设置句柄 HDC hDC = GetWindowDC(pCxp->hWnd); // 获取窗口大小 GetWindowRect(pCxp->hWnd, &Rect); Rect.right -= Rect.left; Rect.bottom -= Rect.top; Rect.left = Rect.top = 0; // 画最外面的框,颜色与系统按钮颜色一直 hBrush = SelectObject(hDC, GetStockObject(NULL_BRUSH)); RoundRect(hDC, Rect.left,Rect.top+6,Rect.right,Rect.bottom, 6,6); SelectObject(hDC, hBrush); // 写文字 dwStyle = (DWORD)GetWindowLong(pCxp->hWnd, GWL_STYLE); if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp))) { SetTextColor(hDC, ((pCxp->dwState & CXPS_INDETERMINATE) || (pCxp->dwState & CXPS_DISABLED)) ? 0x0094A2A5: 0x00000000); hHandle = (HANDLE) SelectObject(hDC, (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0)); //DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER); Rect.left+=5; DrawText(hDC, szTemp, -1, &Rect, DT_LEFT); SelectObject(hDC, (HGDIOBJ) hHandle); } //释放句柄 ReleaseDC(pCxp->hWnd,hDC); } //////////////////////////////////////////////// //绘制说明条 VOID WINAPI ButtonDrawStateBoxXP(PCLASSXP pCxp) { HICON hIcon; // HBITMAP hBmp; RECT Rect; char szTemp[256]; HANDLE hHandle; DWORD dwStyle; int nSaveDC; HDC hDC = GetWindowDC(pCxp->hWnd); // 获取窗口大小 // GetWindowRect(pCxp->hWnd, &Rect); // Rect.right -= Rect.left; // Rect.bottom -= Rect.top; // Rect.left = Rect.top = 0; nSaveDC = SaveDC(hDC); // 画文字 dwStyle = (DWORD)GetWindowLong(pCxp->hWnd, GWL_STYLE); if(dwStyle & SS_ICON) { hIcon = (HICON)SendMessage(pCxp->hWnd,STM_GETICON,0L,0L); if(hIcon) DrawIcon(hDC, Rect.left, Rect.top, hIcon); } /* else if(dwStyle & SS_BITMAP) { hBmp = (HBITMAP)SendMessage(pCxp->hWnd,STM_GETIMAGE,IMAGE_BITMAP,0L); if(hBmp) DrawIconEx(hDC,0,0,(HICON)hBmp, Rect.right-Rect.left, Rect.bottom-Rect.top,0,0,DI_DEFAULTSIZE); // BitBlt(hDC,Rect.left,Rect.top, // Rect.right-Rect.left,Rect.bottom-Rect.top, // &hBmp,0,0,SRCCOPY); } */ else { if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp))) { SetTextColor(hDC, ((pCxp->dwState & CXPS_INDETERMINATE) || (pCxp->dwState & CXPS_DISABLED)) ? 0x0094A2A5: 0x00000000); hHandle = (HANDLE) SelectObject(hDC, (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0)); //DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER); DrawText(hDC, szTemp, -1, &Rect, dwStyle); SelectObject(hDC, (HGDIOBJ) hHandle); } } RestoreDC(hDC, nSaveDC ); // ReleaseDC(pCxp->hWnd, hDC); } // End of OnDrawBackground //////////////////////////////////////////////////////////////////////////////////////////////////// LRESULT ButtonWindowProc(PCLASSXP pCxp, UINT message,WPARAM wParam, LPARAM lParam) { LONG lReturn, lFound; TRACKMOUSEEVENT Tme; HWND hParent; typedef VOID (WINAPI *DRAWXP)(PCLASSXP); static DRAWXP s_DrawXP[] = { ButtonDrawPushButtonXP, ButtonDrawCheckBoxXP, ButtonDrawRadioBoxXP, ButtonDrawGroupBoxXP, ButtonDrawStateBoxXP, }; HWND hWnd = pCxp->hWnd; switch (message) { case WM_SETICON: return ButtonOnSetIcon(pCxp, wParam,lParam); case BM_SETSTYLE: // 按钮风格改变 CXPM_SETSTATE(pCxp->dwState, CXPS_DEFAULT, wParam & BS_DEFPUSHBUTTON); s_DrawXP[pCxp->dwType](pCxp); break; case BM_SETSTATE: // 设置按钮状态 lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam); CXPM_SETSTATE(pCxp->dwState, CXPS_PRESSED, wParam); s_DrawXP[pCxp->dwType](pCxp); return lReturn; case BM_SETCHECK: // 设置选中状态 lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam); CXPM_SETSTATE(pCxp->dwState, CXPS_CHECKED, (wParam == BST_CHECKED)); CXPM_SETSTATE(pCxp->dwState, CXPS_INDETERMINATE, (wParam == BST_INDETERMINATE)); s_DrawXP[pCxp->dwType](pCxp); return lReturn; case WM_SETTEXT: // 设置窗口文本 lReturn = (LONG) DefWindowProc(hWnd, message, wParam, lParam); s_DrawXP[pCxp->dwType](pCxp); return lReturn; case WM_PAINT: // 窗口重画 // if(pCxp->dwType == CXPT_STATEBOX || // pCxp->dwType == CXPT_GROUPBOX) lReturn = DefWindowProc(pCxp->hWnd, message, wParam, lParam); // else // lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam); s_DrawXP[pCxp->dwType](pCxp); return lReturn; case WM_LBUTTONUP: if(pCxp->dwType == CXPT_PUSHBUTTON) { ReleaseCapture(); hParent = GetParent(hWnd); if(hParent != NULL) SendMessage(hParent,WM_COMMAND,MAKEWPARAM(GetDlgCtrlID(hWnd),BN_CLICKED),(LPARAM)hWnd); pCxp->dwState &= ~CXPS_PRESSED; s_DrawXP[pCxp->dwType](pCxp); return 0; } break; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: if(pCxp->dwType == CXPT_PUSHBUTTON) { SetFocus(hWnd); pCxp->dwState |= CXPS_PRESSED; s_DrawXP[pCxp->dwType](pCxp); return 0; } break; case WM_ERASEBKGND: //禁止check和radio按钮背景重绘 if(pCxp->dwType == CXPT_CHECKBOX) return TRUE; if(pCxp->dwType == CXPT_RADIOBOX) return TRUE; if(pCxp->dwType == CXPT_STATEBOX) return TRUE; if(pCxp->dwType == CXPT_GROUPBOX) return TRUE; break; case WM_MOUSELEAVE: // 鼠标移出 if (pCxp->dwState & CXPS_HOTLIGHT) { pCxp->dwState &= ~CXPS_HOTLIGHT; //s_DrawXP[pCxp->dwType](pCxp); lFound = 1; } if (pCxp->dwState & CXPS_PRESSED) { pCxp->dwState &= ~CXPS_PRESSED; lFound = 1; } s_DrawXP[pCxp->dwType](pCxp); return 0; } // 调用原来的回调函数 lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam); // 对所有窗口相同的处理 switch (message) { case WM_MOUSEMOVE: // 窗口移动 if (((pCxp->dwState & CXPS_HOTLIGHT) == 0) && ((wParam & MK_LBUTTON) == 0)) { pCxp->dwState |= CXPS_HOTLIGHT; s_DrawXP[pCxp->dwType](pCxp); // 追踪鼠标移出消息一次 Tme.cbSize = sizeof(TRACKMOUSEEVENT); Tme.dwFlags = TME_LEAVE; Tme.hwndTrack = hWnd; TrackMouseEvent(&Tme); } break; /* case WM_MOUSELEAVE: // 鼠标移出 lFound = 0; if (pCxp->dwState & CXPS_HOTLIGHT) { pCxp->dwState &= ~CXPS_HOTLIGHT; lFound = 1; } if (pCxp->dwState & CXPS_PRESSED) { pCxp->dwState &= ~CXPS_PRESSED; lFound = 1; } if(lFound) s_DrawXP[pCxp->dwType](pCxp); break; */ case WM_ENABLE: // 窗口被设置为禁用或可用 CXPM_SETSTATE(pCxp->dwState, CXPS_DISABLED, !wParam); s_DrawXP[pCxp->dwType](pCxp); break; case WM_SETFOCUS: // 获得焦点 SendMessage((HWND)wParam, WM_KILLFOCUS,0,0); pCxp->dwState |= CXPS_FOCUS; s_DrawXP[pCxp->dwType](pCxp); break; case WM_KILLFOCUS: // 丢失焦点 pCxp->dwState &= ~CXPS_FOCUS; s_DrawXP[pCxp->dwType](pCxp); break; case WM_NCDESTROY: // 窗口销毁 DeleteClassXP(hWnd); } return lReturn; } /**************以下设置必需包含在每个子类中**********************/ //////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus } #endif // __cplusplus //////////////////////////////////////////////////////////////////////////////////////////////////// /*****************************************************************/