简体   繁体   English

如何从辅助线程访问MFC控件?

[英]How to access an MFC control from a worker thread?

What is the best way to access an MFC control from a worker thread? 从工作线程访问MFC控件的最佳方法是什么?

What is the MFC idiomatic way of accessing a control? MFC惯用的控件访问方式是什么?

I read here http://www.flounder.com/workerthreads.htm the following approach but I do not like very much the new of the CString , how can I be sure the CString will be properly deleted ? 我在下面的方法中阅读了http://www.flounder.com/workerthreads.htm ,但是我不太喜欢CStringnew ,如何确定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;
}

Using PostMessage(..) is correct. 使用PostMessage(..)是正确的。 Consider using SendMessage(..) - which block until finished. 考虑使用SendMessage(..) -直到完成为止。 Passing a pointer to a newed object is common - check the return value of the PostMessage(..) to check whether it was posted or not. 传递指向新对象的指针很常见-检查PostMessage(..)的返回值以检查其是否已发布。

how can I be sure the CString will be properly deleted ? 如何确定CString将被正确删除?

As mentioned, check the return value of PostMessage(..) and work up the whole message queue in case of quiting the message loop. 如前所述,检查PostMessage(..)的返回值,并在退出消息循环的情况下处理整个消息队列。

As a general rule, MFC controls can only be accessed from the thread that created them. 通常,只能从创建它们的线程访问MFC控件。 This is the reason why the sample you found goes through the extra step of passing a message. 这就是为什么您找到的样本经过传递消息的额外步骤的原因。 The message is received and processed by the thread that created the control. 该消息由创建控件的线程接收和处理。

The CString is properly deleted in OnUpdateResults(). CString已在OnUpdateResults()中正确删除。

In addition to @Simon's answer, if you have a more complicated scenario where it's harder to figure out who should delete the CString (or whatever type), consider std::tr1::shared_ptr. 除了@Simon的答案之外,如果您遇到的情况更加复杂,很难确定谁应该删除CString(或任何类型),请考虑std :: tr1 :: shared_ptr。 It will take care of deleting. 它将负责删除。

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

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