无框窗口出现边框
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() 重叠任务栏