如何从工作线程访问MFC控件

How to access an MFC control from a worker thread?

本文关键字:访问 MFC 控件 线程 工作      更新时间:2023-10-16

从工作线程访问MFC控件的最佳方法是什么?

访问控件的MFC惯用方法是什么?

我在这里阅读http://www.flounder.com/workerthreads.htm以下方法,但我不太喜欢CString中的new,我怎么能确定CString将正确地成为deleted ?

typedef struct tagTP
{
   HWND hwnd;
   int n;
} TP;
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
   // ...
   ON_MESSAGE( UWM_UPDATE_RESULTS, OnUpdateResults )
END_MESSAGE_MAP()
void CMyDlg::OnBnClickedDoWork()
{
   TP* tp = new TP;
   tp->hwnd = m_hWnd;
   tp->n = 42;
   AfxBeginThread( doWork, tp );
}
UINT CMyDlg::doWork(LPVOID p)
{
   TP* tp = reinterpret_cast< TP* >(p);
   CWnd* dlg = FromHandle( tp->hwnd );
   if ( tp->n == 42 ) {   
      CString* s = new CString( "Is the Answer to the Ultimate Question of Life, the Universe, and Everything" );
      dlg->PostMessage( UWM_UPDATE_STATUS, 0, reinterpret_cast< LPARAM >(s) );
   }
   return 0;
}
LRESULT CMyDlg::OnUpdateResults(WPARAM,LPARAM lParam)
{
   CString* s = reinterpret_cast<CString *>(lParam);
   m_result.AddString( *s );// m_result is a CListBox
   delete s;
   UpdateData( FALSE );
   return 0;
}

使用PostMessage(..)是正确的。考虑使用SendMessage(..)——它会一直阻塞直到完成。向新对象传递指针是很常见的——检查PostMessage(..)的返回值来检查它是否被发布。

如何确保CString将被正确删除?

如前所述,检查PostMessage(..)的返回值,并在退出消息循环的情况下计算整个消息队列

作为一般规则,MFC控件只能从创建它们的线程访问。这就是为什么您找到的示例要经过传递消息的额外步骤的原因。创建控件的线程接收并处理该消息。

在onupdaterresults()中正确删除了CString。

除了@Simon的答案,如果你有一个更复杂的场景,很难弄清楚谁应该删除CString(或任何类型),考虑std::tr1::shared_ptr。它会负责删除