QT應用隱藏啓動外部應用

最近在開發的一個項目需要用QT調用Unity的應用。想到的辦法就是啓動Unity應用,嵌入到QT應用中。

由於Unity應用加載需要時間,而且無法隱藏加載窗口(本人不熟悉unity開發)。因此採用外部調用的方式加載unity應用。

一、QT 調用Unity程序CreateProcess

STARTUPINFO si;
    si.cb = sizeof(STARTUPINFO);
    si.lpReserved = NULL;
    si.lpDesktop = NULL;
    si.lpTitle = NULL;
     si.dwFlags = STARTF_USESHOWWINDOW| STARTF_USESTDHANDLES;
     si.wShowWindow = SW_HIDE;
    si.cbReserved2 = NULL;
    si.lpReserved2 = NULL;
    std::wstring str = path.toStdWString();
    BOOL ret = CreateProcess(NULL, (LPTSTR)str.c_str(), NULL, NULL, FALSE, CREATE_SUSPENDED|CREATE_NO_WINDOW, NULL, NULL, &si, &pi);

此時untiy.exe以進程掛起的方式隱藏創建,且沒有新的窗口。

二、第一次顯示的時候可以調用解掛,並設置unity.exe與應用程序的窗口關係

    ::ResumeThread((HANDLE)pi.hThread);
    HWND childHwnd = NULL;
    while (true)
    {
        childHwnd = FindWindowA(NULL, m_strExeWndName.c_str());
        if (childHwnd != NULL)
        {
            break;
        }
    }
    //2、延時,這個很重要,一定要大於50
       Sleep(3200);

    //4、設置父窗口
     HWND parentHwnd = (HWND)ui.mWidget->winId();
     SetParent(childHwnd, parentHwnd);
 //5、設置窗口位置
    SetWindowPos(childHwnd, HWND_TOPMOST, 0, 0, nWidth, nHeight, SWP_FRAMECHANGED);

三、關閉進程
    TerminateProcess(pi.hProcess, 0);//終止進程
    ::CloseHandle(pi.hThread);
    ::CloseHandle(pi.hProcess);

四、設置Unity窗口屬性

unity窗口是以windows形式build的。此時會帶有邊框、標題欄。需要隱藏邊框和標題欄。

此處代碼可參見:https://blog.csdn.net/ldy597321444/article/details/86595786

注意:unity窗口如果是全屏創建的,此時到了QT應用中,不能自適應窗口的大小。需要保證unity窗口的大小和QT中展示Unity應用部分的窗口大小一致。

STARTF_USESIZE| STARTF_USEPOSITION兩個屬性,並不能更改Unity窗口的大小。詳見MSDN。

研究過程記錄:

1、首先想到的是隱藏Unity程序的邊框,但是本人對於Unity不熟悉,僅隱藏了腳本加載後的邊框,沒有隱藏掉加載時的邊框;

2、不能使用QT通過CreateProcess調用進程後,再修改unity窗口的屬性。此時,已經顯示並獲取到了Unity窗口的屬性。方法1和2,均會產生unity加載窗口,且加載後會有位置的移動。因此有了第三種方案,在加載進程時改變窗口狀態。

3、CreateProcess時,使用線程掛起的方式,並設置窗口的隱藏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章