2

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

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

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

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

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

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

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

有问题的父应用程序(EXE)是我无法控制的,因为它是由(轻度敌对的)第 3 方开发的。

我确实知道我可以::MessageBox()从我的 COM 组件成功调用或显示标准 Windows 文件对话框,并且在这样做之后我就可以显示我的自定义对话框。如果不先显示“标准”对话框,我将无法显示我的自定义对话框。

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

4

5 回答 5

1

您是否在对话框中使用父级?例如

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

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

于 2008-09-01T13:32:06.610 回答
1

根据“隐藏窗口”应用程序的工作方式,它可能无法显示窗口。例如,服务没有“主消息循环”,因此无法在进程中处理发送到窗口的消息。即,显示窗口的应用程序应该是这样的:

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

在 WinMain 中。

于 2008-09-01T13:35:22.607 回答
1

这不应该是可靠的 - 但尝试 ::GetDesktopWindow() 作为父级(它返回一个 HWND)。

请注意 - 如果您的应用程序崩溃,它会导致桌面崩溃。但我很想看看它是否有效。

于 2008-09-01T14:02:16.957 回答
1

事实证明我错了:

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

所以现在我只需要找出如何将我的对话放在前面。

感谢您的回答;-)

于 2008-09-01T14:12:12.457 回答
0

无论您做什么,都不要将桌面窗口用作模式对话框的父窗口。

见这里的解释:http: //blogs.msdn.com/b/oldnewthing/archive/2004/02/24/79212.aspx

引用理由:

把它放在一起:如果模式对话框的所有者是桌面,那么桌面就会被禁用,这会禁用它的所有后代。换句话说,它会禁用系统中的每个窗口。甚至是你想要展示的那个!

于 2011-03-09T09:18:40.557 回答