繁体   English   中英

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

[英]Modeless Dialog in App::InitInstance()

我的应用程序需要在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()的提示是正确的方向,我在更新状态时对此函数添加了调用。 这解决了我的问题。

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

拥有的窗口的一项功能是,当其所有者被隐藏时,它们也将被隐藏。 所以直到您调用m_pMainWnd->ShowWindow(SW_SHOW); ,您自己的对话框也不会显示。

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

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

听起来您的“昂贵的东西”是受计算限制的,不允许更新任何UI线程。 这些类型的问题通常通过利用单独的线程来提供进度反馈来解决。 您可能想看看“ 使用工作线程”,以获取一些有关使用线程解决此类问题的背景知识。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM