绘制非客户区的问题 - Win32

Posted

技术标签:

【中文标题】绘制非客户区的问题 - Win32【英文标题】:Problem with painting non client area - Win32 【发布时间】:2021-12-15 11:59:36 【问题描述】:

我正在尝试创建自定义非客户区。

所以我在 WndProc 方法中处理了WM_NCPAINT 消息,并尝试在非客户区创建一个红色矩形,但我发现了两个问题。

    我在非客户区绘制的矩形也覆盖了客户区。

为了遇到它,我在WM_NCPAINT 消息的末尾添加了RedrawWindow 函数,但我不确定这是一个好主意。我还能做些什么来纠正这个问题?

    我在多次调整窗口大小时得到了一些奇怪的结果。我只是不知道如何解释,但我尝试了

这是我目前所取得的成就

但如果我连续多次调整它的大小(比如 10 - 15),它会得到这个

全图为窗口截图(第一张)。 我不知道发生了什么。白色部分画错了,右下角看起来是透明的,但都是一个窗口的截图。 (SS通过截图工具)

所有鼠标点击都穿过透明部分。

窗口的大小调整得很好,但没有正确地在其中绘制,而不是正确的大小。 绘图的大小设置为某个最大大小(不知道是什么,它是随机的)。

代码与Visual Studio Windows Desktop Application C++模板自带的默认代码相同。

刚刚添加了WM_NCPAINT消息的自定义代码。

case WM_NCPAINT:

    HDC hdc = GetWindowDC(hWnd);
    if (hdc) 
        RECT frame =  0 ;
        GetWindowRect(hWnd, &frame);
        frame.right = frame.right - frame.left;
        frame.bottom = frame.bottom - frame.top;
        frame.left = 0;
        frame.top = 0;
        FillRect(hdc, &frame, CreateSolidBrush(RGB(255, 0, 0)));
        ReleaseDC(hWnd, hdc);
        RedrawWindow(hWnd, &frame, (HRGN)wParam, RDW_UPDATENOW);
    
    return 0;

【问题讨论】:

使用ExcludeClipRect剪掉你的客户矩形。 来自CreateSolidBrush“当您不再需要HBRUSH 对象时,调用DeleteObject 函数将其删除。” 你没有这样做,并根据WM_NCPAINT 回调泄漏HBRUSH。 GDI 资源是您的系统必须提供的最有限的资源之一。 @JonathanPotter 感谢您的建议,但它给我带来了更多麻烦,除了我没有看到使用 Redraw Window 函数的任何下降,所以我保持原样。还是谢谢 【参考方案1】:

IInspectable 的评论对我有帮助。

来自CreateSolidBrush:“当您不再需要 HBRUSH 对象时,请调用 DeleteObject 函数将其删除。”您没有这样做,并且每泄漏一个 HBRUSH WM_NCPAINT 回调。 GDI 资源是您的系统必须提供的最有限的资源之一。

【讨论】:

以上是关于绘制非客户区的问题 - Win32的主要内容,如果未能解决你的问题,请参考以下文章

win32-使用FillRect绘制具有渐变颜色的客户区域背景

使用 Direct2D 在非客户区绘图

位图未在 Win32 C++ 中绘制

在win32中绘制像素的最快方法是啥

自定义绘制 CProgressBarCtrl win32

非客户区