Re: destroying a window on windows

eryk sun <[email protected]> Thu, 18 May 2017 20:29:48 +0000
Newsgroups gmane.comp.python.ctypes
Message-ID <CACL+1as1+1KH7k4L8ysCSoBY-HaEsC-jmcw8LQPMc9i6-w-vXQ@mail.gmail.com>
On Thu, May 18, 2017 at 3:41 PM, Michael C
<[email protected]> wrote:
> Ok, I tried to read
> https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx
>
> But it doesn't say which one it belongs to, User32 or Kernel32... I guess
> 'User-defined function name' is something I have never seen before, I see
> that I should send this to the application:
>
> #define WM_CLOSE                        0x0010
>
> But I haven't figured out how.

Please read About Messages and Message Queues [1]. Then scan back to
the Posting and Sending Messages section. Note that the documentation
talks about queued vs nonqueued messages, but under the hood it's
really two message queues with different behavior for posted messages
vs sent messages.

A thread that posts a message to a window via PostMessage doesn't wait
for a result from the owning thread. The message gets appended to the
posted message queue of the owning thread, which can retrieve it via
GetMessage or PeekMessage and dispatch it to the window procedure via
DispatchMessage. There's also a PostThreadMessage function that allows
posting a message to a thread without specifying a target window. The
thread has to handle the message in its message loop since there's no
target window and thus no window procedure to which the message can be
dispatched.

A thread that sends a message to a window via SendMessage waits for a
return value, so it has to block on an internal event object that will
be signaled after the window's owning thread has processed the
message. When the receiving thread checks its message queue (i.e.
calls GetMessage, PeekMessage, or WaitMessage), the system
automatically dispatches messages from the thread's sent message
queue. There are also variants on sending: SendMessageTimeout,
SendMessageCallback (use a callback function instead of waiting), and
SendNotifyMessage (don't wait when sending to another thread).

For example, the following console script closes its console window,
thus terminating all processes that are attached to the console:

    #!/usr/bin/python3
    import ctypes
    from ctypes import wintypes

    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
    user32 = ctypes.WinDLL('user32', use_last_error=True)

    WM_CLOSE = 0x0010

    def _check_zero(result, func, args):
        if not result:
            raise ctypes.WinError(ctypes.get_last_error())
        return args

    kernel32.GetConsoleWindow.errcheck = _check_zero
    kernel32.GetConsoleWindow.restype = wintypes.HWND
    user32.PostMessageW.errcheck = _check_zero
    user32.PostMessageW.argtypes = (wintypes.HWND, wintypes.UINT,
        wintypes.WPARAM, wintypes.LPARAM)

    hWnd = kernel32.GetConsoleWindow()
    user32.PostMessageW(hWnd, WM_CLOSE, 0, 0)

[1]: https://msdn.microsoft.com/en-us/library/ms644927

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot