无框Qt窗口中的窗口绘制行为错误(win32)

时间:2014-02-06 22:03:12

标签: c++ windows qt winapi qml

我有一个QML应用程序(也用QWidgets测试它,同样的问题)并使其无边界(但仍支持本机WM功能,如aero snap等)我通过实现QAbstractNativeEventFilter并响应this到零的WM_NCCALSIZE信号:

switch(msg->message) {
  case WM_NCCALCSIZE:
    *r = 0;
    return 1;
    ...
}

我还设置了一些不在Qt命名空间中的窗口标志

SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME);

这样可以正常工作,直到我移动或调整窗口大小,导致Qt重新渲染,未显示的区域宽度,标题和边框的宽度出现:

移动/调整大小之前 Before

移动/调整大小后 After

我还通过在Qt中添加FramelessWindowHint标志找到了解决方法:

window->setFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::Dialog);

但是现在当窗口状态发生变化(最大化,最小化,......)时,这个边距会再次出现。通过阻止WM_SIZE事件,例如当SIZE_MAXIMIZED是参数时,边距不会出现但是我也无法从Qt最大化窗口。这意味着它是Qt方面的问题。

我还注意到通过winspector检查窗口样式,在我最大化它之后会出现一个新的属性原子:

winspector screenshot

你能帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

我认为在窗口句柄上使用SetWindowLong并使用Qt Window Flags / Qt Widget属性会遇到麻烦。您可以查看Qt源以查看处理这些窗口标志时会发生什么。

当我创建无框窗户时,我通常会这样做以防止移动和调整大小,因为我正在单独管理所有这些。

我遇到的一个问题是,当屏幕键盘出现并停靠时,它会调整窗口的大小。因此,除了调用resize()之外,我还必须使用setFixedSize来防止在操作系统尝试更改窗口大小时操作窗口小部件。

换句话说,如果您正在管理无框窗口,我会添加一个应用程序范围QShortcut,监听捕捉键盘快捷键并按照您希望的方式调整窗口大小。

希望有所帮助。

答案 1 :(得分:0)

我想知道这是否是Qt消息中继的缺陷,因为我遇到了嵌套窗口上发生的类似问题。如果按父窗口的SIZE_MAXIMIZE或SIZE_MINIMIZE按钮,子窗口有时无法接收WM_SIZE消息。我想大概有两种解决方案:1。修复Qt,2。解决它。

这里我有一个OGL渲染子窗口,有时甚至没有正确传递WM_SIZE消息。也就是说,如果您调整父窗口的大小,则会使客户区的一部分变黑。

我只是使用一个简单的解决方法来修复此问题,使用缓存的方法检查当前大小,并自行调整大小。