5

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?

rplusg
  • 3,418
  • 6
  • 34
  • 49
  • 2
    Why are you opening the process? That seems unnecessary. Error 6 means an invalid handle. You shouldn't call CloseHandle on a window handle. You don't need to tidy up the window handle, it's not a HANDLE. – David Heffernan Mar 23 '11 at 07:52
  • i was trying something else, so opening process is part of that. And i know error 6. You shouldn't call CloseHandle on a window handle --> thanks alot for this. – rplusg Mar 23 '11 at 08:23
  • 2
    Sending the WM_CLOSE message to the main form of an app does result in it closing, if that window responds to WM_CLOSE. I can't imagine what you are doing wrong. My recommendation is to use Spy++ to check that you have located the right window handle. – David Heffernan Mar 23 '11 at 09:42

3 Answers3

3

I would attempt to close a (Process with) Window(s) in the following order:

  1. WM_CLOSE

  2. WM_QUIT

  3. WM_DESTROY

  4. 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).

Community
  • 1
  • 1
mattjs
  • 31
  • 2
2

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.

pagra
  • 665
  • 4
  • 11
  • IsWindow() returns true, doesn't it mean i've a valid window? – rplusg Mar 23 '11 at 08:27
  • 1
    @rplusg: IsWindow tells you it is a valid window handle, not more. It can be that the application has got several top level windows, maybe not visible. And you may not close the right one. – pagra Mar 23 '11 at 12:29
  • even i'm not sure what is the problem, but enumwindows has given my desired results. Thanks patriiice, marking your answer as final. – rplusg Mar 28 '11 at 08:00
0

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.

Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167