为什么win32中覆盖的非客户区在窗口失去焦点时显示默认值?

7

我已经重写了窗口的非客户区,在窗口的回调函数中,如下所示:

    case WM_NCPAINT:
    {
        HDC hdc;
        RECT rect;
        HPEN pen;

        hdc=GetDCEx(hWnd,(HRGN)wParam,DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_LOCKWINDOWUPDATE);
        GetWindowRect(hWnd,&rect);
        pen=CreatePen(PS_SOLID, 10, RGB(255, 0, 0));//red pen 10 pixels in size
        SelectObject(hdc,pen);
        Rectangle(hdc,0,0,(rect.right-rect.left),(rect.bottom-rect.top));
        DeleteObject(pen);
        ReleaseDC(hWnd,hdc);
        RedrawWindow(hWnd,&rect,(HRGN)wParam,RDW_UPDATENOW)
    }break;

那就可以了,以上代码可以在窗口周围画一个红色矩形。但是,如果窗口失去焦点,则会绘制默认的非客户区域,并且我的自定义非客户区域绘图会消失。
我尝试在窗口的回调函数中捕获 WM_KILLFOCUS 消息,并像处理 WM_NCPAINT 一样处理它,但什么也没发生(虽然我看到当我按另一个窗口时,我收到此消息并且我的窗口失去焦点)。
我错过了什么?

3
NC绘画并不简单,主题使其变得不切实际。存在许多问题。您的DeleteObject()调用不会删除对象。它被选择在设备上下文中。您必须恢复DC。保存SelectObject()的返回值,并在绘制后再次调用SelectObject以恢复旧笔。据我所知,您的代码应该烧掉100%的核心,RedrawWindow会导致再次生成WM_NCPAINT。不要帮助太多,WM_PAINT可以完成工作。 - Hans Passant
1个回答

6

WM_NCACTIVATE添加一个处理程序:

case WM_NCACTIVATE:
    // Paint the non-client area now, otherwise Windows will paint its own
    RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW);
    break;

如果我在WM_NCPAINT的末尾删除RedrawWindow,那么当我重新调整窗口大小时,被调整大小的非客户区域(鼠标所持有的边框)会消失 - 我看不到默认的非客户区域和自定义非客户区域。当我完成调整大小(释放鼠标)后,自定义的非客户区域会返回。如果我在WM_NCPAINT的末尾保留RedrawWindow,则在调整大小时也会绘制自定义的非客户区域。我已经检查了具有RedrawWindow和没有它对CPU的影响,并没有发现显着的差异。 - Gidi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接