如何从隐藏的窗口应用程序中显示对话框?
Posted
技术标签:
【中文标题】如何从隐藏的窗口应用程序中显示对话框?【英文标题】:How do you display a dialog from a hidden window application? 【发布时间】:2010-09-07 11:10:00 【问题描述】:我开发了一个 COM 组件 (dll),它实现了一个显示 WTL 模式对话框的 Edit() 方法。
该 COM 组件的完整接口对应于化学过程工业中使用的软件标准 (CAPE-OPEN),因此该 COM 组件应该可以被我不知道的一系列第 3 方可执行文件使用控制。
我的组件在许多这些 EXE 中都按预期工作,但特别是其中一个,Edit() 方法只是挂起而没有出现对话框。
但是,如果我在 DoModal()
之前立即调用 ::MessageBox()
,则对话框会在首次显示 MessageBox 后显示并正确运行。
我怀疑问题可能与这个作为“隐藏窗口应用程序”运行的特定 EXE 有关。
我尝试使用 NULL 和来自 ::GetConsoleWindow()
的返回值作为对话框的父级,但都没有成功。
对话框本身是一个 ATL/WTL CPropertySheetImpl。
有问题的父应用程序 (EXE) 不受我控制,因为它是由(轻度敌对的)第 3 方开发的。
我确实知道我可以成功调用::MessageBox()
或从我的 COM 组件显示标准 Windows 文件对话框,并且在这样做之后我就可以显示我的自定义对话框。如果不先显示“标准”对话框,我将无法显示我的自定义对话框。
谁能建议我如何在不先显示不必要的 MessageBox 的情况下让它显示对话框?我知道这是可能的,因为我已经看到这个 EXE 显示了来自其他 COM 组件对应于同一接口的对话框。
【问题讨论】:
【参考方案1】:您是否为对话框使用父级?例如
MyDialog dialog(pParent);
dialog.DoModal();
如果是,请尝试删除父级。特别是如果父级是桌面窗口。
【讨论】:
【参考方案2】:根据“隐藏窗口”应用程序的工作方式,它可能无法显示窗口。例如,服务没有“主消息循环”,因此无法在进程中处理发送到窗口的消息。即,显示窗口的应用程序应该是这样的:
while(GetMessage(&msg, NULL, 0, 0))
if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
TranslateMessage(&msg);
DispatchMessage(&msg);
在 WinMain 中。
【讨论】:
【参考方案3】:这不应该是可靠的 - 但尝试 ::GetDesktopWindow() 作为父级(它返回一个 HWND)。
请注意 - 如果您的应用崩溃,它会导致桌面崩溃。但我很想看看它是否有效。
【讨论】:
【参考方案4】:原来我错了:
如果我使用 NULL 父级创建对话框,则它不会显示,并挂起父级应用程序 但是,如果我使用 ::GetConsoleWindow() 作为父对话框创建对话框,则会显示对话框;它只是愚弄了我,因为它显示在启动父应用程序的应用程序的窗口后面所以现在我只需要找出如何将我的对话放在前面。
感谢您的回答;-)
【讨论】:
【参考方案5】:无论您做什么,不要将桌面窗口用作模式对话框的父窗口。
解释见这里:http://blogs.msdn.com/b/oldnewthing/archive/2004/02/24/79212.aspx
引用理由:
把这个放在一起:如果一个所有者 模态对话框是桌面,然后 桌面被禁用,这 禁用其所有后代。在 换句话说,它会禁用每个窗口 在系统中。即使是你 正在尝试显示!
【讨论】:
以上是关于如何从隐藏的窗口应用程序中显示对话框?的主要内容,如果未能解决你的问题,请参考以下文章