You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win32自定义绘制非客户区时覆盖客户区及调整窗口大小异常问题

自定义非客户区绘制问题修复方案

问题1:绘制内容覆盖客户区的修正

你当前使用RedrawWindow的方案效率极低,属于先全窗口覆盖绘制再强制重绘客户区覆盖的冗余逻辑,不是合理方案。正确实现逻辑如下:

  • GetWindowDC获取的DC坐标范围包含整个窗口(非客户区+客户区),你需要仅针对非客户区范围绘制,不要绘制整个窗口矩形
  • 可以通过GetClientRect获取客户区尺寸,用窗口总尺寸减去客户区尺寸即可得到非客户区的边框、标题栏的尺寸范围,仅针对该范围绘制就不会覆盖客户区
  • 无需主动调用RedrawWindow,系统会自动触发客户区的绘制逻辑

问题2:调整大小后窗口异常的根因与修复

该问题是代码存在GDI资源泄漏导致:你调用CreateSolidBrush创建的画刷属于GDI资源,使用完成后没有调用DeleteObject释放。窗口调整大小会频繁触发WM_NCPAINT消息,每次触发都会新增一个未释放的GDI对象,当进程GDI对象数触及系统限制后,所有GDI绘制调用都会失效,就会出现窗口透明、鼠标穿透、绘制尺寸异常的现象。


修正后的完整代码

case WM_NCPAINT:
{
    HDC hdc = GetWindowDC(hWnd);
    if (hdc) {
        // 获取窗口总尺寸
        RECT wndRect;
        GetWindowRect(hWnd, &wndRect);
        int wndWidth = wndRect.right - wndRect.left;
        int wndHeight = wndRect.bottom - wndRect.top;

        // 获取客户区尺寸
        RECT clientRect;
        GetClientRect(hWnd, &clientRect);

        // 计算非客户区尺寸:左右边框宽度、顶部标题栏高度、底部边框高度
        int borderWidth = (wndWidth - clientRect.right) / 2;
        int titleHeight = (wndHeight - clientRect.bottom) - borderWidth;

        // 创建GDI画刷,使用完成必须释放
        HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
        
        // 仅绘制非客户区,不覆盖客户区
        RECT topTitle = {0, 0, wndWidth, titleHeight};
        FillRect(hdc, &topTitle, redBrush);
        RECT leftBorder = {0, titleHeight, borderWidth, wndHeight - borderWidth};
        FillRect(hdc, &leftBorder, redBrush);
        RECT rightBorder = {wndWidth - borderWidth, titleHeight, wndWidth, wndHeight - borderWidth};
        FillRect(hdc, &rightBorder, redBrush);
        RECT bottomBorder = {0, wndHeight - borderWidth, wndWidth, wndHeight};
        FillRect(hdc, &bottomBorder, redBrush);

        // 释放GDI资源,避免泄漏
        DeleteObject(redBrush);
        ReleaseDC(hWnd, hdc);
    }
    return 0;
}

如果你需要自定义非客户区的尺寸,额外处理WM_NCCALCSIZE消息调整非客户区大小即可。

内容的提问来源于stack exchange,提问作者The RESEARCHER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:15:03