One thing to be aware of is that processes and programs (or at least what the user sees as a program) are not necessarily the same thing.
If you use PSAPI to get a list of all running processes, you will see a lot of background process that does not correspond to the open window at all. There are also cases where one process can open several top-level windows. Therefore, when you have simple cases, such as Notepad, where once the notepad.exe process corresponds to one Notepad window, you also have cases such as:
- A word in which one word processes all documents currently open (one process, many windows)
- Explorer, where one exploere.exe process handles all open explorer windows, as well as things like control panel windows and taskbar windows.
- Chrome (and other browsers) where each tab gets its own process (many processes, one window!)
Using TerminateProcess is probably not the best way to close the application: it is not equivalent to directly clicking the close button. He forcibly terminates the whole process there, and then, giving him no opportunity to clear. If you do this in Word when it restarts, it will go into "recovery mode" and will act as if it had not closed for the last time. This is best left as a last resort if the process stops responding. Also, if you terminate a process for a process such as Word or Explorer, you end up closing all windows that belong to that process, not just one specific one.
Given all this, if you want to essentially write some kind of program manager, you might be better off using a window-oriented approach rather than a process-oriented one. Instead of monitoring running processes, control top-level application windows.
There are several ways to listen for changes in windows; SetWinEventHook with EVENT_CREATE / DESTROY is one way to listen to HWNDs being created or destroyed (you will need to filter here, as it will tell you about all HWNDs - and much more!), But you only care about the top levels and only the applications). SetWindowsHookEx may have other options that may work here (WH_CBT). You can also use EnumWindows to display the currently present windows (again, you will need to filter your own dialogs and tooltips that are currently invisible to HWNDs, etc.).
Given HWND, you can get process information, if necessary, using GetWindowThreadProcessId.
To close the window by sending WM_SYSCOMMAND / SC_CLOSE it is best to try first: this is closer to pressing the close button, and this gives the application the ability to clear. Please note that in some applications the message "Are you sure you want to close?" if you have not saved recently - again, this is consistent with clicking the close button with the mouse.