【发布时间】:2017-01-06 13:12:59
【问题描述】:
如何在 Microsoft Access 中显示类似通知的非阻塞“toast”?那确实有某种动画,不应该阻止宿主应用程序!
【问题讨论】:
-
如果有像我一样不知道“吐司”的人:codeseven.github.io/toastr/demo.html
标签: ms-access notifications vba nonblocking
如何在 Microsoft Access 中显示类似通知的非阻塞“toast”?那确实有某种动画,不应该阻止宿主应用程序!
【问题讨论】:
标签: ms-access notifications vba nonblocking
我的朋友问我关于 ms 访问通知之类的非阻塞 toast。我的第一个想法是,检查谷歌你会发现很多样本。他对得到的样品不满意。
他想要(JQuery)非阻塞通知之类的东西。用户需要知道但不一定需要交互的东西。
由于在 VBA 中无法使用线程,我想,如果您可以编写自己的 .dll 会怎样?所以我最终编写了一个 .NET DLL,可以通过(Windows)VBA 代码访问它并显示一个 toast 通知。 (实际的 dll 创建和从 vba 访问 .NET dll 是另一个我将在稍后介绍的主题)(You can read more in my blog 根据您的意愿留下 cmets 或建议。)
现在,您可以从这里下载我创建的 DLL: HERE
编辑: 以上下载链接和 GitHub 链接已更新为我认为属于作者的工作链接。
如果您担心下载未知 DLL:VirusTotal Scan report
将 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
如果要自定义 fn_toast_dll 函数,则来自 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 来确认您的消息的任何内容。
目标 我将在 GitHub 上上传 Dll 项目,并请求其他 VBA C# 专家的贡献,以使其更加精美并可供所有 VBA 开发人员使用。
这是我的 GitHub 链接:GitHub 请尽可能多地贡献,并让每个人都可以使用它:) 如果你能保持主类名不变,我会很高兴。
【讨论】:
iANIME_DIRECTION 做了什么)。谢谢。
不确定这是否值得另一个答案!没有的话请见谅! 回答“如果我可以发布 DLL 源代码”,并让那些想要贡献/参与 DLL 项目的人更容易阅读/脱颖而出。
我已将 DLL 项目添加到 GitHub,我将添加更新的新功能。如果你想贡献,请做。该项目是用 C# 编写的,以证明这个概念,因此代码可能非常混乱。 (初始阶段)
Please do improve:
无论你想出什么。
如果您能将主类名称保留为“KRISH_VBA_TOOLS”,我会很高兴。
这里是 GitHub 链接:https://github.com/krishKM/VBA_TOOLS
享受吧。
【讨论】:
我对这个问题的解决方案是使用内置的 Windows 10 toast 通知 API。我调用了 PowerShell,我们可以在其中利用 BurntToast。我的示例是非阻塞的,因为它在调用 PowerShell 后立即返回,因此您的应用程序可以在模块加载时继续运行。即使 PowerShell 需要一分钟来加载用户也不会注意到。在我的测试中,它的触发速度相当快。
首先制作一个如下所示的Pop-Toast.ps1 文件:
## 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
然后我们创建一个调用我们的 PowerShell 脚本的免费 VBA 过程:
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
注意:您可以配置应用程序名称和 appID 以使 toast 看起来来自您自己的应用程序。如果您不这样做,那么它将被视为来自 PowerShell。
【讨论】: