Неблокирующие уведомления типа "тост" для 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" и сделать его более легким для чтения / выделения тем, кто хочет внести свой вклад / участвовать в проекте DLL.
Я добавил проект DLL в GitHub и буду добавлять новые функции. Если вы хотите внести свой вклад, пожалуйста, сделайте. Проект написан на C#, чтобы доказать эту концепцию, поэтому код может быть очень грязным. (Начальная стадия)
Please do improve:
- Новые анимации
- Возможно отправка сообщений обратно хост-приложениям?
- Лучше х, у позиции обработки?
и что бы вы ни придумали.
Я буду рад, если вы можете оставить имя основного класса, как оно есть " KRISH_VBA_TOOLS
".
Вот ссылка на GitHub: https://github.com/krishKM/VBA_TOOLS
Наслаждаться.
Мое решение этой проблемы - вызвать PowerShell, где мы можем использовать BurntToast. Мой пример неблокирующий, потому что он возвращается сразу после вызова PowerShell, чтобы ваше приложение могло продолжать работу, пока модуль загружен.
Минусы двоякие:
- Уведомление, похоже, исходит от PowerShell в качестве источника.
- Это немного медленнее, чем собственный метод, потому что 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