[英]Getting top-level window by widget
我挂在Windows上的Qt5应用程序的QPainter::drawText()
函数。 我的目标是确定将文本绘制到的顶级窗口的本机句柄。 首先,我要获取关联的小部件。
QWidget *widget = static_cast<QWidget *>(painter->device());
因此,应该可以找到相应的顶层窗口/小部件。 但这比我想的要难。 这是我到目前为止尝试过的:
while (widget->parentWidget())
widget = widget->parentWidget();
HWND hwnd = (HWND) widget->winId();
没有成功 顶级父母永远不是所需的窗口。
QApplication::topLevelWidgets()
告诉我一个窗口包含几个顶级小部件(包括我要寻找的小部件)。
我也尝试了QApplication::topLevelAt(widget->mapToGlobal(QPoint()))
在某些情况下,这确实有效,但不可靠。 根据文本和窗口的位置,我会得到一个AccessViolationException
,所以这不是一个选择。
通过测试widget->testAttribute(Qt::WA_NativeWindow)
我发现大多数小部件都是非本地Alien Widgets 。
这就是我获得(称为)顶级窗口的方式。
WinAPI.EnumChildWindows(
WinAPI.GetDesktopWindow(),
new EnumWindowsProc(this.EnumWindowsCallback), 0);
然后,我检查窗口标题以找到我感兴趣的句柄。
我找不到从任何(低级)小部件到包含窗口标题的(顶层)小部件的关系。
对于QWidget
充当顶层窗口, 调用QWidget::window()
对于具有本地句柄的最近的父级, 请调用QWidget::nativeParentWidget()
。
调用winId()
强制窗口小部件获取本机窗口句柄(如果它没有窗口句柄) ,这不是您的目标。 顶层窗口将始终具有本机ID,因此(HWND)window()->winId()
很好。 请注意,这通常与调用QWidget::effectiveWinId()
。
完成! 我找到了解决问题的方法。
每个窗口都有其自己的线程。
int threadId = WinApi.GetWindowThreadProcessId(wndHandle, IntPtr.Zero)
通过它,我使用EnumThreadWindows来获取此线程创建的所有窗口句柄的列表。
最后,我检查了清单中的widget widget->effectiveWinId()
。
因此,我可以将每个小部件映射到其对应的窗口!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.