Windhawk修改窗口关闭按钮颜色失败:多方案尝试无效求助
修改Windows 11关闭按钮悬停颜色失败求助
我尝试通过Windhawk(窗口模组分享平台)修改Windows 11窗口关闭按钮的悬停颜色,先后试过以下方案,但均完全无效:
- 修改
DwmSetWindowAttribute以更改DWMWA_CAPTION_COLOR - 挂钩
DwmGetWindowAttribute而非DwmSetWindowAttribute - 拦截
WM_NCPAINT消息自定义绘制关闭按钮 - 使用窗口子类化创建子窗口的Overlay Button方案
以下是我尝试的Overlay Button方案代码:
// ==WindhawkMod== // @id custom-overlay-close-button-mod // @name 自定义覆盖式关闭按钮模组 // @description 添加可自定义悬停颜色的覆盖式关闭按钮 // @version 2.0.2 // @author 你的名字 // @github https://github.com/YourName/YourRepo // @include * // @compilerOptions -luser32 -lgdi32 -luxtheme -ldwmapi -lcomctl32 // ==/WindhawkMod== // ==WindhawkModReadme== /* # 自定义覆盖式关闭按钮模组 本模组添加一个可自定义悬停颜色的覆盖式关闭按钮,通过在原有关闭按钮上方创建一个小型子窗口实现。 ## 特性 - 可自定义悬停颜色的关闭按钮 - 适用于Windows 11各类应用 - 保留原窗口功能 */ // ==/WindhawkModReadme== // ==WindhawkModSettings== /* - closeButtonHoverColor: "#FF0000" $name: 关闭按钮悬停颜色 $description: 鼠标悬停时显示的颜色(例如#FF0000为红色) - enableMod: true $name: 启用模组 $description: 开关模组的启用状态 */ // ==/WindhawkModSettings== #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <dwmapi.h> #include <commctrl.h> // 函数声明 static LRESULT CALLBACK HostWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); static LRESULT CALLBACK CloseButtonWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static void PositionCloseButton(HWND hwndHost, HWND hwndButton); static COLORREF HexToColorRef(const wchar_t* hexColor); // 全局变量 static COLORREF g_closeButtonHoverColor; static bool g_enableMod; static HBRUSH g_hoverBrush = NULL; // Windhawk模组函数 void LoadSettings() { g_closeButtonHoverColor = HexToColorRef(Wh_GetStringSetting(L"closeButtonHoverColor")); g_enableMod = Wh_GetIntSetting(L"enableMod") != 0; if (g_hoverBrush) DeleteObject(g_hoverBrush); g_hoverBrush = CreateSolidBrush(g_closeButtonHoverColor); Wh_Log(L"已加载设置:悬停颜色=%06X,启用状态=%d", g_closeButtonHoverColor, g_enableMod); } BOOL Wh_ModInit() { LoadSettings(); // 初始化通用控件 INITCOMMONCONTROLSEX icex; icex.dwSize = sizeof(INITCOMMONCONTROLSEX); icex.dwICC = ICC_STANDARD_CLASSES; InitCommonControlsEx(&icex); return TRUE; } void Wh_ModUninit() { if (g_hoverBrush) DeleteObject(g_hoverBrush); } void Wh_ModSettingsChanged() { LoadSettings(); } // 辅助函数:十六进制颜色转COLORREF static COLORREF HexToColorRef(const wchar_t* hexColor) { unsigned int color = wcstoul(hexColor + 1, NULL, 16); return RGB((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF); } // 辅助函数:定位关闭按钮位置 static void PositionCloseButton(HWND hwndHost, HWND hwndButton) { RECT rcClient; GetClientRect(hwndHost, &rcClient); POINT ptTopRight = { rcClient.right, rcClient.top }; ClientToScreen(hwndHost, &ptTopRight); int buttonSize = GetSystemMetrics(SM_CXSIZE); SetWindowPos(hwndButton, NULL, ptTopRight.x - buttonSize, ptTopRight.y, buttonSize, buttonSize, SWP_NOZORDER | SWP_NOACTIVATE); } // 宿主窗口子类化过程 static LRESULT CALLBACK HostWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { HWND hwndButton = (HWND)dwRefData; switch (uMsg) { case WM_SIZE: case WM_MOVE: if (hwndButton) { PositionCloseButton(hwnd, hwndButton); } break; case WM_DESTROY: if (hwndButton) { DestroyWindow(hwndButton); } RemoveWindowSubclass(hwnd, HostWndProc, uIdSubclass); break; } return DefSubclassProc(hwnd, uMsg, wParam, lParam); } // 自定义关闭按钮窗口过程 static LRESULT CALLBACK CloseButtonWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static bool isHovered = false; static bool isPressed = false; switch (uMsg) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rc; GetClientRect(hwnd, &rc); if (isHovered) { FillRect(hdc, &rc, g_hoverBrush); } // 绘制叉号 HPEN hPen = CreatePen(PS_SOLID, 2, isHovered ? RGB(255, 255, 255) : RGB(0, 0, 0)); HGDIOBJ hOldPen = SelectObject(hdc, hPen); MoveToEx(hdc, rc.left + 5, rc.top + 5, NULL); LineTo(hdc, rc.right - 5, rc.bottom - 5); MoveToEx(hdc, rc.right - 5, rc.top + 5, NULL); LineTo(hdc, rc.left + 5, rc.bottom - 5); SelectObject(hdc, hOldPen); DeleteObject(hPen); EndPaint(hwnd, &ps); return 0; } case WM_MOUSEMOVE: if (!isHovered) { isHovered = true; InvalidateRect(hwnd, NULL, TRUE); TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, hwnd, 0 }; TrackMouseEvent(&tme); } return 0; case WM_MOUSELEAVE: isHovered = false; InvalidateRect(hwnd, NULL, TRUE); return 0; case WM_LBUTTONDOWN: isPressed = true; SetCapture(hwnd); return 0; case WM_LBUTTONUP: if (isPressed) { HWND hwndParent = GetParent(hwnd); if (hwndParent) { PostMessage(hwndParent, WM_CLOSE, 0, 0); } } isPressed = false; ReleaseCapture(); return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); } // 窗口创建后钩子:添加自定义关闭按钮 void Wh_ModAfterCreateWindow(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT result) { if (!g_enableMod) return; WCHAR className[256]; if (GetClassName(hwnd, className, ARRAYSIZE(className)) == 0) return; // 仅处理顶级窗口(排除对话框类#32770) if (wcscmp(className, L"#32770") != 0 && GetWindow(hwnd, GW_OWNER) == NULL) { HWND hwndButton = CreateWindowEx( WS_EX_TOPMOST | WS_EX_LAYERED, L"BUTTON", L"", WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 0, 0, 0, 0, hwnd, NULL, NULL, NULL); if (hwndButton) { SetWindowLongPtr(hwndButton, GWLP_WNDPROC, (LONG_PTR)CloseButtonWndProc); SetLayeredWindowAttributes(hwndButton, RGB(255, 0, 255), 0, LWA_COLORKEY); PositionCloseButton(hwnd, hwndButton); SetWindowSubclass(hwnd, HostWndProc, 0, (DWORD_PTR)hwndButton); Wh_Log(L"已为窗口添加自定义关闭按钮:%p", hwnd); } } }
内容的提问来源于stack exchange,提问作者Kai Piper
相关产品推荐
相关产品推荐

