I am looking for a way to watch for specific messages sent by the system to my application. For example, I want to be able to watch for the WM_QUERYENDSESSION message and when it is received, to perform a specific action.

I am working with the python win32 extensions, but I'm sure that I could translate the equivalent code in another language.

I know how to use SendMessage to send messages to other windows, but I don't know what to use to watch for messages sent to my window.

Any help is appreciated.

Dani AI

Generated

Short answer: you must have a window (real or message-only) with a WndProc and a running message loop. was on the right track with a WndProc, but WM_QUERYENDSESSION is a top-level window message (not a WM_COMMAND notification) and should be handled directly in your WndProc. 's pointer to "window hooking" is an alternative but is heavier and usually unnecessary for this task.

A compact pywin32 approach: register a window class with a Python WndProc, create a hidden/message window, then run the message pump. Handle WM_QUERYENDSESSION to indicate whether shutdown can proceed, and handle WM_ENDSESSION to perform final cleanup (do the real work here). Keep WM_QUERYENDSESSION handling fast — do not perform long I/O there.

Example (pywin32):

import win32con
import win32gui
import win32api

def WndProc(hwnd, msg, wParam, lParam):
    if msg == win32con.WM_QUERYENDSESSION:
        # quick check/save; return nonzero to allow shutdown
        return 1
    if msg == win32con.WM_ENDSESSION:
        if wParam:  # session is ending
            # perform cleanup here
            pass
    return win32gui.DefWindowProc(hwnd, msg, wParam, lParam)

wc = win32gui.WNDCLASS()
hinst = wc.hInstance = win32api.GetModuleHandle(None)
wc.lpszClassName = "PyMsgWindow"
wc.lpfnWndProc = WndProc
win32gui.RegisterClass(wc)
hwnd = win32gui.CreateWindow(wc.lpszClassName, "msg", 0, 0, 0, 0, 0, 0, 0, hinst, None)
win32gui.PumpMessages()

Notes and gotchas:

  • Return nonzero from WM_QUERYENDSESSION to allow shutdown, zero to veto. Modern Windows may ignore vetoes or enforce timeouts; do not rely on blocking shutdown.
  • Do actual saving/cleanup in WM_ENDSESSION (wParam True) or set a flag in WM_QUERYENDSESSION and finish quickly.
  • If your app uses a GUI toolkit, get its HWND (e.g., Tkinter.winfo_id(), PyQt winId()) and either subclass carefully or create a separate message-only window to avoid breaking the toolkit.
    References: Microsoft WM_QUERYENDSESSION documentation (details on return values and behavior) and the pywin32 project for the win32gui APIs (WM_QUERYENDSESSION docs, pywin32 on GitHub).

Recommended Answers

All 3 Replies

in c++ you would go:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		    case WM_QUERYENDSESSION:
                    {
                        //the action to use when it receives this message
                    }
		}
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

hope that helps :)

Here's a nice thread about it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.