1
I’m trying to modify the library win10toast
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’ve mastered as much as I can 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 code of the received message. What I would like to happen is that by clicking or interacting with the notification, that callback gets the interaction message, since the window is connected to the notification.
The documentation of 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 from the window itself, and not the notification, are coming:
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 of WM_NCDESTROY
and 144 don’t know, but it happens even when the notification is not created, so it doesn’t seem to have any relation to it.
How do I receive events related to notification?
Perfect! The
lparam
of the message1044
is1028
if the notification expires without clicking, and1029
expires because of the click. Thank you very much!– Pedro von Hertwig Batista