【问题标题】:Scrollbar messages block interthread messages in MFC滚动条消息阻止 MFC 中的线程间消息
【发布时间】:2015-05-29 17:17:25
【问题描述】:

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

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

计算开始后,状态调度程序将带有状态的消息发送到 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)
  {
      //...
  }
};

提前致谢, 加尔

【问题讨论】:

    标签: multithreading mfc messages


    【解决方案1】:

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

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

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

    【讨论】:

    • 我还有其他被阻止的消息,但它们应该由线程而不是窗口接收。我能对他们做些什么?
    • 由于上面引用的原因 PostThreadMessage 不应该用于发布到显示任何 GUI 的线程。线程可以创建一个不可见的窗口来接收线程间消息给 HWND。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      相关资源
      最近更新 更多