繁体   English   中英

使 Qt 顶级窗口由单个进程中的其他非 Qt 窗口“拥有”

[英]Make Qt top-level window “owned” by other non-Qt window within a single process

通过 Qt API 在 Windows 上可行吗? 我需要这样的功能/行为,因为我想将我的 Qt 代码作为插件集成到 3rd 方应用程序中,并且我想尽可能无缝地做到这一点。 例如,我不想在任务栏上有另一个项目代表我的 Qt 窗口。 我说的是单进程应用程序

我找到了一种使用 WinAPI 和 HWND 的方法:

// The Qt frame is "alien". We need its HWND so transform it (and all its ancestors,
// which is probably fine for me) to a "native" widget first. 
Q_ASSERT(!frame->testAttribute(Qt::WA_NativeWindow));
frame->setAttribute(Qt::WA_NativeWindow);
Q_ASSERT(frame->testAttribute(Qt::WA_NativeWindow));

// Get the HWND.
QWindow* frameHandle = frame->windowHandle();
Q_ASSERT(frameHandle);
HWND frameHwnd = HWND(frameHandle->winId());
Q_ASSERT(frameHwnd);

// And use it to set the frame's "owner" (not "parent" because WS_CHILD bit is not set).
Q_ASSERT((GetWindowLongPtr(frameHwnd, GWL_STYLE) & WS_CHILD) == 0);
SetWindowLongPtr(frameHwnd, GWLP_HWNDPARENT, LONG_PTR(getOtherNonQtWindowHwnd()));

如果显示框架完成这似乎按预期工作。 但这样的解决方案有点奇怪,恐怕甚至是危险的。 此外,该设置可能会在以后任何时间被 Qt 本身覆盖。

从上面的代码片段中可以看出,我能够检索 3rd 方应用程序主窗口的 HWND。 所以一般从 WinAPI 的角度来看,它应该是可行的。 请问,有没有一些Qt方法可以做到这一点? 或者至少是更好的解决方案?

另一种方法是使用ActiveQt模块将代码公开为 ActiveX 控件。 这样,Qt 将为您处理所有细节。

您的解决方案也很好。 这是关于您可以获得的最“Qt”的方式。 有两个挑剔:

  1. 由于 Qt 负责子窗口的生命周期,因此您一定不要设置所有者。 改为设置父级。 在这种情况下,由您来设置WS_CHILD样式 - 毕竟,您将要使窗口成为子窗口。

  2. frame不应该有任何祖先窗口开始。 您必须确保框架有自己的窗口。

因此:

bool reparentToNativeWindow(QWidget * widget, HWND newParent) {
  widget->setWindowFlags(Qt::Window);
  if (!widget->testAttribute(Qt::WA_NativeWindow));
    widget->setAttribute(Qt::WA_NativeWindow);  
  auto childHandle = widget->windowHandle();
  if (!childHandle)
    return false;
  auto child = HWND(widgetHandle->winId());
  if (!child)
    return false;

  auto style = GetWindowLongPtr(child, GWL_STYLE);
  if (!style)
    return false;
  if ((style & WS_CHILD) == 0) {
    Q_ASSERT(style & WS_POPUP);
    style &= ~WS_POPUP;
    style |= WS_CHILD;
    if (SetWindowLongPtr(child, GWL_STYLE, style) == 0)
      return false;  
  }
  SetParent(child, newParent);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM