繁体   English   中英

我可以在MFC中有多个GUI线程吗?

[英]Can I have multiple GUI threads in MFC?

我有一个基于MFC的大型应用程序,它包含主线程中一些可能非常慢的任务。 这可以给出应用程序在实际执行长任务时挂起的外观。 从可用性的角度来看,我想向用户提供更多关于进度的反馈,并且可以选择以干净的方式中止任务。 虽然将长任务分解为单独的线程将是一个更好的长期解决方案,但我认为一个实用的短期解决方案是创建一个新的GUI线程,封装在自己的对象中,包括进度条和取消按钮,用于与CWait对象类似的方式。 主线程通过IsCancelled方法监视取消状态,并在需要时通过throw完成。

这是一种合理的方法,如果有的话,那里有一些我可以使用的MFC代码,或者我应该自己动手? 第一幅草图看起来像这样

class CProgressThread : public CWinThread
{
public:
    CProgressThread(int ProgressMax);      
    ~CProgressThread()
    void SetProgress(int Progress);
    BOOL IsCancelled();
private:
   CProgressDialog  *theDialog;
}

void MySlowTask()
{
   CProgressThread PT(MaxProgress);
   try
   {
       {
           {  // deep in the depths of my slow task
              PT.SetProgress(Progress);
              if (PT.IsCancelled())
                 throw new CUserHasHadEnough; 
           }
        }
    }
    catch (CUserHasHadEnough *pUserHasHadEnough)
    {
        // Clean-up
    }
}    

作为一项规则,我倾向于有一个GUI线程和许多工作线程,但这种方法可能会省去一堆重构和测试。 任何严重的潜在陷阱?

简而言之,是的,您可以在MFC中拥有多个GUI线程。 但是除了创建的线程之外,您无法直接访问GUI组件。 原因是因为MFC下的Win32存储了每个线程的GUI处理程序。 这意味着一个线程中的处理程序对另一个线程不可见。 如果跳转到CWinThread类源代码,可以在那里找到处理程序映射属性。

Windows(MFC)在工作线程和GUI线程之间没有硬性差异。 一旦创建了消息队列,就可以将任何线程更改为GUI线程,该消息队列是在与消息相关的第一次调用之后创建的,例如GetMessage()。

在上面的代码中,如果在一个线程中创建了进度条,而在另一个线程中调用了MySlowWork()。 您只能在不触及Win32 GUI相关功能的情况下使用CProgressThread属性,例如close,setText,SetProgress ......因为它们都需要GUI处理程序。 如果您确实调用了这些函数,则错误将无法找到指定的窗口,因为该处理程序不在线程处理程序映射中。

如果确实需要更改GUI,则需要将消息发送到该进度条所有者线程。 让该线程通过PostThreadMessage自己处理消息(消息处理程序) ,详细信息请参考MSDN

暂无
暂无

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

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