Multiple WindowsBaloonTip / TrayTip Notifications?

后端 未结 1 1111
深忆病人
深忆病人 2021-01-06 04:48

If you were to use this code below to create TrayTips (BaloonTips) in the Notification Area you will notice that it only allows one message and then gets stuck and errors ou

相关标签:
1条回答
  • 2021-01-06 05:41

    As you can see if you were to try and send multiple balloon_tip's to the WindowsBalloonTip class you will get the following error:

    File "C:/WindowsBalloonTip.py", line 20, in __init__
        classAtom = RegisterClass(wc)
    error: (1410, 'RegisterClass', 'Class already exists.')
    

    Looking at Microsoft's documentation of the RegisterClass you need to Unregister the class as well by using UnregisterClass(lpClassName, hInstance)

    http://msdn.microsoft.com/en-us/library/ms644899

    We can do this by adding: classAtom = UnregisterClass(classAtom, hinst) but it must be added AFTER the window has been destroyed for example here is a fixed full version

    # -- coding: utf-8 --
    
    from win32api import *
    from win32gui import *
    import win32con
    import sys, os
    import struct
    import time
    
    # Class
    class WindowsBalloonTip:
        def __init__(self, title, msg):
            message_map = { win32con.WM_DESTROY: self.OnDestroy,}
    
            # Register the window class.
            wc = WNDCLASS()
            hinst = wc.hInstance = GetModuleHandle(None)
            wc.lpszClassName = 'PythonTaskbar'
            wc.lpfnWndProc = message_map # could also specify a wndproc.
            classAtom = RegisterClass(wc)
    
            # Create the window.
            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)
    
            # Icons managment
            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')
    
            # Notify
            Shell_NotifyIcon(NIM_ADD, nid)
            Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO, win32con.WM_USER+20, hicon, 'Balloon Tooltip', msg, 200, title))
            # self.show_balloon(title, msg)
            time.sleep(5)
    
            # Destroy
            DestroyWindow(self.hwnd)
            classAtom = UnregisterClass(classAtom, hinst)
        def OnDestroy(self, hwnd, msg, wparam, lparam):
            nid = (self.hwnd, 0)
            Shell_NotifyIcon(NIM_DELETE, nid)
            PostQuitMessage(0) # Terminate the app.
    
    # Function
    def balloon_tip(title, msg):
        w=WindowsBalloonTip(title, msg)
    
    # Main
    if __name__ == '__main__':
        # Example
        balloon_tip('Lorem Ipsum', 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...')
        balloon_tip('Example two', 'There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain...')
    

    There are issues on certain operating systems with the icon loading so if you want your own custom icon then change this line:

    iconPathName = os.path.abspath(os.path.join( sys.path[0], 'balloontip.ico' ))
    

    To something like:

    iconPathName = "C:\myfolder\myicon.ico"
    
    0 讨论(0)
提交回复
热议问题