Hello my fellow colleagues from CodeProject!
I will try to be brief, so I will cut to the point:
I work on Windows XP, in C++, using pure Win32 to create a dialog box.
That dialog box has some edit controls, and OK button, which activates a thread when pressed.
Thread then gathers text from edit controls and writes them into MS Word document, using OLE Automation.
Everything works fine,when I press OK button, and wait for thread to show filled Word document.
However, when I push the OK button and then close the dialog, while thread is in the middle of the work, a blank Word document pops up.
To further illustrate my problem here are some code snippets:
This is snippet for thread function:
DWORD WINAPI TabelaSvihObjekata( LPVOID hWnd ) {
HWND hwnd = (HWND)hWnd;
CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid);
}
In dialog box, this is the snippet for button handler:
case IDOK:
{
DWORD threadID;
HANDLE threadHandle = CreateThread( NULL , 0 ,
(LPTHREAD_START_ROUTINE)TabelaSvihObjekata ,
(void*)hwnd , 0 ,
&threadID );
if( !threadHandle )
{
MessageBox( hwnd, L"Error", L"Error", MB_ICONERROR );
EndDialog( hwnd, IDCANCEL );
}
CloseHandle( threadHandle );
}
break;
And this is the problematic handler:
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
My question is:
What should I add or change, so when I close the dialog box, Word application closes along with threads destruction ?
I have looked on MSDN for a clue, and have found only ExitThread as a solution, but I don't know how to use it properly since I am inexperienced with threads.
If there is anything else that I can do to help, ask and I will gladly do it.
Thanks to everybody who tries to help.
EDIT #1:
-----------------
According to suggestion made by member
pasztorpisti, the improvements that I have came up with will be shown bellow.
Before that, I must point out that I didn't test this code, since I would like it to be verified first by experienced colleagues.
Here are the code snippets, discussed above:
Thread function changes:
-Passed LONG value instead of HWND to terminate thread properly.
-Query is performed inside thread function, so the GUI can be left "untouched".
Sample snippet:
DWORD WINAPI TabelaSvihObjekata( LPVOID StopThreadExecution )
{
LONG exit = ( LONG ) StopThreadExecution;
DWORD result = 0;
while( InterlockedExchange( &exit , 0 ) != 0 )
{
try
{
CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid);
break; }
catch( _comm_error & )
{
result = 1;
break; }
}
return result;
}
Dialog box changes:
-Added LONG variable which will be used for stopping the thread.
-Changed the declaration of thread handle, so WaitForSingleObject can be used properly.
-Changed parameter for CreateThread in IDOK handler.
-Added statement that stops thread, and WaitForSingleObject to IDCANCEL handler.
Sample snippet:
LONG StopThreadExecution = 0;
HANDLE threadHandle = NULL;
case IDOK:
{
DWORD threadID;
threadHandle = CreateThread( NULL , 0 ,
(LPTHREAD_START_ROUTINE)TabelaSvihObjekata ,
(void*) StopThreadExecution, 0 ,
&threadID );
if( !threadHandle )
{
MessageBox( hwnd, L"Error", L"Error", MB_ICONERROR );
EndDialog( hwnd, IDCANCEL );
}
CloseHandle( threadHandle );
}
break;
case IDCANCEL:
InterlockedExchange( &StopThreadExecution, 1 );
if( threadHandle != NULL )
WaitForSingleObject( threadHandle, INFINITE );
EndDialog( hwnd, IDCANCEL );
break;