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

时间:2020-03-05 18:45:58  来源:igfitidea点击:

我已经开发了一个COM组件(dll),该组件实现了显示WTL模态对话框的Edit()方法。

此COM组件的完整接口对应于化学过程工业中使用的软件标准(CAPE-OPEN),因此,该COM组件应由不受我控制的一系列第三方可执行文件使用。

我的组件在许多这些EXE中均按预期工作,但是特别是其中一个Edit()方法只是挂起而没有对话框出现。

但是,如果我在DoModal()之前立即调用:: MessageBox(),则对话框将显示并在首次显示MessageBox后正确运行。

我怀疑问题可能与作为"隐藏窗口应用程序"运行的特定EXE有关。

我尝试使用NULL和`:: GetConsoleWindow()的返回值作为对话框的父级,但都没有用。

该对话框本身是一个ATL / WTL CPropertySheetImpl。

该父应用程序(EXE)由(轻度敌对)第三方开发,因此不受我的控制。

我确实知道我可以成功地调用`:: MessageBox()或者从COM组件显示标准的Windows文件对话框,然后我就可以显示自定义对话框了。如果不先显示"标准"对话框,就无法显示自定义对话框。

谁能建议我在不首先显示不必要的MessageBox的情况下如何显示对话框?我知道这是可能的,因为我已经看到此EXE显示与相同接口相对应的其他COM组件的对话框。

解决方案

回答

我们是否在对话框中使用父项?例如

MyDialog dialog(pParent);
dialog.DoModal();

如果是这样,请尝试删除父项。特别是如果父级是桌面窗口。

回答

根据"隐藏窗口"应用程序的工作方式,它可能无法显示窗口。例如,服务没有"主消息循环",因此无法在该过程中处理发送到Windows的消息。即显示窗口的应用程序应具有以下内容:

while(GetMessage(&msg, NULL, 0, 0))
    {
        if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

在WinMain中。

回答

这应该是不可靠的,但是尝试将:: GetDesktopWindow()作为父项(它会返回HWND)。

如果应用崩溃将被警告,它将导致桌面崩溃。但是我很想看看它是否有效。

回答

原来我弄错了:

  • 如果我使用NULL父级创建对话框,则不会显示该对话框,并挂起父级应用程序
  • 但是,如果我使用:: GetConsoleWindow()作为父级创建对话框,则会显示该对话框;否则,将显示对话框。它欺骗了我,因为它显示在启动父应用程序的应用程序窗口的后面

因此,现在我只需要找出如何将对话框置于最前面即可。

谢谢你的回答;-)