How to show non-blocking "toast" like notifications in Microsoft Access? That does have some sort of animation and should not block the host application!
My friend asked me about non-blocking toast like notifications for ms access. My first thought was, check google you will find plenty of samples. He wasn't happy with the samples he got.
He wanted something like (JQuery) non-blocking notifications. Something that user needs to know but not necessarily needs to interact.
Since threading is not possible in VBA, I thought, what if you could write your own .dll? so I ended up writing a .NET DLL which can be accessed by (windows) VBA code and show a toast notification. (the actual dll creation and accessing .NET dll from vba is another topic that I will cover later)(You can read more in my blog leave comments or suggestions as per your wish.)
For now, you can download the DLL that I've created from here: HERE
Edit: The above download links and the GitHub link have been updated to working links that I think belong to the author.
If you are concerned about downloading unknown DLLs: VirusTotal Scan report
Add the DLL to your application's root folder and add following codes to your application.
'Module level public variable
Public gTOASTER As Object
' to save window metrics
Public Type RECT
Left As Long ' x1
Top As Long ' y1
Right As Long ' x2
Bottom As Long ' y2
End Type
#If VBA7 Then
Public Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPtr
Public Declare PtrSafe Function KRISH_VBA_TOOLS Lib "VBA_TOOLS.dll" () As Object
Public Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hWnd As LongPtr, ByRef lpRect As RECT) As LongPtr
#Else
Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal strFilePath As String) As Long
Public Declare Function KRISH_VBA_TOOLS Lib "VBA_TOOLS.dll" () As Object
Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As LongPtr, ByRef lpRect As RECT) As LongPtr
#End If
Public Function FN_TOAST_DLL(iMessage As String, Optional iCLOSE_DURATION As Long = 3000, Optional iType As String = "success", Optional iANIME_DURATION As Long = 1000, Optional iFONT_COLOR As String = "#FFFFFF", Optional iX As Long = 0, Optional iY As Long = 0, Optional iANIME_DIRECTION As Integer = 1, Optional iPARENT_HWND As Long = 0)
On Error GoTo LABEL_EXIT_ROUTINE:
If gTOASTER Is Nothing Then
LoadLibrary (FN_APP_GET_BASE_PATH & "VBA_TOOLS.dll")
Set gTOASTER = KRISH_VBA_TOOLS()
GoTo LABEL_TOAST
Else
GoTo LABEL_TOAST
End If
On Error GoTo 0
Exit Function
LABEL_EXIT_ROUTINE:
msgbox iMessage & vbnewline & err.description
Exit Function
LABEL_TOAST:
'set background color. (pass any html color code)
Select Case iType
Case "error"
iType = "#F76160"
Case "success"
iType = "#26ad82"
Case Else
iType = "#26ad82"
End Select
'if parent object is provided show the toast on top of the parent. if custom x, y is provided use x,y coordinated. if none provided use access app's locaiton.
Dim mRect As RECT
If iPARENT_HWND <= 0 Then
If iX = 0 And iY = 0 Then
GetWindowRect Application.hWndAccessApp, mRect
iANIME_DIRECTION = 0 'anim direction 0 to down and 1 to up
End If
Else ' iPARENT_HWND > 0 Then 'parent_hwnd is null
GetWindowRect iPARENT_HWND, mRect
End If
'set up some offsets
iX = mRect.Left + 360
iY = mRect.Top + 1
On Error Resume Next
gTOASTER.FN_SHOW_TOAST iMessage, iCLOSE_DURATION, iType, iANIME_DURATION, iFONT_COLOR, iX, iY, iANIME_DIRECTION
End Function
Public Function FN_APP_GET_BASE_PATH()
Dim FN As String
FN = Application.CurrentProject.path
If VBA.Right(Application.CurrentProject.path, 1) <> "\" Then FN = FN & "\"
FN_APP_GET_BASE_PATH = FN
End Function
parameter list from the DLL if you want to customise the fn_toast_dll function:
' /// <summary>
' ///
' /// </summary>
' /// <param name="iMessage">Message to display</param>
' /// <param name="iDuration">Duration in Milliseconds to keep the toast before fading out..</param>
' /// <param name="iBG_COLOR">HTML color code for your toast background...</param>
' /// <param name="iANIME_DURATION">Millisecond value used to for fading in and out the Toast.. 1/4 is used to fade in rest to fade out..</param>
' /// <param name="iFONT_COLOR">HTML Color code for the font..</param>
' /// <param name="iX">x position on the screen. where the toast should appear</param>
' /// <param name="iY">y position on the screen where the toast should appear</param>
' /// <param name="iANIM_DIRECTION">{0,1} 0 will show/add further notifications downwards and 1 upwards.</param>
' /// <returns></returns>
to show a notification call this method:
FN_TOAST_DLL "hello this is a green test" ' By default a success message with 3 seconds will be "toasted"
FN_TOAST_DLL "hello this is an error", 15000, "error"
Usage:
You can use this for any non interacting alerts.. like login success, or action cancelled alerts or anything that user does not need to press OK to acknowledge your message.
Goal I will upload the Dll project on GitHub and ask for contribution from other VBA C# experts to make it bit more fancier and available for all VBA developers.
Here is my GitHub link: GitHub Please contribute as much as you want and make this available for everyone :) I'll be happy if you can leave the main class name as it is.
iANIME_DIRECTION
does). Thanks. –
Beeck WM_LBUTTONDOWN
?) ... in my case, for example, I'd want to open a web page, the URL depending on which notification was clicked. –
Selfexplanatory Application.CurrentProject.Path
and GetWindowRect
and even if I work around them with hard-coded values I get the same error on gTOASTER.FN_SHOW
. LoadLibrary
succeeds and gTOASTER
seems to initialized –
Dameron Not sure if this deserves another answer! Please forgive if it hasn't! To answer "If i could publish the DLL source-code" and to make it easier to read/stand out for those who wants to contribute/participate to the DLL project.
I've added the DLL project to the GitHub and I will be adding updating new functions. If you would like to contribute please do. The project is written is C# to prove this concept hence code can be very messy. (Initial stage)
Please do improve:
- New animations
- Perhaps sending messages back to host applications?
- Better x,y position handling ?
and whatever you come up with.
I'll be happy if you could leave the main class name as it is "KRISH_VBA_TOOLS
".
Here is the GitHub link:
https://github.com/krishKM/VBA_TOOLS
Enjoy.
My solution to this problem is to use the built in Windows 10 toast notification API. I call upon PowerShell where we can leverage BurntToast. My example is non-blocking because it returns right after calling PowerShell so your application can continue while the module is loaded. Even if PowerShell takes a minute to load the user will not notice. It fires fairly quickly in my testing.
First make a Pop-Toast.ps1
file that looks like this:
## Pop-Toast
#Requires -Version 5
Param (
[String]$cmdText="Test",
[String]$cmdTitle="Example",
[String]$cmdLogo="$PSScriptRoot\YourLogo.ico",
[String]$thisApplication,
[String]$appID
)
## Ensure we have the latest version of our module installed
$toastModule = "BurntToast"
if (Get-Module -ListAvailable -Name $toastModule) {
# If you uncomment the next line it will update but each call is much slower.
#Update-Module -Name $toastModule
}
else {
try {
Install-Module -Name $toastModule -AllowClobber -Confirm:$False -Force
}
catch [Exception] {
$_.message
exit
}
}
## Pop that tart!
$header = New-BTHeader -Id $appID -Title $thisApplication
New-BurntToastNotification -AppLogo $cmdLogo -Header $header -AppId $appID -Text $cmdTitle, $cmdText
Then we make a complimentary VBA procedure that calls our PowerShell script:
Const PopToastPath As String = "Toast\Pop-Toast.ps1"
Public Sub PopToaster(ByVal toastText As String, Optional ByVal toastTitle As String, Optional ByVal toastLogoPath As String)
Dim PSOptions As String
PSOptions = " -WindowStyle hidden -ExecutionPolicy bypass -NonInteractive"
Dim PSCommand As String
PSCommand = "powershell.exe" & PSOptions & " -File " & PopToastPath & " -cmdText """ & toastText & """"
If Not Trim$(toastTitle) = vbNullString Then PSCommand = PSCommand & " -cmdTitle """ & toastTitle & """"
If Not Trim$(toastLogoPath) = vbNullString Then PSCommand = PSCommand & """ -cmdLogo """ & toastLogoPath & """"
With CreateObject("Wscript.Shell")
.Run PSCommand, 0, False
End With
End Sub
NOTE: You can configure your application name and appID to make the toast appear to come from your own application. If you do not then it will be seen as coming from PowerShell.
© 2022 - 2024 — McMap. All rights reserved.