I don't know if what I am asking is possible but let me see if I can describe it. I have several utility functions that are put together to do a task. Each function outputs string data to a text file. I would like to use each of these functions in a worker thread, and have my thread post messages to the main UI rich textbox. The same data I am writing to the text file.
My question is, what is the best way to implement this without coding post messages everywhere in my utility functions. Since all the worker thread sees is "StartTask()" it won't know when to post the message to the UI. My idea was to pass the pointer of a class to the utility functions that would contain the string data, but I still don't know how I can have the worker thread post messages to the UI everytime text is available.
Here is some more clarification:
I want to add the class Analysis which already has code to output text to a file. I want to find a way to use my NotifyUI inside the Analysis class.
In my UI I have code to handle PostMessages from my thread:
LRESULT CMappingAnalysisDialog::OnUpdateStatus(WPARAM, LPARAM lParam)
{
// Put in shared_ptr so it is automatically destroyed.
CString* msg = reinterpret_cast<CString*>(lParam);
SetDlgItemText(IDC_STATIC_STATUS_TEXT, *msg);
delete msg;
return 0;
}
In my WorkerThread I have:
void NotifyUI( UINT uNotificationType )
{
// Check if the hWnd is still valid before posting the message
// Note: use PostMessage instead of SendMessage because PostMessage
// performs an asynchronous post; whereas SendMessage sends synchronously
// (sending synchronously would kind of defeat the purpose of using a
// worker thread)
if( ::IsWindow( m_hWnd ) )
{
switch( uNotificationType )
{
case NOTIFY_INC_PROGRESS:
::PostMessage( m_hWnd, WM_USER_INC_PROGRESS, 0, 0);//LPARAM data goes here);
break;
case NOTIFY_UPDATE_STATUS_TEXT:
::PostMessage(m_hWnd, WM_USER_UPDATE_STATUS_TEXT, 0, reinterpret_cast<LPARAM>(new CString(updateMessage)));
break;
case NOTIFY_UPDATE_EVENT_TEXT:
::PostMessage( m_hWnd, WM_USER_UPDATE_EVENT_TEXT, 0, reinterpret_cast<LPARAM>(new CString(updateMessage)));
break;
case NOTIFY_UPDATE_OUTPUT:
::PostMessage( m_hWnd, WM_USER_UPDATE_OUTPUT, 0, reinterpret_cast<LPARAM>(new CString(updateMessage)));
break;
case NOTIFY_THREAD_COMPLETED:
::PostMessage( m_hWnd, WM_USER_THREAD_COMPLETED, 0, 0 );
break;
default:
ASSERT( 0 );
}
}
}
static UINT WINAPI ThreadProc( LPVOID lpContext )
{
// Turn the passed in 'this' pointer back into a CMappingLog instance
CMapFaultAnalysis* pThis = reinterpret_cast< CMapFaultAnalysis* >( lpContext );
CAnalysis analysis;
CString output;
CString status;
//Thread work
for(int j = 0; j < 3; j++)
{
pThis->updateMessage = "Starting Analysis";
pThis->NotifyUI(NOTIFY_UPDATE_EVENT_TEXT);
for(int i = 0; i < 20; i++)
{
anaysis.RunAnalysis()
}
}
//REPORT END OF THREAD
pThis->NotifyUI(NOTIFY_THREAD_COMPLETED);
return 1;
}