Just because PostThreadMessage() is successfull, doesn't mean that the message was processed.
Anyways, as it turns out, PostThreadMessage() isn't enough to get the job done.
Here is another example application that demostrates the points in this article (which uses VB but uses the Win32 API all the same).
Code:
#include <windows.h>
#include <iostream>
using namespace std;
BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam)
{
BOOL ret = PostMessage(hwnd, WM_CLOSE, 0, 0);
if (!ret)
{
cerr << "PostMessage(WM_CLOSE) failed, ec = "
<< GetLastError() << endl;
}//if
return TRUE;
}//EnumThreadWndProc
int main()
{
PROCESS_INFORMATION pi = {0}; // always zero out structs
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_MAXIMIZE;
BOOL ret = CreateProcess(NULL, "Notepad.exe", NULL, NULL, FALSE,
0, NULL, NULL, &si, &pi);
if (!ret)
{
cerr << "CreateProcess() failed, ec = " << GetLastError() << endl;
return 1;
}//if
cout << "Process created." << endl;
// give the process a chance to startup
Sleep(1000);
// send all the top level windows of the process thread WM_CLOSE
ret = EnumThreadWindows(pi.dwThreadId, EnumThreadWndProc, 0);
if (!ret)
cerr << "EnumThreadWindows() failed, ec = " << GetLastError() << endl;
// give the process up to 5 seconds to process the WM_CLOSE, if we failed
// to post any messages, then don't wait at all
DWORD timeout = 5000;
if (!ret)
timeout = 0; // don't wait at all
// see if the process is still running
bool isRunning = WaitForSingleObject(pi.hProcess, timeout) == WAIT_TIMEOUT;
if (isRunning)
{
cout << "Process still running, using TerminateProcess()..." << endl;
ret = TerminateProcess(pi.hProcess, 0);
if (!ret)
cerr << "TerminateProcess() failed, ec = " << GetLastError() << endl;
else
cout << "Process terminated via TerminateProcess()" << endl;
}//if
else
{
cout << "Process received WM_CLOSE successfully" << endl;
}//else
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}//main
gg