如何在Windows自定义桌面(HDESK)上显示QDialog
问题描述
我在Windows平台开发Qt项目时,需要调用CreateDesktop、OpenDesktop、SwitchDesktop等Win32 API创建自定义桌面(HDESK),原本计划按需调用exec或show方法在新桌面上展示QDialog,但实际运行时QDialog并未显示在新创建的桌面,反而出现在系统默认桌面上。
原有实现代码大致如下:
/* 从main函数启动QApplication */ QApplication qApp; qApp.exec(); /* [...] 事件触发或收到Win32 COM调用,通知需要展示QDialog */ /* 创建新桌面并切换 */ HDESK hNewDesktop=NULL; hNewDesktop=CreateDesktop(L"_MyNewDesktopName", NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL); SwitchDesktop(hNewDesktop); /* 创建并展示QDialog */ QDialog *pqdlgMyDialog=NULL; pqdlgMyDialog=new QDialog(NULL); pqdlgMyDialog->show(); // 根据需求也可调用.exec()
按照上述代码运行时,虽然能成功创建并切换到黑色背景的新桌面,但QDialog始终显示在Windows启动后默认加载的系统桌面上。
我也曾尝试通过如下方式为QDialog设置父窗口,但该方案同样无效:
QWindow *pqwParentWindow=NULL; QWidget *pwqParentWidget=NULL; HWND hwndParentWindow=NULL; hwndParentWindow=GetTopWindow(NULL); // 也尝试过GetDesktopWindow、FindWindowEx等接口 pqwParentWindow=QWindow::fromWinId((WId)hwndParentWindow); pwqParentWidget=QWidget::createWindowContainer(pqwParentWindow); [...] QDialog *pqdlgMyDialog=NULL; pqdlgMyDialog=new QDialog(pwqParentWidget); pqdlgMyDialog->show(); // 根据需求也可调用.exec()
我查阅了大量Qt官方文档与MSDN资料,尝试查找“QApplication是否与特定桌面绑定”等相关内容,但始终未找到有效解决方案。
解决方案
经过多轮测试并结合社区提供的有效思路,现已确认必须在创建QApplication实例之前调用SetThreadDesktop接口,这是让Qt能够在新桌面正常显示QWidget组件的唯一方式。
SwitchDesktop接口可在QApplication创建前后任意时机调用,只要保证SetThreadDesktop的调用早于QApplication创建即可。
希望该内容能为其他开发者提供参考。
内容的提问来源于stack exchange,提问作者JayDee
相关产品推荐
相关产品推荐

