App :: InitInstance()中的无模式对话

时间:2016-10-11 12:41:10

标签: c++ mfc

我的应用程序需要在InitInstance()中创建一些昂贵的东西。我想告诉用户有关进度的信息,所以我决定在InitInstance()方法中创建一个无模式对话框。

我的问题是,没有绘制对话框。它在

之后更新
CStartStopDlg dlg(_T("Start"));
dlg.Create(IDD_START_STOP_DLG);
dlg.ShowWindow(SW_SHOW);

// expensive stuff

m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();

即使我在这行之后睡觉,它也会更新对话框。问题是,MainFrame使用我创建的资源,因此我无法重新排列这些行。

如何解决这个问题?

编辑: 昂贵的东西是与摄像头的连接,与io硬件的连接,与数据库的连接以及创建工作线程。应用程序对象拥有所有这些东西,大型机及其视图等使用它。因为这个东西与应用程序中的文档无关。

根据以太网负载,连接需要不同的时间。

模态对话框不需要响应。我只想要一些像adobe reader的启动对话框。

UpdateWindow()的提示是正确的方向,我在更新状态时添加了对此功能的调用。这解决了我的问题。

2 个答案:

答案 0 :(得分:3)

CStartStopDlg dlg(_T("Start"));创建了一个owned对话框,因为 pParentWnd 隐式设置为NULL(请参阅CDialog::CDialog)。该对话框由主应用程序窗口拥有。

拥有的窗口的一个功能是,隐藏其所有者时隐藏它们。因此,在您致电m_pMainWnd->ShowWindow(SW_SHOW);之前,您所拥有的对话框也不会显示。

有很多方法可以解决这个问题。

  1. 显而易见的解决方案是立即显示主应用程序窗口。但是,这可能不实用(并且无法解决阻止UI线程的问题)。
  2. 卸载工作线程的昂贵初始化:
    这是必需的,以便UI线程可以服务于传入的消息,例如,作为用户交互的结果。您需要在工作线程和GUI线程之间实现某种通信。将自定义消息(WM_APP + x)发布到主应用程序窗口通常就足够了。
  3. 推迟昂贵的初始化:
    InitInstance不应该比启动此应用程序实例所需的更多。任何类型的昂贵操作都应该推迟到用户可以看到UI(并可能取消该操作)的点。
    一种常见的方法是为此创建一次性计时器。由于WM_TIMER消息是低优先级的,因此这些消息仅在处理完所有其他消息后才到达,并且应用程序处于可操作状态。此时,您可以将昂贵的初始化卸载到工作线程,并显示模态对话框,直到完成。

答案 1 :(得分:2)

听起来你的“昂贵的东西”是计算限制的,不允许更新任何UI线程。通常通过利用单独的线程来提供进度反馈来解决这些类型的问题。您可能需要查看Using Worker Threads,了解使用线程解决此类问题的一些背景知识。