[Spambayes] Outlook Envelope Tray Icon

Bob Chojnacki bob at jellyvision.com
Fri Nov 7 11:39:45 EST 2003


I really like SpamBayes and the Outlook plugin.  It is working much better
than other spam filters, considering I get 85-95% spam. I am currently using
version 008.1.  I read your FAQ about the problems with making the Outlook
envelope tray icon go away.  (I am also not sure if this is the right email
address to send this comment, so please bear with me if it isn't.)

Is the following link helpful? (Keep in mind that I am not a Windows




P.S.: http://www.techhit.com/autoread/ may also be of use.

------- Page text attached ------

To clear the Outlook envelope icon from the Windows system tray

A common issue for people who subscribe to many mailing lists or use Net
Folders to share data is controlling when Outlook puts an envelope in the
system tray in the right side of the Windows task bar. Typically, they want
to see the envelope icon only when they have new mail in the Inbox that is
not from one of those lists and not part of a Net Folders transmission.

Since the envelope goes away after a user opens the latest items, you might
think that setting the Unread property on those lower priority items to
False would be enough to do the job. However, it doesn't suffice. Even if
you use code or a Rules Wizard rule to mark items as Read, the envelope icon

The icon placed in the system tray is governed by hidden window that
developers don't have direct access to via the Outlook Object Model or
Collaboration Data Objects. Therefore, you need to go outside Outlook for a
solution. Outlook MVP Neo  has come up with an Outlook 2000/2002 VBA method
that uses Windows API calls to remove the icon from the system tray. You can
copy and paste the code below to your project or download the clear_icon.txt

One application of the RemoveNewMailIcon subroutine might be to run some
code when the Application.NewMail event fires to see if any "interesting"
new items have actually come in -- "interesting" here meaning items for
which you want to see the envelope in the system tray. If not, call the
RemoveNewMailIcon subroutine to clear the icon:

Private Sub Application_NewMail()

  ' add some code to check whether the latest items are "interesting"

  ' if not interesting, clear the envelope icon

  Call RemoveNewMailIcon

End Sub

It turns out that integrating Neo's code into Outlook events isn't as
straightforward as you might like. A discussion in the
microsoft.public.outlook.program_vba newsgroup uncovered some apparent
timing issues.

 Code | More Information

Code ' Code sample by Outlook MVP "Neo"

' Removes the New Mail icon from the Windows system tray,

' and resets Outlook's new mail notification engine.

' Tested against Outlook 2000 (IMO) and Outlook 2002 (POP Account)

' Send questions and comments to neo at mvps.org

' WARNING: Due to the use of AddressOf, code must

' go into a module and not ThisOutlookSession or

' a class module

' Entry Point is RemoveNewMailIcon.

Option Explicit

Public Const WUM_RESETNOTIFICATION As Long = &H407

'Required Public constants, types & declares

'for the Shell_Notify API method

Public Const NIM_ADD As Long = &H0

Public Const NIM_MODIFY As Long = &H1

Public Const NIM_DELETE As Long = &H2

Public Const NIF_ICON As Long = &H2 'adding an ICON

Public Const NIF_TIP As Long = &H4 'adding a TIP

Public Const NIF_MESSAGE As Long = &H1 'want return messages

' Structure needed for Shell_Notify API


  cbSize As Long

  hwnd As Long

  uID As Long

  uFlags As Long

  uCallbackMessage As Long

  hIcon As Long

  szTip As String * 64

End Type

Declare Function SendMessage Lib "user32" Alias "SendMessageA" _

  (ByVal hwnd As Long, ByVal wMsg As Long, _

  ByVal wParam As Integer, ByVal lParam As Any) As Long

Declare Function GetClassName Lib "user32" _

  Alias "GetClassNameA" _

  (ByVal hwnd As Long, _

  ByVal lpClassName As String, _

  ByVal nMaxCount As Long) As Long

Declare Function GetWindowTextLength Lib "user32" _

  Alias "GetWindowTextLengthA" _

  (ByVal hwnd As Long) As Long

Declare Function GetWindowText Lib "user32" _

  Alias "GetWindowTextA" _

  (ByVal hwnd As Long, _

  ByVal lpString As String, _

  ByVal cch As Long) As Long

Declare Function EnumWindows Lib "user32" _

  (ByVal lpEnumFunc As Long, _

  ByVal lParam As Long) As Long

Declare Function Shell_NotifyIcon Lib "shell32.dll" _

  Alias "Shell_NotifyIconA" _

  (ByVal dwMessage As Long, _


Declare Function FindWindow Lib "user32" Alias "FindWindowA" _

  (ByVal lpClassName As String, _

  ByVal lpWindowName As String) As Long

' This is the entry point that makes it happen

Sub RemoveNewMailIcon()

  EnumWindows AddressOf EnumWindowProc, 0

End Sub

Public Function EnumWindowProc(ByVal hwnd As Long, _

  ByVal lParam As Long) As Long

  'Do stuff here with hwnd

  Dim sClass As String

  Dim sIDType As String

  Dim sTitle As String

  Dim hResult As Long

  sTitle = GetWindowIdentification(hwnd, sIDType, sClass)

  If sTitle = "rctrl_renwnd32" Then

    hResult = KillNewMailIcon(hwnd)

  End If

  If hResult Then

    EnumWindowProc = False

    ' Reset the new mail notification engine

    Call SendMessage(hwnd, WUM_RESETNOTIFICATION, 0&, 0&)


    EnumWindowProc = True

  End If

End Function

Private Function GetWindowIdentification(ByVal hwnd As Long, _

  sIDType As String, _

  sClass As String) As String

  Dim nSize As Long

  Dim sTitle As String

  'get the size of the string required

  'to hold the window title

  nSize = GetWindowTextLength(hwnd)

  'if the return is 0, there is no title

  If nSize > 0 Then

    sTitle = Space$(nSize + 1)

    Call GetWindowText(hwnd, sTitle, nSize + 1)

    sIDType = "title"

    sClass = Space$(64)

    Call GetClassName(hwnd, sClass, 64)


    'no title, so get the class name instead

    sTitle = Space$(64)

    Call GetClassName(hwnd, sTitle, 64)

    sClass = sTitle

    sIDType = "class"

  End If

  GetWindowIdentification = TrimNull(sTitle)

End Function

Private Function TrimNull(startstr As String) As String

  Dim pos As Integer

  pos = InStr(startstr, Chr$(0))

  If pos Then

    TrimNull = Left(startstr, pos - 1)

    Exit Function

  End If

  'if this far, there was

  'no Chr$(0), so return the string

  TrimNull = startstr

End Function

Private Function KillNewMailIcon(ByVal hwnd As Long) As Boolean

  Dim pShell_Notify As NOTIFYICONDATA

  Dim hResult As Long

  'setup the Shell_Notify structure

  pShell_Notify.cbSize = Len(pShell_Notify)

  pShell_Notify.hwnd = hwnd

  pShell_Notify.uID = 0

  ' Remove it from the system tray and catch result

  hResult = Shell_NotifyIcon(NIM_DELETE, pShell_Notify)

  If (hResult) Then

    KillNewMailIcon = True


    KillNewMailIcon = False

  End If

End Function

More Information AutoRead for Outlook -- Custom action for Rules Wizard to
mark messages that meet certain criteria as read and suppress the new mail
indicator in the system tray.

More information about the Spambayes mailing list