簡體   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