Display new mail icon in Windows taskbar using VBScript

前端 未结 4 618
南方客
南方客 2021-01-05 14:10

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 sho

相关标签:
4条回答
  • 2021-01-05 14:40

    As far as I've been able to tell, there is no direct way to display the New Mail Icon using VBA. However, you can add a different 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.

    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).

    1. go to Tools->Macros->Visual Basic Editor, click View->Project explorer.
    2. On the left hand Project window, right-click "Project1" and select Insert->Module.
    3. Double-click the new module you just created,

    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:

    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.

    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".

    enter image description here

    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).

    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.

    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.

    0 讨论(0)
  • 2021-01-05 14:41

    Create c:\scheduletools\mailcheck.vbs with the below content

    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.

    Use the absolute file path in the command.

    or create a .bat file calling your vbs file

    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

    0 讨论(0)
  • 2021-01-05 14:53

    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.

    ' 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
    

    See here and here for original code.

    0 讨论(0)
  • 2021-01-05 14:56

    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.

    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.

    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.

    0 讨论(0)
提交回复
热议问题