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

标签 c++ windows qt winapi qml

我有一个 QML 应用程序(也使用 QWidgets 对其进行了测试,同样的问题)并使其无边界(但仍支持原生 WM 功能,如 aero snap 等)我遵循了 this通过实现 QAbstractNativeEventFilter 并用零响应 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

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

最佳答案

我认为在窗口句柄上使用 SetWindowLong 并使用 Qt Window Flags/Qt Widget Attributes 是自找麻烦。您可以去看看 Qt 源代码,看看在处理这些窗口标志时会发生什么。

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

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

所以换句话说,我会添加一个应用程序范围的QShortcut,监听捕捉键盘快捷键,并在它发生时按照您想要的方式调整窗口大小,如果您管理的是无框窗口.

希望对您有所帮助。

关于c++ - 无框架 Qt 窗口 (win32) 中错误的窗口绘制行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21615034/

相关文章:

c++ - C++ 数组反向器中的 EXC_BAD_ACCESS 错误

C++17 十六进制浮点文字单精度后缀冲突?

windows - WASAPI:即使 IAudioClient->IsFormatSupported 以相同的格式失败,IAudioClient->Initialize 也会成功

c++ - 调用 accept() 时出现异常

windows - 在 Subversion 存储库中存储文件权限

c++ - QAbstractSocket::UnknownSocketError

c++ - 我在哪个时区初始化 QDateTime?

java - 将 C++ md5 编码转换为 android/java

c++ - 初始化中的自赋值

c++ - 将 find 与 QAssociativeIterable 或 QSequentialIterable 一起使用,同时避免在 Qt5 中进行复制