I generate a basic notifications on my Windows 11 like this:
from win32api import *
from win32gui import *
import win32con
import sys, os
import struct
import time
class WindowsBalloonTip:
def __init__(self, title, msg, timeout):
message_map = {
win32con.WM_DESTROY: self.OnDestroy,
}
wc = WNDCLASS()
hinst = wc.hInstance = GetModuleHandle(None)
wc.lpszClassName = "PythonTaskbar"
wc.lpfnWndProc = message_map
classAtom = RegisterClass(wc)
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
self.hwnd = CreateWindow( classAtom, "Taskbar", style, \
0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
0, 0, hinst, None)
UpdateWindow(self.hwnd)
iconPathName = os.path.abspath(os.path.join( sys.path[0], "balloontip.ico" ))
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
try:
hicon = LoadImage(hinst, iconPathName, \
win32con.IMAGE_ICON, 0, 0, icon_flags)
except:
hicon = LoadIcon(0, win32con.IDI_APPLICATION)
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "tooltip")
Shell_NotifyIcon(NIM_ADD, nid)
Shell_NotifyIcon(NIM_MODIFY, \
(self.hwnd, 0, NIF_INFO, win32con.WM_USER+20,\
hicon, "Balloon tooltip",title,200,msg))
time.sleep(timeout)
DestroyWindow(self.hwnd)
def OnDestroy(self, hwnd, msg, wparam, lparam):
nid = (self.hwnd, 0)
Shell_NotifyIcon(NIM_DELETE, nid)
PostQuitMessage(0)
def balloon_tip(title, msg, timeout):
w=WindowsBalloonTip(msg, title, timeout)
if __name__ == '__main__':
balloon_tip(sys.argv[1], sys.argv[2], float(sys.argv[3]))
I keep two separate codes running simultaneously in a loop every 30 seconds and throughout the day, in case they both generate a notification at the same time (to shorten the codes in the question, I didn't put the looping part, just the subprocess call):
code_1.py
:
import subprocess
import sys
subprocess.Popen([sys.executable, "balloontip.py", 'alala', 'code 1', '1'])
code_2.py
:
import subprocess
import sys
subprocess.Popen([sys.executable, "balloontip.py", 'alala', 'code 2', '1'])
This error is encountered:
Python WNDPROC handler failed
Traceback (most recent call last):
File "C:\Users\Computador\Desktop\Tests\balloontip.py", line 42, in OnDestroy
Shell_NotifyIcon(NIM_DELETE, nid)
pywintypes.error: (-2147467259, 'Shell_NotifyIcon', 'Unspecified error')
And let's say a single code at some point tries to create multiple calls to the notifications:
When waiting for each of the notifications to finish executing, no error is found:
import subprocess
import sys
one = '1'
two = '2'
three = '3'
if one == '1':
p1 = subprocess.Popen([sys.executable, "balloontip.py", 'alala', one, '1'])
p1.wait()
if two == '2':
p2 = subprocess.Popen([sys.executable, "balloontip.py", 'alala', two, '1'])
p2.wait()
if three == '3':
p3 = subprocess.Popen([sys.executable, "balloontip.py", 'alala', three, '1'])
p3.wait()
# rest of code...
But I can't wait for the notifications executions finish to continue the code, so I need to remove the wait
:
import subprocess
import sys
one = '1'
two = '2'
three = '3'
if one == '1':
p1 = subprocess.Popen([sys.executable, "balloontip.py", 'alala', one, '1'])
if two == '2':
p2 = subprocess.Popen([sys.executable, "balloontip.py", 'alala', two, '1'])
if three == '3':
p3 = subprocess.Popen([sys.executable, "balloontip.py", 'alala', three, '1'])
# rest of code...
This error is encountered:
Python WNDPROC handler failed
Traceback (most recent call last):
File "C:\Users\Computador\Desktop\Tests\balloontip.py", line 42, in OnDestroy
Shell_NotifyIcon(NIM_DELETE, nid)
pywintypes.error: (-2147467259, 'Shell_NotifyIcon', 'Unspecified error')
Is there a way to receive these notifications without having to wait for each one to finish running?