滚动条消息阻止MFC中的线程消息

时间:2015-03-25 20:21:23

标签: multithreading mfc messages

我有一个由多个线程组成的MFC应用程序,但问题在于特定的两个。

  1. 第一个线程(CGuiThread)负责GUI(它不是主线程)并包含一个窗口对象(CMainWindow),它包含一个内部窗口对象(CInnerWindow),它显示多个进度显示并有一个滚动条。
  2. 第二个线程(CStatusDispatcherThread)负责向gui线程发送消息,其中包含与某些计算过程相关的进度状态信息。
  3. 计算开始后,状态调度程序将状态消息发送到GUI线程。 gui线程相应地更新内部窗口中的进度条。

    当我移动或握住内部窗口滚动条的拇指时,问题就开始了 - 似乎GUI线程停止处理来自状态调度程序线程的状态消息,因为进度条不再更新。不仅如此,我希望状态消息在某处停止并在我释放tumb后处理,但它不会发生。新消息到达但是点击时丢失的消息。

    如果有人知道可能是什么原因,我将非常感激。

    我尝试在CGuiThread :: PreaTranslateMessage函数中“捕获”状态消息,但似乎在按住滚动滑块之后,它们不再到达那里,即使CStatusDispatcherThread的PostThreadMessage指示它们已成功发送。

    #define MY_MESSAGE 1
    
    class CStatusDispatcherThread : public CWinThread
    {
      //... 
      
      // This class sends progress status percentaget to gui thread via PostThreadMessage
      OnTimer(UINT nIDEvent)
      {
          PostThreadMessage(iThreadID,MY_MESSAGE,100,0);
      }
    };
    
    class CGuiThread : public CWinThread
    {
      //...
      
    BEGIN_MESSAGE_MAP(CGuiThread, CWinThread)
      ON_THREAD_MESSAGE(MY_MESSAGE,OnStatusMessage)
    END_MESSAGE_MAP()
      
    private:
      CMyMainWindow m_mainWindow;
      
      void OnStatusMessage(WPARAM iStatus, LPARAM dummy);
      {
          m_mainWindow.updateStatus((int)iStatus)
      }
    };
    
    class CMyMainWindow : public CWnd
    {
      //...
      void updateStatus(int iStatus)
      {
          m_sbarWindow.updateStatusBar(iStatus);
      }
      
    private:
      CInnerWindow m_sbarWindow;
    }; 
     
    class CInnerWindow : public CWnd
    {
      //...
      
      void updateStatusBar(int iStatus)
      {
          //...
      }
    
    private:
      BOOL Create(...)
      {
          CWnd::Create(strClassName, strWindowTitle, WS_DLGFRAME | WS_CHILD| WS_VISIBLE | WS_VSCROLL,
            rectRectOfWnd, pParentWnd, iID, NULL);
      }
      
      void OnVScroll(nSBCode, nPos, pScrollBar)
      {
          //...
      }
    };

    提前感谢, 伽

2 个答案:

答案 0 :(得分:0)

允许更新GUI的唯一线程是主线程。否则你最终会有不可预知的行为。

答案 1 :(得分:0)

记录失败。从PostThreadMessage上的MSDN页面:

  

如果收件人线程处于模态循环中(如MessageBox或   DialogBox),消息将丢失。

按住滚动滑块可创建这样的模态循环。您可以通过发布到HWND而不是线程ID来消除问题。