vba 使用 VBScript 在 Windows 任务栏中显示新邮件图标
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9378313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Display new mail icon in Windows taskbar using VBScript
提问by andersonbd1
I was having the hardest time configuring outlook to show the new mail message icon only when I wanted it to. I have several rules/filters set up that I didn't want to show, but they always did. I tried everything, but that's not my question. What I found as a good solution was to create a vbs script that called a bash script I use to notify me. I call this code in my catch-all rule and have all the other rules exit early. It works pretty well. What I'd really like, though, is to display the new mail icon (envelope) in the taskbar. I'm really ignorant of vb, vba, vbs. But if someone can send the code that I need in a file, I'd love to give it a shot. THANKS!
我在配置 Outlook 以仅在需要时显示新邮件图标时遇到了最困难的时间。我设置了几个我不想显示的规则/过滤器,但它们总是显示。我尝试了一切,但这不是我的问题。我发现一个很好的解决方案是创建一个 vbs 脚本,该脚本称为我用来通知我的 bash 脚本。我在我的包罗万象规则中调用此代码,并让所有其他规则提前退出。它工作得很好。不过,我真正想要的是在任务栏中显示新邮件图标(信封)。我真的对vb,vba,vbs一无所知。但是,如果有人可以将我需要的代码发送到文件中,我很乐意试一试。谢谢!
回答by transistor1
As far as I've been able to tell, there is no direct way to display theNew Mail Icon using VBA. However, you can add adifferent tray icon on-demand. I'm sure there is a way to get a similar-looking icon to appear by using LoadIcon or a similar Win32 function, but I have not been able to figure out how.
据我已经能够告诉,也显示没有直接的方法的使用VBA新邮件图标。但是,您可以添加一个点播不同的托盘图标。我确信有一种方法可以通过使用 LoadIcon 或类似的 Win32 函数来显示类似的图标,但我一直无法弄清楚如何。
Note that this only works in 32-bit Office (I wasn't able to get it to work in 64-bit; so you're out of luck in that regard -- even in the Microsoft forums, that issue is unresolved. Then again, I think more highly of Stack Overflow than of the Microsoft Forums).
请注意,这仅适用于 32 位 Office(我无法让它在 64 位中工作;所以在这方面您很不走运——即使在Microsoft 论坛中,该问题也未解决。然后再一次,我更看重 Stack Overflow 而不是微软论坛)。
- go to Tools->Macros->Visual Basic Editor, click View->Project explorer.
- On the left hand Project window, right-click "Project1" and select Insert->Module.
- Double-click the new module you just created,
- 转到工具->宏->Visual Basic 编辑器,单击视图->项目资源管理器。
- 在左侧的 Project 窗口中,右键单击“Project1”并选择 Insert->Module。
- 双击刚刚创建的新模块,
and paste the following code:
并粘贴以下代码:
'Some code borrowed from:
'http://support.microsoft.com/kb/176085
Public Type NOTIFYICONDATA
cbSize As Long
hwnd As Long
uId As Long
uFlags As Long
uCallBackMessage As Long
hIcon As Long
szTip As String * 64
End Type
Public Const NIM_ADD = &H0
Public Const NIM_MODIFY = &H1
Public Const NIM_DELETE = &H2
Public Const NIF_MESSAGE = &H1
Public Const NIF_ICON = &H2
Public Const NIF_TIP = &H4
Public Const IDI_APPLICATION = 32512&
Public Const IDI_ASTERISK = 32516&
Public Const IDI_EXCLAMATION = 32515&
Public Const IDI_HAND = 32513&
Public Const IDI_ERROR = IDI_HAND
Public Const IDI_INFORMATION = IDI_ASTERISK
Public Const IDI_QUESTION = 32514&
Public Const IDI_WARNING = IDI_EXCLAMATION
Public Const IDI_WINLOGO = 32517&
Public Const WM_MOUSEMOVE = &H200
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Public Const WM_LBUTTONDBLCLK = &H203
Public Const WM_RBUTTONDOWN = &H204
Public Const WM_RBUTTONUP = &H205
Public Const WM_RBUTTONDBLCLK = &H206
Public Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Public Declare Function Shell_NotifyIcon Lib "shell32" _
Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWndParent As Long, ByVal hwndChildAfter As Long, _
ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Public Declare Function LoadIcon Lib "user32" Alias "LoadIconA" (ByVal hInstance As Long, ByVal lpIconName As Long) As Long
Public nid As NOTIFYICONDATA
Public Sub ShowNotifyIcon()
With nid
.cbSize = Len(nid)
.hwnd = 0
'If you un-comment this line below the icon won't disappear when you mouse over it. You will need to use the HideNotifyIcon() function to make it disappear
'.hwnd = FindWindowEx(0&, 0&, "mspim_wnd32", "Microsoft Outlook")
.uId = vbNull
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uCallBackMessage = WM_MOUSEMOVE
.hIcon = LoadIcon(0&, IDI_APPLICATION)
.szTip = "A message has arrived" & vbNullChar
End With
Shell_NotifyIcon NIM_ADD, nid
End Sub
Public Sub HideNotifyIcon()
Shell_NotifyIcon NIM_DELETE, nid
End Sub
Now, to be able to use these in an Outlook rule, you need to double-click ThisOutlookSession, and paste the following code:
现在,为了能够在 Outlook 规则中使用这些,您需要双击 ThisOutlookSession,并粘贴以下代码:
Public Sub ShowNewMailIcon(Item As Outlook.MailItem)
Call ShowNotifyIcon
End Sub
Public Sub HideNewMailIcon(Item As Outlook.MailItem)
Call HideNotifyIcon
End Sub
Now you can save, and close the Visual Basic window.
现在您可以保存并关闭 Visual Basic 窗口。
To use these functions in a rule, you can then create a new rule: Tools->Rules and Alerts->New Rule, select your criteria on the first 2 screens, then on the "Select action(s)" screen, choose "run a script". When you add that to your rule, and click the underlined "run a script", you should then see the 2 functions "ShowIconInTray" and "HideIconInTray".
要在规则中使用这些功能,您可以创建一个新规则:工具->规则和警报->新规则,在前两个屏幕上选择您的条件,然后在“选择操作”屏幕上,选择“运行脚本”。当您将其添加到规则中并单击带下划线的“运行脚本”时,您应该会看到两个函数“ShowIconInTray”和“HideIconInTray”。
When you use ShowIconInTray in your rule, the icon should appear when the rule runs, and when you mouse-over it, it should disappear (I was challenged in giving other functionality to the icon, because there is no window handle to connect it to that could receive and process the mouse events on the icon).
当您在规则中使用 ShowIconInTray 时,该图标应该会在规则运行时出现,当您将鼠标悬停在它上面时,它应该会消失(我在为该图标提供其他功能方面遇到了挑战,因为没有窗口句柄可以将其连接到可以接收和处理图标上的鼠标事件)。
You may need to check Outlook's security (Tools->Macros->Security). I think Outlook 2007 comes preconfigured with high security. To get the macros to always run, you can select "No security check for macros" or "warnings for macros". Signing VBA is easy but beyond the scope of this answer.
您可能需要检查 Outlook 的安全性(工具->宏->安全性)。我认为 Outlook 2007 预先配置了高安全性。要让宏始终运行,您可以选择“没有宏安全检查”或“宏警告”。签署 VBA 很容易,但超出了本答案的范围。
This is not my favorite code ever, and it's somewhat hackish; but Shell_NotifyIcon wasn't really designed to be used in VBA, and you can't use Win32 functions in VBScript. The best alternative answer would probably include a VSTO add-in, but you can't really "paste" an add-in to an answer-- plus it would require Visual Studio.
这不是我最喜欢的代码,而且有点老套;但是 Shell_NotifyIcon 并不是真正设计为在 VBA 中使用,并且您不能在 VBScript 中使用 Win32 函数。最好的替代答案可能包括 VSTO 加载项,但您不能真正将加载项“粘贴”到答案中——而且它需要 Visual Studio。
回答by 79E09796
First add a reference to Microsoft shell controls and notification, then add a module to your outlook vba project with the following code. It makes available a function to show and hide the tray icon (currently set to c:\temp\msn.ico), which you need modify to show a suitable mail icon.
首先添加对 Microsoft shell 控件和通知的引用,然后使用以下代码将模块添加到您的 Outlook vba 项目。它提供了显示和隐藏托盘图标(当前设置为 c:\temp\msn.ico)的功能,您需要修改它以显示合适的邮件图标。
' Add reference to Microsoft shell controls and notification
Public Declare Function Shell_NotifyIconA Lib "shell32.dll" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
Public hWnd As Long
Private Declare Function GetActiveWindow Lib "user32" () As Long
Public Type NOTIFYICONDATA
cbSize As Long ' Size of the NotifyIconData structure
hWnd As Long ' Window handle of the window processing the icon events
uID As Long ' Icon ID (to allow multiple icons per application)
uFlags As Long ' NIF Flags
uCallbackMessage As Long ' The message received for the system tray icon if NIF_MESSAGE specified. Can be in the range 0x0400 through 0x7FFF (1024 to 32767)
hIcon As Long ' The memory location of our icon if NIF_ICON is specifed
szTip As String * 64 ' Tooltip if NIF_TIP is specified (64 characters max)
End Type
' Shell_NotifyIconA() messages
Public Const NIM_ADD = &H0 ' Add icon to the System Tray
Public Const NIM_MODIFY = &H1 ' Modify System Tray icon
Public Const NIM_DELETE = &H2 ' Delete icon from System Tray
' NotifyIconData Flags
Public Const NIF_MESSAGE = &H1 ' uCallbackMessage in NOTIFYICONDATA is valid
Public Const NIF_ICON = &H2 ' hIcon in NOTIFYICONDATA is valid
Public Const NIF_TIP = &H4 'szTip in NOTIFYICONDATA is valid
Private Sub AddTrayIcon()
Dim nid As NOTIFYICONDATA
' nid.cdSize is always Len(nid)
nid.cbSize = Len(nid)
' Parent window - this is the window that will process the icon events
nid.hWnd = GetActiveWindow()
' Icon identifier
nid.uID = 0
' We want to receive messages, show the icon and have a tooltip
nid.uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP
' The message we will receive on an icon event
nid.uCallbackMessage = 1024
' The icon to display
Dim myPicture As IPictureDisp
strPath = "c:\temp\msn.ico"
Set myPicture = LoadPicture(strPath)
nid.hIcon = myPicture
' Our tooltip
nid.szTip = "Always terminate the tooltip with vbNullChar" & vbNullChar
' Add the icon to the System Tray
Shell_NotifyIconA NIM_ADD, nid
End Sub
Private Sub RemoveTrayIcon()
Dim nid As NOTIFYICONDATA
nid.hWnd = GetActiveWindow()
nid.cbSize = Len(nid)
nid.uID = 0 ' The icon identifier we set earlier
' Delete the icon
Shell_NotifyIconA NIM_DELETE, nid
End Sub
回答by Krishna
Create c:\scheduletools\mailcheck.vbs with the below content
使用以下内容创建 c:\scheduletools\mailcheck.vbs
Set otl = createobject("outlook.application")
Set session = otl.getnamespace("mapi")
session.logon ''use parameters if required - see below
''session.Logon "myUsername", "password", False, False
Set inbox = session.getdefaultfolder(6) '' 6 is for inbox
c = 0
For Each m In inbox.items
If m.unread Then c = c + 1
Next
session.logoff
s = "s"
If c = 1 Then s = ""
Msgbox "You have " & c & " unread message" & s
one way to automatically run this is via task scheduler
自动运行它的一种方法是通过任务调度程序
(start -> run -> (type)tasks -> enter)
you can specify multiple schedules. A VB script file can run directly from Windows task schedule. In the task scheduler, select Add a new scheduled task. Following the prompts, browse to select your .vbs file. Name your task and select your schedule to run the task daily and select the time of day to run. It works just the same as if you want to schedule .Bat file.
您可以指定多个计划。VB 脚本文件可以直接从 Windows 任务计划中运行。在任务计划程序中,选择添加新的计划任务。按照提示,浏览以选择您的 .vbs 文件。为您的任务命名并选择每天运行该任务的计划,并选择一天中的运行时间。它的工作方式与您想要安排 .Bat 文件的工作方式相同。
Use the absolute file path in the command.
在命令中使用绝对文件路径。
or create a .bat file calling your vbs file
或创建一个 .bat 文件调用您的 vbs 文件
cscript //nologo c:\schedulttools\mailcheck.vbs
please note if you have exchange level rules to move your mail to different folders, then you will need to look up all these folders for new mail.
请注意,如果您有将邮件移动到不同文件夹的交换级别规则,那么您需要在所有这些文件夹中查找新邮件。
hope this help
希望这有帮助
回答by David Gausmann
I had got the same problem, but since Windows 7 I don't look for a tray icon, instead I look on the outlook task button.
我遇到了同样的问题,但从 Windows 7 开始,我不寻找托盘图标,而是查看 Outlook 任务按钮。
I wrote the following script to notify windows that the outlook task bar button shall start to flash until the outlook window becomes active. The script must be executed from the rule.
我编写了以下脚本来通知窗口 Outlook 任务栏按钮将开始闪烁,直到 Outlook 窗口变为活动状态。必须从规则中执行脚本。
Option Explicit
Private Type FLASHWINFO
cbSize As Long
hWnd As Long
dwFlags As Long
uCount As Long
dwTimeout As Long
End Type
Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" (ByRef pData As Any, ByVal nSize As Long)
Private Declare Function FlashWindowEx Lib "user32.dll" (ByRef pFlashWInfo As FLASHWINFO) As Boolean
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Private Const FLASHW_ALL As Long = &H3&
Private Const FLASHW_CAPTION As Long = &H1&
Private Const FLASHW_STOP As Long = &H0&
Private Const FLASHW_TIMER As Long = &H4&
Private Const FLASHW_TIMERNOFG As Long = &HC&
Private Const FLASHW_TRAY As Long = &H2&
Public Sub OnNotification(Item As Outlook.MailItem)
Dim fwi As FLASHWINFO
Call ZeroMemory(fwi, Len(fwi))
fwi.cbSize = Len(fwi)
fwi.hWnd = GetHWND
fwi.dwFlags = FLASHW_TRAY Or FLASHW_TIMERNOFG
fwi.uCount = -1
fwi.dwTimeout = 0
Call FlashWindowEx(fwi)
End Sub
Private Function GetHWND() As Long
GetHWND = FindWindowEx(0, 0, vbNullString, Application.ActiveWindow.Caption)
End Function
This is a suitable solution for my problem.
这是适合我的问题的解决方案。