2017-05-04 48 views
2

它可以通過Qt API在Windows上執行嗎?我需要這樣的功能/行爲,因爲我想將我的Qt代碼作爲插件集成到第三方應用程序中,我希望儘可能無縫地實現它。例如,我不想在任務欄上有另外一個代表我的Qt窗口的項目。我正在談論一個單進程應用程序使Qt頂級窗口在單個進程中由其他非Qt窗口「擁有」

我發現使用WinAPI的和HWNDs一個辦法:

// 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本身都可能會覆蓋該設置。

從上面的代碼片段可以看出,我可以檢索第三方應用程序主窗口的HWND。所以從WinAPI的角度來看,它應該是可行的。請問,有沒有一些Qt的方式?或者至少有更好的解決方案?

回答

0

另一種方法是使用ActiveQt模塊將您的代碼作爲ActiveX控件公開。那樣的話,Qt會爲你處理所有的問題。

您的解決方案也很好。這是關於您可以獲得的最「Qt」方式。有兩個nitpicks:

  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); 
} 
+0

謝謝。 :-)我會進一步調查ActiveX解決方案。至於父母/所有者問題:我希望在https://msdn.microsoft.com/en-us/library/windows/desktop/ms632599(v=vs.85).aspx#owned_windows中描述的行爲。按照您的建議,設置父級而非所有者不知道如何在「插件」上下文中按預期/需要工作。不知道爲什麼。設置所有者似乎現在工作。稍後會看到... –