【问题标题】:Issues with handling ON_WM_NCPAINT() message and OnNCPaint() override. (Overriding default MFC window border) [2020]处理 ON_WM_NCPAINT() 消息和 OnNCPaint() 覆盖的问题。 (覆盖默认 MFC 窗口边框)[2020]
【发布时间】:2021-03-20 03:31:51
【问题描述】:

我正在尝试为我的 Windows 应用程序创建一个“暗模式”主题,但在覆盖 OnNcPaint() 函数时遇到了一些不一致的问题。请原谅那个巨大的红色盒子。我只是用这种方式着色以显示问题。

这是我的初始函数:

void CSoftwareDlg::OnNcPaint() {
    Default(); //I can also use "CDialgoEx::OnNcPaint();" here for the same result because it just calls "Default..."

    CDC* pDC = GetWindowDC();
    CRect rect;
    GetWindowRect(&rect);
    rect.top = 0;
    rect.left = 0;
    rect.bottom = rect.Size().cy;
    rect.right = rect.Size().cx;
    pDC->FillRect(rect, &m_brushRed);
    
    ReleaseDC(pDC);
}

还有(通常的)结果:

我可以通过删除对Default(); 的调用来部分解决此问题:

...但是任何时候移动窗口(或重绘我猜):

我也可以添加Sleep(1000); 来获得不同的结果,但不值得张贴图片。最终......我的覆盖并不是真正的“覆盖”,因为它应该基于我看过的大量示例代码。我知道Default(); 是某种线程回调函数,但我不知道如何进一步解决这个问题。

我是否需要等待Default(); 命令?我是否需要将OnNcPaint() 实现为某种回调函数?我需要覆盖其他功能吗?

【问题讨论】:

  • 至少有一个资源泄漏。对于每次成功调用CWnd::GetWindowDC “应该调用ReleaseDC。资源泄漏可能会产生各种奇怪的影响,尤其是在资源非常有限的情况下,例如 GDI objects
  • 谢谢,已修复。
  • 这确实会导致行为发生非常轻微的变化,但最终消失/重新出现的框架/边框(?)仍然是一个问题。
  • 您还需要覆盖WM_NCACTIVATE,它“绘制标题栏或图标标题”。

标签: winapi visual-c++ mfc windows-messages cdialog


【解决方案1】:

正如@dxiv所说,请处理WM_NCACTIVATE消息,

这样(win32下),

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

不确定您的客户区是否也需要保持相同的颜色。

如有必要,您可以额外处理WM_ERASEBKGND消息。

【讨论】:

    猜你喜欢
    • 2020-01-17
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 2012-03-04
    • 2012-07-09
    • 2011-02-25
    相关资源
    最近更新 更多