无忧资源站

 找回密码
 加入我们
查看: 430|回复: 0

[C/C++] MFC编程CButton美化

[复制链接]

18

主题

22

帖子

174

积分

学徒

Rank: 2

积分
174

最佳新人

发表于 2024-2-7 00:14:58 | 显示全部楼层 |阅读模式


hook文件.h
  1. #include "pch.h"
  2. #include "hook_test.h"
  3. #include "NewButton.h"
  4. HHOOK  Q_hWndHook;
  5. HINSTANCE Q_hMod = NULL;

  6. LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);

  7. BOOL __stdcall Hook_Start(DWORD dwThreadID, HMODULE hModule)
  8. {
  9.     Q_hWndHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)HookProc, Q_hMod, dwThreadID);
  10.     return TRUE;
  11. }

  12. int SetWindowBackColor(HWND _hwnd) {


  13.     // 获取窗口的客户区域
  14.     RECT rect;
  15.     CWnd* pWnd = CWnd::FromHandle(_hwnd);
  16.     pWnd->GetClientRect(&rect);
  17.     // 获取窗口的设备上下文
  18.     HDC hdc = GetDC(_hwnd);
  19.     //设置背景色
  20.     SetBkColor(hdc, RGB(21, 21, 23));
  21.     //使用背景色填充窗口的客户区域
  22.     ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
  23.     // 释放设备上下文
  24.     ReleaseDC(_hwnd, hdc); //SetWindowTheme(0, L"Explorer", NULL);

  25.     return 0;


  26.     wchar_t ClassName[MAX_PATH] = _T("");
  27.     GetClassName(_hwnd, ClassName, MAX_PATH);
  28.     if (ClassName[0] == L'#') {
  29.         CWnd* pWnd = CWnd::FromHandle(_hwnd);
  30.         CDC* pDC = pWnd->GetDC();
  31.         RECT rect;
  32.         {

  33.             pWnd->GetWindowRect(&rect);
  34.             pWnd->ScreenToClient(&rect);
  35.             pDC->FillSolidRect(&rect, RGB(21, 21, 23)); // 设置窗口背景颜色
  36.         }

  37.         {
  38.             rect.left += 9; rect.right -= 9; rect.top += GetSystemMetrics(SM_CYCAPTION) + 9; rect.bottom -= 9;
  39.             pDC->Draw3dRect(&rect, RGB(88, 111, 255), RGB(88, 111, 255));
  40.         }

  41.         pWnd->ReleaseDC(pDC);
  42.     }
  43.     return 0;
  44. }
  45. LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
  46. {
  47.         CWPSTRUCT* pMsg = (CWPSTRUCT*)lParam;
  48.         //printf("pMsg->message=%X\n", pMsg->message);
  49.         if (pMsg->message == WM_PAINT) {
  50.             //SetWindowBackColor(pMsg->hwnd);
  51.             wchar_t ClassName[MAX_PATH] = _T("");
  52.             GetClassName(pMsg->hwnd, ClassName, MAX_PATH);
  53.             if (wcscmp(ClassName, _T("Button")) == 0) {
  54.                 CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);
  55.                 CWnd* pParent = pWnd->GetParent();
  56.                 int id = pWnd->GetDlgCtrlID();
  57.                 if (id != 0) {
  58.                     NewButton* pButton = (NewButton*)GetWindowLongPtr(pWnd->m_hWnd, GWLP_USERDATA);
  59.                     if (pButton == nullptr) {
  60.                         //还没有设置
  61.                         CString title;
  62.                         pWnd->GetWindowTextW(title);
  63.                         if (title == L"") {
  64.                             SetWindowLongPtr(pWnd->m_hWnd, GWLP_USERDATA, (LONG_PTR)-1);
  65.                             return CallNextHookEx(Q_hWndHook, nCode, wParam, lParam);
  66.                         }

  67.                         //printf("%d\n", pMsg->message);

  68.                         pButton = new NewButton();
  69.                         //printf("%p\n", pButton);
  70.                         pButton->s_info.id = id;
  71.                         pButton->s_info.hwnd = pMsg->hwnd;
  72.                         pButton->s_info.pWnd = pWnd;

  73.                         pButton->s_info.souProc = GetWindowLongPtrW(pWnd->m_hWnd, GWLP_WNDPROC);
  74.                         pButton->s_info.newProc = (LONG_PTR)NewButton::ButtonProc;
  75.                         SetWindowLongPtr(pWnd->m_hWnd, GWLP_WNDPROC, pButton->s_info.newProc);
  76.                         SetWindowLongPtr(pWnd->m_hWnd, GWLP_USERDATA, (LONG_PTR)pButton);
  77.                         //return 0;

  78.                     }
  79.                     else if (pButton != (NewButton*)-1) {
  80.                         ;// printf("%p\n", pButton);
  81.                     }
  82.                 }
  83.             }
  84.             else {
  85.                 //printf("%X 0x%X\n", nCode, pMsg->message);
  86.             }
  87.         }
  88.         else if (pMsg->message == WM_CAPTURECHANGED) {
  89.             CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);
  90.          
  91.             //pWnd->Invalidate();
  92.             //SetWindowBackColor();
  93.             
  94.             return 0;
  95.         }
  96.         else if (pMsg->message == WM_DESTROY) {
  97.          
  98.             UnhookWindowsHookEx(Q_hWndHook);
  99.             return 0;
  100.         }
  101.     return CallNextHookEx(Q_hWndHook, nCode, wParam, lParam);
  102. }
复制代码


.h文件

  1. #pragma once
  2. #include <afxwin.h>
  3. class NewButton
  4. {
  5. public:
  6.     NewButton();
  7.     ~NewButton();
  8. public:
  9.     HCURSOR m_cursorFocus;      //按钮焦点鼠标样式(手型)
  10.     HCURSOR m_cursorDown;       //普通鼠标样式
  11.     struct {
  12.         COLORREF currentColor;  //当前颜色
  13.         COLORREF textColor;            //字体颜色
  14.         COLORREF bgColor;            //背景颜色
  15.         COLORREF FocusColor;    //焦点颜色
  16.         COLORREF DownColor;            //按下颜色
  17.     }s_color;
  18.     struct//_S_BUTTON_INFO_
  19.     {
  20.         int id = -1;            //按钮ID
  21.         HWND hwnd = 0;          //句柄
  22.         CWnd* pWnd = 0;         //对象指针
  23.         LONG_PTR souProc = 0;   //原始proc
  24.         LONG_PTR newProc = 0;   //新的proc
  25.     }s_info;
  26. public:
  27.     static LRESULT CALLBACK ButtonProc(
  28.         HWND hwnd,   
  29.         UINT uMsg,   
  30.         WPARAM wParam,
  31.         LPARAM lParam)
  32.         ;
  33. private:
  34.     static void Paint(const NewButton* pButton);
  35. };

复制代码
.cpp
  1. #include "pch.h"
  2. #include "NewButton.h"

  3. NewButton::NewButton()
  4. {
  5.     m_cursorFocus = LoadCursor(0, MAKEINTRESOURCE((LPWSTR)32649)/*IDC_HAND*/);
  6.     m_cursorDown = LoadCursor(0, MAKEINTRESOURCE((LPWSTR)32514)/*IDC_HAND*/);

  7.     s_color.textColor = RGB(255, 255, 255);
  8.     s_color.bgColor = RGB(30, 100, 188);
  9.     s_color.FocusColor = RGB(30, 70, 200);
  10.     s_color.DownColor = RGB(30, 122, 222); //RGB(100, 222, 100);天然绿

  11.     s_color.currentColor = s_color.bgColor;
  12. }
  13. NewButton::~NewButton()
  14. {
  15. }
  16. LRESULT NewButton::ButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  17. {
  18.     NewButton* pButton = (NewButton*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
  19.     if ((pButton != nullptr) && (pButton->s_info.hwnd == hwnd)) {
  20.         switch (uMsg)
  21.         {
  22.         case WM_LBUTTONDOWN://按钮按下
  23.             SetCursor(pButton->m_cursorDown);
  24.             pButton->s_color.currentColor = pButton->s_color.DownColor;
  25.             pButton->s_info.pWnd->Invalidate();//重绘
  26.             break;
  27.         case WM_LBUTTONUP://弹起
  28.             SetWindowLongPtr(pButton->s_info.hwnd, GWLP_WNDPROC, pButton->s_info.souProc);
  29.             pButton->s_info.pWnd->ShowWindow(SW_HIDE);
  30.             pButton->s_info.pWnd->SendMessage(BM_CLICK);
  31.             pButton->s_info.pWnd->ShowWindow(SW_SHOW);
  32.             SetWindowLongPtr(pButton->s_info.hwnd, GWLP_WNDPROC, pButton->s_info.newProc);
  33.             pButton->s_color.currentColor = pButton->s_color.bgColor;
  34.             break;
  35.         case WM_MOUSEMOVE://焦点
  36.             SetCursor(pButton->m_cursorFocus);
  37.             break;
  38.         case WM_PAINT://绘制
  39.             NewButton::Paint(pButton);
  40.             break;
  41.         case WM_DESTROY://结束
  42.             SetWindowLongPtr(pButton->s_info.hwnd, GWLP_WNDPROC, pButton->s_info.souProc);
  43.             SetWindowLongPtr(pButton->s_info.hwnd, GWLP_USERDATA, (LONG_PTR)nullptr);
  44.             delete pButton;
  45.             break;
  46.         default:
  47.             break;
  48.         }
  49.     }
  50.     else {
  51.         ;// printf("空的,不可能\n");
  52.     }
  53.     return DefWindowProc(hwnd, uMsg, wParam, lParam);
  54. }

  55. void NewButton::Paint(const NewButton* pButton)
  56. {
  57.     //获取按钮矩形位置
  58.     RECT rect;
  59.     pButton->s_info.pWnd->GetWindowRect(&rect);
  60.     pButton->s_info.pWnd->ScreenToClient(&rect);
  61.     //获取绘制对象
  62.     CDC* pDC = pButton->s_info.pWnd->GetDC();
  63.     //绘制控件框架
  64.     //pDC->DrawFrameControl(&rect, DFC_BUTTON, 0);
  65.     //选入按钮背景色
  66.     CBrush brush(pButton->s_color.currentColor);
  67.     CBrush* pOldBrush = pDC->SelectObject(&brush);
  68.     //绘制一个圆角矩形
  69.     pDC->RoundRect(&rect, CPoint(8, 8));
  70.     //恢复原来的画刷
  71.     pDC->SelectObject(pOldBrush);
  72.     //获取按钮文本内容
  73.     CString btnCaption = L"";
  74.     pButton->s_info.pWnd->GetWindowText(btnCaption);
  75.     //复制按钮矩形区域
  76.     CRect textRect;
  77.     textRect.CopyRect(&rect);
  78.     //获得字符串尺寸
  79.     CSize sz = pDC->GetTextExtent(btnCaption);
  80.     //调整文本位置使其居中
  81.     textRect.top += (textRect.Height() - sz.cy) / 2;
  82.     //设置文本透明背景
  83.     pDC->SetBkMode(TRANSPARENT);
  84.     //设置文本颜色
  85.     pDC->SetTextColor(pButton->s_color.textColor);
  86.     //绘制文本内容
  87.     pDC->DrawText(btnCaption, &textRect, DT_RIGHT | DT_CENTER | DT_BOTTOM);
  88. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入我们

x

QQ|SiteMap|Map|小黑屋|无忧资源站

GMT+8, 2024-5-19 16:35 , Processed in 0.056473 second(s), 21 queries .

无忧资源站

Copyright © 2022-2032 www.wyzyz.net

快速回复 返回顶部 返回列表