Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

non-blocking "toast" like notifications for Microsoft Access (VBA)

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!

like image 315
Krish Avatar asked Aug 30 '16 09:08

Krish


1 Answers

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.

A sample: Dll toast vba

like image 110
Krish Avatar answered Sep 23 '22 21:09

Krish