无框窗口出现边框

Posted

技术标签:

【中文标题】无框窗口出现边框【英文标题】:Border appears on frameless window 【发布时间】:2018-03-22 14:58:26 【问题描述】:

我有一个用 Qt 编写的应用程序,在 Windows 上我自己处理原生事件,以拥有一个具有原生感觉的自定义窗口。

我正在删除这样的标题,以实现当任务栏自动隐藏选项打开时窗口也正确定位。

DWORD style = GetWindowLong (hwnd, GWL_STYLE);
style &= ~WS_CAPTION;
style |= (WS_MAXIMIZEBOX | WS_THICKFRAME);
SetWindowLong (hwnd, GWL_STYLE, style);

..我隐藏了 MSDN 文档中建议的边框:

switch (msg)

    case WM_NCCALCSIZE:
    
        // this removes the window frame and title bar we added with WS_THICKFRAME and
        // WS_CAPTION
        *result = 0;
        return true;
    

    ...

我得到一个功能齐全的无框窗口,但是当我点击任务栏时出现边框,这是我不想要的。 那么有人知道为什么会发生这种情况以及我如何绕过它吗?

顺便说一句,如果我不从样式中删除标题,我也有一个无框窗口,这个问题不会出现,但是我遇到了其他问题。

【问题讨论】:

&= WS_CAPTION 关闭除 WS_CAPTION 位之外的所有内容。你真的是说&= ~WS_CAPTION 吗? 是的,我编辑了它。谢谢。 你的窗口过程不熟悉。 result 是什么?以及为什么函数返回true 啊,我还在 Qt 环境中。 *result = 0 将等于 WindowProc 中的 return 0 你能给出推荐使用 WM_NCCALCSIZE 的 MSDN 页面的链接吗?在 WM_NCCALCSIZE 下,我看到,“从 Windows Vista 开始,在 wParam 为 TRUE 时通过简单地返回 0 来删除标准框架不会影响使用 DwmExtendFrameIntoClientArea 函数扩展到客户区域的框架。只会删除标准框架。”听起来很可疑。 【参考方案1】:

来自SetWindowLong reference:

某些窗口数据已缓存,因此您使用 SetWindowLong 进行的更改 在调用 SetWindowPos 函数之前不会生效。 具体来说,如果您更改任何框架样式,则必须调用 带有 SWP_FRAMECHANGED 标志的 SetWindowPos 用于缓存 正确更新。

像这样拨打SetWindowPos解决问题:

SetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );

这也会导致 Windows 向您的窗口发送WM_NCCALCSIZE 消息以重新计算 NC 区域。

【讨论】:

我刚试过。与任务栏交互时,窗口框架仍然会出现,但只要我调整窗口大小就会消失。 @bob 我认为在WM_NCCALCSIZE 中,您缺少检查wParam 是否为TRUE,如本消息参考中所述(在 cmets 部分中)。如果没有,你应该调用原来的窗口过程让系统做默认。 所以我去掉的标准框架和我点击任务栏时出现的不一样?我没有使用 dwmapi,所以我不知道该怎么做。 @bob 我对另一个问题有更详细的answer,也许这对你有帮助。 我知道你在那里做了什么。我测试了你的示例代码。将它的样式更改为我在我的应用程序中所做的,重现了我遇到的问题。因此,在点击任务栏时,删除 style &= ~WS_CAPTION; 的标题会导致同样的问题。所以我想一个解决方案不会删除标题但是当我这样做时,窗口在最大化时会与任务栏重叠。

以上是关于无框窗口出现边框的主要内容,如果未能解决你的问题,请参考以下文章

Qt/win:无框窗口上的 showMaximized() 重叠任务栏

为啥在调试过程中有时窗口标题为黑色和按钮无框

Python OpenCV - 如何删除窗口边框和标题

C#无框窗体的隐藏代码是啥?(类似QQ停靠桌面边缘自动隐藏)

qml无框窗口的阴影

无框 pyqt/qml 窗口