Reputation: 3446
I want to send wm_close to another process, with which i want end that process safely.
int _tmain(int argc, _TCHAR* argv[])
{
DWORD SetOfPID;
SetOfPID = GetProcId(_T("abc.exe")); //this will return pid
HANDLE h = OpenProcess(PROCESS_ALL_ACCESS,false, SetOfPID);
HWND hwnd = ::GetTopWindow(NULL);
while(hwnd)
{
DWORD pid;
DWORD dwThreadId = ::GetWindowThreadProcessId(hwnd, &pid);
if(pid == SetOfPID)
{
break;
}
hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
}
//DestroyWindow(hwnd);
bool temp = IsWindow(hwnd); **//this gives true**
LRESULT res = ::SendMessage(hwnd, WM_CLOSE, NULL, NULL);
DWORD err = GetLastError(); **//this gives 6**
CloseHandle(hwnd);
CloseHandle(h);
return 0;
}
this piece of code looks good, but the target process doesn't terminate, can somebody help me?
Upvotes: 5
Views: 28605
Reputation: 1728
I found an example of sending messages to a different processes window from Tonto that uses a different method of finding the window to send to.
It uses EnumWindows() to walk over the windows. When it finds the one with the matching PID it sends the message.
Here is a slightly modified version (the same but sends a sends the WM_CLOSE):
#include <windows.h>
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if(lParam == processId)
PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
}
int main(int argc, char *argv[])
{
STARTUPINFO siInfo;
PROCESS_INFORMATION piInfo;
ZeroMemory(&siInfo, sizeof(siInfo));
ZeroMemory(&piInfo, sizeof(piInfo));
CreateProcess
("C:\\WINDOWS\\Notepad.exe", "", 0, 0,
FALSE, CREATE_DEFAULT_ERROR_MODE, 0, 0,
&siInfo, &piInfo);
WaitForSingleObject(piInfo.hProcess, 1000);
EnumWindows(&EnumWindowsProc, piInfo.dwProcessId);
return 0;
}
This starts C:\WINDOWS\Notepad.exe waits a second and then sends the WM_CLOSE.
This opened notepad and then closed it. When I tried it with my program instead it also worked, so I think you are having problems find the right window to send the message to.
NOTE that there is no error checking in this example.
Upvotes: 0
Reputation: 31
I would attempt to close a (Process with) Window(s) in the following order:
WM_CLOSE
WM_QUIT
WM_DESTROY
TerminateProcess().
Just my take as I am handling (disabling) WM_CLOSE
for a Window and having difficulty distinguishing between User Close and close messages send by another master task. WM_QUIT
seems to resolve my problem without using a custom WM_APP_CLOSE
of my own. TerminateProcess
is very much a last resort unclean exit to be avoided at all costs (it may leave handles (e.g. COM etc) and memory etc unfreed).
Upvotes: 3
Reputation: 35448
If the application does not process WM_CLOSE the DefWindowProc should handle this (by gracefully closing the application), however if the application is handling WM_CLOSE then it simply can choose to ignore it. Try sending the WM_DESTROY and WM_NCDESTROY messagees instead.
Upvotes: 0
Reputation: 665
Are you sure that the window you are finding is the correct one? You can check easily with Spy++. Moreover, when searching for a window, I think it's better to use EnumWindows. I'm not sure your method is correct.
Upvotes: 2