Skip to content

Instantly share code, notes, and snippets.

@Aanand-Kainth
Created July 1, 2016 03:19
Show Gist options
  • Save Aanand-Kainth/86aa6b60bad8e9798e135c54061e79ff to your computer and use it in GitHub Desktop.
Save Aanand-Kainth/86aa6b60bad8e9798e135c54061e79ff to your computer and use it in GitHub Desktop.
# WindowsNotification by Aanand Kainth
#
# WindowsNotification is a module providing access to the Windows System Tray. Run "dir(WindowsNotification)" to see its methods.
import time
import win32api
import win32con
import win32gui
def registerProgram(programName):
windowClass = win32gui.WNDCLASS()
hInstance = windowClass.hInstance = win32api.GetModuleHandle(None)
windowClass.lpszClassName = programName
atomClass = win32gui.RegisterClass(windowClass)
hWindow = win32gui.CreateWindow(atomClass, programName, win32con.WS_OVERLAPPED | win32con.WS_SYSMENU, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, hInstance, None)
win32gui.UpdateWindow(hWindow)
return {
'hInstance': hInstance,
'hWindow': hWindow,
'atomClass': atomClass
}
def addIcon(programName, pathToIcon, notificationAmount, hInstance, hWindow):
if pathToIcon.lower().count('.ico') == 0:
raise TypeError('Image referenced by pathToIcon must point to a .ICO file!')
try:
hIcon = win32gui.LoadImage(hInstance, pathToIcon, win32con.IMAGE_ICON, 0, 0, win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE)
except Exception:
raise FileNotFoundError('pathToIcon is pointing to a non-existent .ICO file!')
notifyIconData = (hWindow, 0, win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, win32con.WM_USER + notificationAmount, hIcon, programName)
win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, notifyIconData)
notificationAmount = notificationAmount + 1
def subIcon(hWindow):
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, (hWindow, 0))
def addNotification(programName, messageToDisplay, pathToIcon, notificationAmount, hInstance, hWindow):
if pathToIcon.count('.ico') == 0:
raise TypeError('Image referenced by pathToIcon must point to a .ICO file!')
try:
hIcon = win32gui.LoadImage(hInstance, pathToIcon, win32con.IMAGE_ICON, 0, 0, win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE)
except Exception:
raise FileNotFoundError('pathToIcon is pointing to a non-existent .ICO file!')
win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, (hWindow, 0, win32gui.NIF_INFO | win32gui.NIF_MESSAGE | win32gui.NIF_TIP | win32gui.NIF_ICON, win32con.WM_USER + notificationAmount, hIcon, programName, messageToDisplay, len(messageToDisplay), programName))
notificationAmount = notificationAmount + 1
def subNotification(hWindow):
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, (hWindow, 0))
def unregisterProgram(atomClass, hInstance, hWindow):
try:
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, (hWindow, 0))
except Exception:
pass
win32gui.DestroyWindow(hWindow)
win32gui.UnregisterClass(atomClass, hInstance)
win32gui.PostQuitMessage(0)
# Copyright © 2016 Aanand Kainth All Rights Reserved.
@Aanand-Kainth
Copy link
Author

Aanand-Kainth commented Jul 1, 2016

Here is my sample code for this MODULE. Written in Python.

notifications = 0
import WindowsNotification as wN
INFO = wN.registerProgram(<YOUR PROGRAM HERE>)
wN.addIcon('Python', r'C:\Users\<USERNAME>\Pictures\<ICON>', notifications, INFO['hInstance'], INFO['hWindow'])
wN.subIcon(INFO['hWindow'])
wN.unregisterProgram(INFO['atomClass'], INFO['hInstance'], INFO['hWindow'])

Note: It is recommendable to save the dictionary returned by registerProgram() to a file in case your program crashes. Then, when it runs into a reregistry error, it can use an except to unregister the old program, then reregister. Also, if you want multiple notifications at the same time, then register multiple programs, and remember to unregister them. However this could cause some issues with simplicity if you save the dictionary to a file. Simply addNotification or addIcon with different programs. I would save the dictionary to a array which is looped through as notifications are sent, so unregistry is also simple. If you have any questions, email me at aanandkainth@gmail.com.

NOTE: Do NOT modify the variable notifications, which can be named anything, UNLESS a PyWinTypes Error is thrown. In that case, do notifications += 1, run subNotification(), and then retry addNotification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment