I have a dialog box with a Save button.
When that button is clicked, I should populate excel with data from database.
To do that, I have modified code from here:
http://support.microsoft.com/kb/216686[
^], which suites my purposes .
The problem is that this operation is lengthy and doesn’t allow user to use GUI until it is finished.
That is why I have decided to put Excel automation in a thread function, and to launch thread when Save button is clicked.
Earlier, I have posted here on CP, questions about multithreading, but have decided to stay away from it, since I am inexperienced.
I have decided to hide the Save button while thread is running, to prevent other threads being spawned with multiple clicks on a Save button.
This will ensure that there will be only one thread running, and will avoid thread synchronization.
I have created thread function which does the Excel automation as above, and it works.
The problem is that zombie process can appear ( Excel doesn’t close ) if the user interrupts thread execution by closing the dialog box, or closing the program.
That is my problem:
How to close dialog box/main window and to abort thread properly, so the zombie process does not appear ?
I work on Windows XP using MS Visual C++ and pure Win32 API ( no MFC ).
NOTE:
Here is what I have so far:
My thread function:
struct ThreadData
{
HWND hDlg; int PrimaryKey; };
DWORD WINAPI MyThread( LPVOID lp )
{
ThreadData* td = (ThreadData*)lp;
wchar_t query[100];
swprintf_s( query, 100,
L"select * from MyTable where Primary_Key = %d ;",
td->PrimaryKey);
HRESULT hr;
try
{
CoInitialize(NULL);
hr =
return 0;
}
catch( _comm_error & ) {
return 1;
}
}
Dialog box snippet:
INT_PTR CALLBACK DialogBoxProcedure(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
static ThreadData td;
HANDLE threadHandle = NULL;
static int primaryKey;
switch(Message)
{
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDCANCEL:
if( threadHandle )
{
WaitForSingleObject( threadHandle, INFINITE );
CloseHandle( threadHandle );
}
DestroyWindow(hwnd);
break;
case IDC_BUTTON1:
{
ShowWindow( GetDlgItem( hwnd, IDC_SAVE ),
SW_HIDE );
td.hwnd = hwnd;
td.PrimaryKey = primaryKey;
DWORD threadID;
threadHandle = CreateThread( NULL,
0,
MyThread,
(void*)&td,
0,
&threadID );
if( !threadHandle )
{
MessageBox( hwnd, L"Error", L"Error",
MB_ICONERROR );
DestroyWindow(hwnd);
}
}
break;
}
}
}
}
IMPORTANT UPDATE:
Code for Excel generation is too big, but since I have a similar thread that populates predefined Word document, here is the link to that thread procedure, since the abort mechanism is practically the same:
http://pastebin.ca/2441960[
^]