MFC - Публикация данных через PostMessage в GUI - PullRequest
0 голосов
/ 30 марта 2012

Я прочитал несколько потоков о том, как передавать данные из Workerthread в главное окно (диалог), но я все еще не понимаю и все еще нуждаюсь в помощи. Мой рабочий поток должен обрабатывать некоторые вычисления и отображать результат во время каждого цикла для редактирования в графическом интерфейсе. Я знаю, я должен использовать PostMessage, но так как вычисления, которые я делаю, подразумевают элемент управления, я не знаю, как решить эту проблему ...

 //CWorkerThreadMgr.h manages the second thread
HRESULT Start (HWND hWnd);// from where the workerthread will be started 

 HWND  m_hWnd ;    //Window handle to the UI ;

 HANDLE m_hTread;  //handle of the worker thread

 static UINT WINAPI ThreadProc( LPVOID lptest ); 

static UINT WINAPI ThreadProc( LPVOID lptest ) 

{    
  CWorkerThreadMgr* pCalculateMgr = reinterpret_cast< CWorkerThreadMgr*(lptest);

//The following operation:rand() *m_Slider.GetPos() should

//should be calculated and the result displayed each time in the edit box in the gui

for( UINT uCount = 0; uCount < 40; uCount++ ){ 

pCalculateMgr->rand() *m_Slider.GetPos();//?don't allowed to touch the gui!! 

PostMessage(pCalculateMgr-> m_hWnd, WM_SENDCALCULATED_VALUE,wparam(rand() *m_Slider.GetPos(),0); 
} 
} 

LRESULT CStartCalculationDlg::OnSendCalculatedValue( WPARAM Result, LPARAM )

{ 
    // The resut should be displayed in the edit box

      m_Calculation.Format(_T("%d"),???); 
      SetDlgItemText(IDC_CALCULATION, m_Calculation); 

     return 1; 
} 

void CStartCalculationDlg::OnHScroll(UINT nSBCode, UINT nPos,CScrollBar* pScrollBar) 
{ 
  m_SliderValue.Format(_T("%d"),m_Slider.GetPos()); 
  SetDlgItemText(IDC_SLIDER_VALUE,m_SliderValue); 
} 

// Implementation in the CStartCalculationDlg.h 

CWorkerThreadMgr   m_WorkerThreadMgr  //instance of the WorkerThreadMgr 
CSliderCtrl  m_Slider  //member variable of the slider control 
CString m_SliderValue  // member variable of the edit box, where the current value of the 
                       //slider will be displayed 
CString  m_Calculation // member variable of the edit box where the calculated 
                       //result from  the workerthread will be displayed via PostMessage 
afx_msg LRESULT OnSendCalculatedValue( WPARAM, LPARAM ); 
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); 

Следующая проблема заключается в том, что, когда мой ползунок перемещается и получает новое значение, процедура потока должна знать это и обновлять значение ползунка. Как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 02 апреля 2012

Из рабочего потока:

m_data = foo();
PostMessage(hWndMain, UWM_SOME_CUSTOM_MESSAGE, 0, 0);

Из потока пользовательского интерфейса:

LRESULT CMainFrame::OnSomeCustomMessage(WPARAM wParam, LPARAM lParam)
{
    CMyData data = m_pWorker->GetData();
    // Do stuff...
    return 0;
}

GetData должен быть защищен критической секцией:

CMyData CMyWorker::GetData()
{
     // This critical section is used in the worker thread too, whenever m_data is accessed.
     m_lock.Lock();
     CMyData data = m_data;
     m_lock.Unlock();

     return data;
}

См. CCriticalSection в MSDN.

0 голосов
/ 30 марта 2012

Вместо чтения положения ползунка из рабочего потока, прочитайте его в потоке пользовательского интерфейса и сделайте его доступным для рабочего потока.

Я действительно не эксперт в этой области, но я сделал несколько рабочих потоков, как объяснено здесь .

В вашем случае я бы создал статическую переменную, такую ​​как флаг «бег», используемый в статье, указанной выше, для хранения текущей позиции ползунка. Затем в обработчике OnHScroll установите для него соответствующее значение.

Пока вы пишете в эту переменную только из одного потока, у вас не должно быть проблем с синхронизацией.

...