Неблокирующие уведомления типа "тост" для Microsoft Access (VBA)

Я собираюсь задать вопрос и ответить на вопрос, который, по моему мнению, будет полезен для тех, кто интересуется некоторыми интересными функциями пользовательского интерфейса в MS Access. Отвечая на собственный вопрос

Вопрос: Как отобразить неблокирующие "тосты" как уведомления в Microsoft Access? это имеет некоторую анимацию и не должно блокировать хост-приложение!

3 ответа

Мой друг спросил меня о неблокирующем тосте, как уведомления о доступе к MS. Моя первая мысль была, проверьте Google, вы найдете много образцов. Он не был счастлив с образцами, которые он получил.

Он хотел что-то вроде (JQuery) неблокирующих уведомлений. Что-то, что пользователь должен знать, но не обязательно должен взаимодействовать.

Так как многопоточность в VBA невозможна, я подумал, что если бы вы могли написать свой собственный.dll? поэтому я закончил писать.NET DLL, к которой можно получить доступ через (windows) код VBA и показать всплывающее уведомление.(Фактическое создание dll и доступ к.NET dll из vba - это еще одна тема, о которой я расскажу позже)( вы можете прочитать больше в моем блоге, оставлять комментарии или предложения по вашему желанию.)

На данный момент вы можете скачать DLL, которую я создал здесь: ЗДЕСЬ

Изменить: вышеуказанные ссылки для скачивания и ссылка на GitHub были обновлены до рабочих ссылок, которые, я думаю, принадлежат автору.

Если вы беспокоитесь о загрузке неизвестных DLL-файлов: отчет VirusTotal Scan

Добавьте DLL в корневую папку вашего приложения и добавьте следующие коды в ваше приложение.

'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

список параметров из DLL, если вы хотите настроить функцию fn_toast_dll:

'    /// <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>

чтобы показать уведомление, вызовите этот метод:

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"

Использование:

Вы можете использовать это для любых не взаимодействующих оповещений, таких как: успешный вход в систему, оповещения об отмене действий или все, что пользователю не нужно нажимать OK, чтобы подтвердить ваше сообщение.

Цель: загрузить проект Dll на GitHub и попросить других экспертов по VBA C# сделать его более интересным и доступным для всех разработчиков VBA.

Вот моя ссылка на GitHub: GitHub Пожалуйста, внесите столько, сколько хотите, и сделайте это доступным для всех:) Я буду рад, если вы оставите имя основного класса таким, какое оно есть.

Образец: Dll тост VBA

Не уверен, что это заслуживает другого ответа! Пожалуйста, прости, если нет! Ответить "Если бы я мог опубликовать исходный код DLL" и сделать его более легким для чтения / выделения тем, кто хочет внести свой вклад / участвовать в проекте DLL.

Я добавил проект DLL в GitHub и буду добавлять новые функции. Если вы хотите внести свой вклад, пожалуйста, сделайте. Проект написан на C#, чтобы доказать эту концепцию, поэтому код может быть очень грязным. (Начальная стадия)

Please do improve: 
  1. Новые анимации
  2. Возможно отправка сообщений обратно хост-приложениям?
  3. Лучше х, у позиции обработки?

и что бы вы ни придумали.

Я буду рад, если вы можете оставить имя основного класса, как оно есть " KRISH_VBA_TOOLS ".

Вот ссылка на GitHub:
https://github.com/krishKM/VBA_TOOLS

Наслаждаться.

Мое решение этой проблемы - вызвать PowerShell, где мы можем использовать BurntToast. Мой пример неблокирующий, потому что он возвращается сразу после вызова PowerShell, чтобы ваше приложение могло продолжать работу, пока модуль загружен.

Минусы двоякие:

  1. Уведомление, похоже, исходит от PowerShell в качестве источника.
  2. Это немного медленнее, чем собственный метод, потому что PowerShell нужно время, чтобы развернуться.

Сначала сделайте Pop-Toast.ps1 файл, который выглядит так:

      ## Pop-Toast 
#Requires -Version 5
Param (
    [String]$cmdText="Test",
    [String]$cmdTitle="Example",
    [String]$cmdLogo="$PSScriptRoot\YourLogo.ico"
)



## Ensure we have the latest version of our module installed
$toastModule = "BurntToast"
if (Get-Module -ListAvailable -Name $toastModule) {
    Update-Module -Name $toastModule
} 
else {
    try {
        Install-Module -Name $toastModule -AllowClobber -Confirm:$False -Force  
    }
    catch [Exception] {
        $_.message 
        exit
    }
}

## Pop that tart!
if (Test-Path -Path $cmdLogo) {
    New-BurntToastNotification -AppLogo $cmdLogo -Text $cmdTitle, $cmdText
} else {
    New-BurntToastNotification -Text $cmdTitle, $cmdText
}

Затем мы создаем дополнительную процедуру VBA, которая вызывает наш сценарий PowerShell:

      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
Другие вопросы по тегам