Jump to content

Recommended Posts

Posted

Hello everyone,

While exploring different ways to create a lightweight and flexible notification system, I realized that the IUserNotification interface is one of the least resource-hungry, especially if you're looking to implement a discreet and low-impact reminder system.

I'm sharing here a small demonstration of this approach.

The code below displays a customizable system notification with a title, message, icon, and optional system sound.
It’s flexible and dynamic, and can easily be adapted for uses like reminders, subtle alerts, and more.

🔧 It uses:

  • the COM object IUserNotification

  • system icons extracted from shell32.dll

  • a custom interface via AutoItObject

📌 This is just another way to do it — not necessarily better, but a useful option if you want to avoid heavy UDFs or external libraries for a simple need.

 

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include "AutoItObject.au3"
#include <WinAPIIcons.au3>
#include <WinAPIShellEx.au3>

; Initialization
_AutoItObject_Startup()

#cs
; Constants for SetBalloonInfo
Global Const $NIIF_NONE = 0x00000000
Global Const $NIIF_INFO = 0x00000001
Global Const $NIIF_WARNING = 0x00000002
Global Const $NIIF_ERROR = 0x00000003
Global Const $NIIF_USER = 0x00000004
Global Const $NIIF_NOSOUND = 0x00000010
Global Const $NIIF_RESPECT_QUIET_TIME = 0x00000080
#ce

; COM structure and interfaces
Global Const $tagIUserNotification = _
        "QueryInterface long(ptr;ptr*);" & _
        "AddRef ulong();" & _
        "Release ulong();" & _
        "SetBalloonInfo long(wstr;wstr;dword);" & _
        "SetBalloonRetry long(dword;dword;uint);" & _
        "SetIconInfo long(ptr;wstr);" & _
        "Show long(ptr;dword);" & _
        "PlaySound long(wstr);"

; Function to create and display the notification
Func CreateSystemNotification($sTitle, $sMessage, $iTimeout = 2000, $iIconIndex = Default, $sSound = "")
    Local $hIcon = 0, $pUserNotif = 0, $oNotif = 0
    ; Create COM instance
    Local $CLSID_IUserNotification = _AutoItObject_CLSIDFromString("{0010890E-8789-413C-ADBC-48F5B511B3AF}")
    Local $IID_IUserNotification = _AutoItObject_CLSIDFromString("{BA9711BA-5893-4787-A7E1-41277151550B}")
    _AutoItObject_CoCreateInstance(DllStructGetPtr($CLSID_IUserNotification), 0, 1, DllStructGetPtr($IID_IUserNotification), $pUserNotif)
    If Not $pUserNotif Then
        ConsoleWrite("Error: Failed to create COM instance." & @CRLF)
        Return False
    EndIf

    ; Create wrapper object
    $oNotif = _AutoItObject_WrapperCreate($pUserNotif, $tagIUserNotification)
    If Not IsObj($oNotif) Then
        ConsoleWrite("Error: Failed to create wrapper object." & @CRLF)
        Return False
    EndIf

    ; Load icon
    Local $dwFlags = $NIIF_USER
    Local $iTotal = _WinAPI_ExtractIconEx(@SystemDir & '\shell32.dll', -1, 0, 0, 0)

    If $iIconIndex = Default Or Not IsInt($iIconIndex) Or $iIconIndex < 0 Or $iIconIndex >= $iTotal Then
        $iIconIndex = 13 ; Default icon
        ;ConsoleWrite("Warning: Invalid icon index. Using default icon (index 64)." & @CRLF)
    EndIf

    $hIcon = _WinAPI_ShellExtractIcon(@SystemDir & '\shell32.dll', $iIconIndex, 32, 32)
    If Not $hIcon Then
        ConsoleWrite("Error: Failed to load icon. Switching to NIIF_NONE." & @CRLF)
        $dwFlags = $NIIF_NONE
    EndIf

    ; Configure notification
    If $sSound <> "" Then
        $oNotif.PlaySound($sSound)
    EndIf
    $oNotif.SetBalloonInfo($sTitle, $sMessage, BitOR($NIIF_RESPECT_QUIET_TIME, $dwFlags))
    $oNotif.SetBalloonRetry(0, 0, 0) ; No retries
    $oNotif.SetIconInfo($hIcon, $sTitle)
    $oNotif.Show(0, $iTimeout)

    ; Resource cleanup
    If $hIcon Then _WinAPI_DestroyIcon($hIcon)
    If IsObj($oNotif) Then $oNotif.Release()
    $oNotif = 0
    $pUserNotif = 0
    Return True
EndFunc   ;==>CreateSystemNotification

; Example usage
If CreateSystemNotification("Notification Title", "This is an AutoIt message", 2000, Default, "") Then
    ConsoleWrite("Notification displayed successfully." & @CRLF)
Else
    ConsoleWrite("Failed to display notification." & @CRLF)
EndIf

 

Posted

You can create the object simply with :

Local $CLSID_IUserNotification = "{0010890E-8789-413C-ADBC-48F5B511B3AF}"
    Local $IID_IUserNotification = "{BA9711BA-5893-4787-A7E1-41277151550B}"
    Local $oNotif = ObjCreateInterface($CLSID_IUserNotification, $IID_IUserNotification, $tagIUserNotification)

Or you can even simpler use :

_WinAPI_ShellNotifyIcon

 

Posted
3 hours ago, argumentum said:

Tested and with $NIIF_RESPECT_QUIET_TIME didn't even stay on. Then tried $NIIF_INFO and that, it did like, but no show of anything but the selected icon, and would only go away after clicking the icon. On x64 it'd crash.

Hi @argumentum . Thanks for your feedback. Regarding the constants $NIIF_NONE, $NIIF_INFO, $NIIF_WARNING, and $NIIF_ERROR, I chose to comment them out in this example because they correspond to Windows' predefined system icons. This function focuses on custom icons extracted from shell32.dll (system 🙃), selected by the user, hence the exclusive use of $NIIF_USER to handle icon handles. For $NIIF_RESPECT_QUIET_TIME, you’ll need to configure the object beforehand using the method $oNotif.SetBalloonRetry(3000, 0, 0) to set the retry parameters. This is a simple example, designed to be flexible and adaptable, so feel free to modify it to add other icon sources, reactivate the constants for different notification types, or adjust the retry settings as needed.

 

Posted
1 hour ago, Nine said:

Or you can even simpler use :

_WinAPI_ShellNotifyIcon

 

Hi @NineI’ve been thinking about this function, and while it’s pretty good, I find it too limited because it requires extra coding to handle a callback. Fortunately, the interface provides a method that does the job: $oNotif.SetBalloonRetry(2000, 3000, 2). As a bonus, I can even add some nice music to enhance the experience!

Posted

I just downloaded your script and AutoItObject 1.2.8.2. I'm running Autoit 3.3.16.1 on Windows 11.
When running your script I get the following error:

Quote

TEST Notification.au3" (44) : ==> Can pass constants by reference only to parameters with "Const" keyword.:
$oNotif = _AutoItObject_WrapperCreate($pUserNotif, $tagIUserNotification)
$oNotif = _AutoItObject_WrapperCreate($pUserNotif, ^ ERROR

Did I miss something?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...