Как получить доступ к элементу управления MFC из рабочего потока? - PullRequest
1 голос
/ 25 августа 2011

Каков наилучший способ доступа к элементу управления MFC из рабочего потока?

Что такое идиоматический способ доступа к элементу управления MFC?

Я прочитал здесь http://www.flounder.com/workerthreads.htmследующий подход, но мне не очень нравится new из CString, как я могу быть уверен, что 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;
}

Ответы [ 3 ]

0 голосов
/ 25 августа 2011

Как правило, доступ к элементам управления MFC возможен только из потока, который их создал.Это причина, по которой образец, который вы нашли, проходит дополнительный этап передачи сообщения.Сообщение получено и обработано потоком, который создал элемент управления.

Строка CString должным образом удалена в OnUpdateResults ().

0 голосов
/ 25 августа 2011

В дополнение к ответу @ Simon, если у вас есть более сложный сценарий, в котором сложнее определить, кто должен удалить CString (или любой другой тип), рассмотрим std :: tr1 :: shared_ptr. Он позаботится об удалении.

0 голосов
/ 25 августа 2011

Использование PostMessage (..) правильно. Попробуйте использовать SendMessage (..) - какой блок до конца. Передача указателя на новый объект является обычной практикой - проверьте возвращаемое значение PostMessage (..), чтобы проверить, был ли он опубликован или нет.

как я могу быть уверен, что CString будет правильно удален?

Как уже упоминалось, проверьте возвращаемое значение PostMessage (..) и обработайте всю очередь сообщений в случае выхода из цикла сообщений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...