解決方案
經過多次測驗和社區的良好引導,我現在可以確認SetThreadDesktop 在創建QApplication. 這是允許 Qt 在新桌面中顯示 QWidgets 的唯一方法。
但是,SwitchDesktop可以在QApplication之前或之后呼叫,只要SetThreadDesktop在QApplication創建之前已經呼叫過就可以了。
感謝大家!我希望這個話題對其他人有用。
問題
我正在 Windows 上開發一個 Qt 專案,我需要使用CreateDesktop、OpenDesktop和SwitchDesktop等 API 創建自定義桌面 ( HDESK ) 。在這個新桌面上,我需要顯示一個 QDialog(根據我的需要使用exec或show ),但 QDialog 不會顯示在新桌面上,而是顯示在“默認”桌面上。
我的代碼看起來像這樣:
/* Starting the QApplication from the main function */
QApplication qApp;
qApp.exec();
/* [...] An HEVENT is fired or a Win32 COM call is made telling me than i need to display the QDialog */
/* Creating the new desktop and switching to it */
HDESK hNewDesktop=NULL;
hNewDesktop=CreateDesktop(L"_MyNewDesktopName", NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL);
SwitchDesktop(hNewDesktop);
/* Creating the QDialog and showing it */
QDialog *pqdlgMyDialog=NULL;
pqdlgMyDialog=new QDialog(NULL);
pqdlgMyDialog.show(); // or .exec() depending on the my needs
這樣做,創建并顯示一個具有黑色背景的新桌面,但 QDialog 顯示在默認桌面上(我們在啟動 Windows 時看到的桌面)。
我必須嘗試為我的 QDialog 設定一個父級,但它也不起作用:
QWindow *pqwParentWindow=NULL;
QWidget *pwqParentWidget=NULL;
HWND hwndParentWindow=NULL;
hwndParentWindow=GetTopWindow(NULL); // I have also tried GetDesktopWindow, FindWindowEx etc.
pqwParentWindow=QWindow::fromWinId((WId)hwndParentWindow);
pwqParentWidget=QWidget::createWindowContainer(pqwParentWindow);
[...]
QDialog *pqdlgMyDialog=NULL;
pqdlgMyDialog=new QDialog(pwqParentWidget);
pqdlgMyDialog.show(); // or .exec() depending on the my needs
如果有人有想法,我愿意嘗試一切!我已經閱讀了大量的 Qt 檔案和 MSDN,尋找諸如“QApplication 是否鏈接到桌面”之類的東西,但沒有成功......
uj5u.com熱心網友回復:
HWND 與執行緒相關聯,具有 HWND 的執行緒與桌面相關聯。
如果呼叫執行緒在其當前桌面上有任何視窗或掛鉤,則 SetThreadDesktop 函式將失敗(除非 hDesktop 引數是當前桌面的句柄)。
我不知道 QApplication 是否創建了一個隱藏視窗,或者您是否在那里有另一個 HWND,但很容易證明SetThreadDesktop如果執行緒上已經有一個視窗,它將失敗:
HDESK g_hNew;
DWORD CALLBACK TrySwitch(LPVOID Param)
{
if (Param)
{
CreateWindow(L"EDIT", L"Existing window", WS_VISIBLE|WS_OVERLAPPEDWINDOW, 0, 0, 200, 200, 0, 0, 0, 0);
}
if (SetThreadDesktop(g_hNew))
{
SwitchDesktop(g_hNew);
CreateWindow(L"EDIT", L"New window", WS_VISIBLE|WS_OVERLAPPEDWINDOW, 0, 0, 200, 200, 0, 0, 0, 0);
}
Sleep(3333);
return 0;
}
void Example()
{
HDESK hIn = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, false, DESKTOP_SWITCHDESKTOP);
g_hNew = CreateDesktop(L"_MyNewDesktopName", NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL);
WaitForSingleObject(CreateThread(NULL, 0, TrySwitch, (void*) TRUE, 0, NULL), 3333); // Leaks thread handle and I don't care
WaitForSingleObject(CreateThread(NULL, 0, TrySwitch, (void*) FALSE, 0, NULL), 3333); // Leaks thread handle and I don't care
SwitchDesktop(hIn);
CloseDesktop(hIn);
CloseDesktop(g_hNew);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/493358.html
