滚动条消息阻塞 MFC 中的线程间消息

Scrollbar messages block interthread messages in MFC

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

  1. 第一个线程(CGuiThread)负责GUI(它不是主线程)并且包含一个window对象(CMainWindow),它包含一个内部window对象(CInnerWindow),它显示多个进度显示并有一个滚动条。
  2. 第二个线程(CStatusDispatcherThread)负责向gui线程发送消息,其中包含一些计算过程相关的进度状态信息。

计算开始后,状态调度程序会将包含状态的消息发送到 GUI 线程。 gui 线程相应地更新内部 window 中的进度条。

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

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

我尝试了 "catching" 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)
  {
      //...
  }
};

提前致谢, 加尔

唯一允许更新 GUI 的线程是主线程。否则你最终会遇到意想不到的行为。

记录失败。来自 PostThreadMessage 的 MSDN 页面:

if the recipient thread is in a modal loop (as used by MessageBox or DialogBox), the messages will be lost.

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