如何从隐藏的窗口应用程序中显示对话框?

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

引用理由:

把这个放在一起:如果一个所有者 模态对话框是桌面,然后 桌面被禁用,这 禁用其所有后代。在 换句话说,它会禁用每个窗口 在系统中。即使是你 正在尝试显示!

【讨论】:

以上是关于如何从隐藏的窗口应用程序中显示对话框?的主要内容,如果未能解决你的问题,请参考以下文章

错误的窗口令牌,您无法在创建 Activity 之前或隐藏之后显示对话框

如何在 C# 中单击通知图标来聚焦模态对话框?

用户界面

如何将文件写入响应流并显示/隐藏“工作”模式窗口?

如何在任务栏中显示 QMainWindow

delphi2007如何让程序不在任务栏中隐藏和显示?