Search code examples
winapinotepad

Why does WM_CLOSE/DESTROY only partially close my Notepad window?


My scenario is that a program calls my DLL and I use Process.Start(notepad) to start a Notepad window on Windows 10 x64. I don't save the process ID of the started process. Then sometime later, a program calls my DLL again, and I find the Notepad window handle (by matching title strings).

The problem is that when I use the handle to send the window a WM_CLOSE or DESTROY message, the job isn't completed. The window does disappear from my screen. It does disappear from the taskbar. But when I look at windows with Alt-TAB, there it is. It's not really gone; it's just hidden from the taskbar. I'm using this Win32 API call to try to close the window.

[DllImport ("user32.dll", SetLastError = true)]
public static extern bool CloseWindow (IntPtr hWnd);

(1) What am I doing wrong?

(2) Are my expectations out of line? Is it even possible for me (as a DLL running under one process) to order Notepad in another process to close?

I suppose, having the Notepad handle in hand, that I could bring it to the foreground and send Alt+F4 to its keyboard buffer somehow to fake it into thinking that I was typing characters to it. But, that seems like the long way around.

(3) How can I programmatically tell apps to close their windows without bringing them to the foreground and sending them keystrokes, or without sending them mouse clicks on the X close button?

I've looked at other posts on the forum, but they mostly talk about terminating the process with the process APIs - a brute force kill method that isn't really what I want to do. (Besides, I want to close the single window that I'm interested in, not a whole process that might be running a dozen different windows like MS Word...)


Solution

  • I'm using [CloseWindow] to try to close the window.

    CloseWindow doesn't close a window -- it minimizes it.

    Instead, send the window a WM_CLOSE message:

    SendMessage(h, WM_CLOSE, 0, 0);