开发者

How to access an MFC control from a worker thread?

What is the best way to access an MFC control from a worker thread?

What is the MFC idiomatic way of accessing a control?

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?

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 CMy开发者_高级运维Dlg::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. Consider using SendMessage(..) - which block until finished. Passing a pointer to a newed object is common - check the return value of the PostMessage(..) to check whether it was posted or not.

how can I be sure the CString will be properly deleted ?

As mentioned, check the return value of PostMessage(..) and work up the whole message queue in case of quiting the message loop.


As a general rule, MFC controls can only be accessed from the thread that created them. 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().


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. It will take care of deleting.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜