I'm trying to modify the win10toast
library so that I can pass a callback that runs when the user clicks on the Windows 10 notification that I show.
The "meat" of the library, which I condested as much as I could to create a minimal and functional example, is here:
from win32api import GetModuleHandle
from win32api import PostQuitMessage
from win32con import CW_USEDEFAULT
from win32con import WM_DESTROY
from win32con import WM_USER
from win32con import WS_OVERLAPPED
from win32con import WS_SYSMENU
from win32gui import CreateWindow
from win32gui import DestroyWindow
from win32gui import NIF_ICON
from win32gui import NIF_INFO
from win32gui import NIF_MESSAGE
from win32gui import NIF_TIP
from win32gui import NIM_ADD
from win32gui import NIM_DELETE
from win32gui import NIM_MODIFY
from win32gui import RegisterClass
from win32gui import UnregisterClass
from win32gui import Shell_NotifyIcon
from win32gui import UpdateWindow
from win32gui import WNDCLASS
import time
# Callback de evento da janela
def on_proc(hwnd, msg, wparam, lparam):
print(f'Recebido evento de janela, mensagem: {msg}')
if msg == WM_DESTROY:
nid = (hwnd, 0)
# Destruir a notificação quando a janela for destruída
Shell_NotifyIcon(NIM_DELETE, nid)
PostQuitMessage(0)
return None
# Criar janela à qual a notificação pertence (0x0)
wc = WNDCLASS()
hinst = wc.hInstance = GetModuleHandle(None)
wc.lpszClassName = str("PythonTaskbar") # must be a string
wc.lpfnWndProc = on_proc
classAtom = RegisterClass(wc)
style = WS_OVERLAPPED | WS_SYSMENU
hwnd = CreateWindow(classAtom, "Taskbar", style,
0, 0, CW_USEDEFAULT,
CW_USEDEFAULT,
0, 0, hinst, None)
UpdateWindow(hwnd)
# Criar a notificação
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid = (hwnd, 0, flags, WM_USER + 20, None, "Tooltip")
Shell_NotifyIcon(NIM_ADD, nid)
# Mostrar a notificação
Shell_NotifyIcon(NIM_MODIFY, (hwnd, 0, NIF_INFO,
WM_USER + 20,
None, "Balloon Tooltip", "Hello, SO PT", 200, "Título"))
# Esperar 3 segundos e destruir a janela
time.sleep(3)
DestroyWindow(hwnd)
UnregisterClass(wc.lpszClassName, None)
When the window receives an event message, such as the destroyed window, the callback on_proc
is called and displays the received message code. What I would like to happen is that by clicking or interacting with the notification, this callback would receive the interaction message, since the window is linked to the notification.
The documentation for Official Windows API seems to indicate that in fact, the window associated with the notification should receive its events:
Type: HWND
A handle to the window that receives notifications associated with an icon in the notification area.
Unfortunately, the program output shows that only the messages in the window itself, not the notification, are arriving:
Recebido evento de janela, mensagem: 144
Recebido evento de janela, mensagem: 2
Recebido evento de janela, mensagem: 130
Here, code 2 warns of the event WM_DESTROY
, the 130 WM_NCDESTROY
and the 144 do not know, but it happens even when the notification is not created, so it does not seem to be related to it.
How do I receive notification-related events?