New Mail Notification for an Additional Mailbox – Part Three


The New Mail Notification for an Additional Mailbox solution I posted in December of 2010 has proven to be popular. I’ve gotten a couple of requests for modified version of the script, the most recent from Tom Hegh. Tom asked for the following modification

I have Outlook 2010, is it possible to get an notification the same as Outlook is showing ? this way, it’s not really a popup message which you have to click away. Reason I ask this question is that there also are a lot of notification mails, after a weekend, you have to click away about 200 e-mail popup messages, which also is not so pleasant.

The only way to provide a notification that looks and functions exactly like the one in Outlook 2010 would be to develop an add-in. That would require a fair amount of work and goes beyond what I’m prepared to do. I can however emulate the general behavior of Outlook’s notification dialog with the combination of a user-form and some additional code.

The user-form I’ll use is a simple dialog-box. The only control it requires is a textbox to display the notification message. The additional code will do two things. First, it will calculate the size of Tom’s screen in order to display the user-form right above the system tray just as Outlook’s notification window does. Second, it will add a timer that keeps the user-form onscreen for 2 seconds. That should be enough time for Tom to see it. When the 2 seconds expires the user-form will disappear automatically like the built-in notification. Unlike Outlook’s notification, this solution will not fade in and fade out, and will not offer options for opening or deleting the message. It will simply notify Tom that a message has arrived in the other mailbox.

Credit.

The code for detecting the size of the screen and working out the positioning of the user-form is based almost entirely on the code from this page.

The code for this comes in four parts.

Part 1.

Follow these instructions to add the user-form to Outlook.

  1. Download the .zip file from this link
  2. Unzip the file
  3. Start Outlook
  4. Press ALT+F11 to open the Visual Basic Editor
  5. Click File and select Import File
  6. Navigate to the folder you saved the files to in step #2
  7. Select the file frmNotification

Part 2.

Follow these instructions to add this code to Outlook.

  1. If not already expanded, expand Microsoft Office Outlook Objects
  2. If not already expanded, expand Modules
  3. Select an existing module (e.g. Module1) by double-clicking on it or create a new module by right-clicking Modules and selecting Insert > Module.
  4. Copy the code from the Code Snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
  5. Edit the code as needed. I included comments wherever something needs to or can change
  6. Click the diskette icon on the toolbar to save the changes
  7. Close the VB Editor
'On the next line change the file name and path of the sound you want to play.'
Public Const SOUND_TO_PLAY = "C:\Windows\Media\Notify.wav"
Public Const SND_ASYNC = &H1
Public Const LOGPIXELSX = 88
Public Const LOGPIXELSY = 90
Public Const TWIPSPERINCH = 1440
Public Const SM_CXFULLSCREEN = 16
Public Const SM_CYFULLSCREEN = 17

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" _
(ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
Public Declare Function MessageBox _
    Lib "User32" Alias "MessageBoxA" _
        (ByVal hWnd As Long, _
        ByVal lpText As String, _
        ByVal lpCaption As String, _
        ByVal wType As Long) _
    As Long
Public Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function ReleaseDC Lib "user32" ( _
    ByVal hWnd As Long, _
    ByVal hDC As Long) As Long
Public Declare Function GetDeviceCaps Lib "gdi32" ( _
    ByVal hDC As Long, _
    ByVal nIndex As Long) As Long
Public Declare Function GetSystemMetrics Lib "user32" ( _
    ByVal nIndex As Long) As Long

Public Sub ConvertPixelsToPoints(ByRef X As Single, ByRef Y As Single)
    Dim hDC As Long
    Dim RetVal As Long
    Dim XPixelsPerInch As Long
    Dim YPixelsPerInch As Long

    hDC = GetDC(0)
    XPixelsPerInch = GetDeviceCaps(hDC, LOGPIXELSX)
    YPixelsPerInch = GetDeviceCaps(hDC, LOGPIXELSY)
    RetVal = ReleaseDC(0, hDC)
    X = X * TWIPSPERINCH / 20 / XPixelsPerInch
    Y = Y * TWIPSPERINCH / 20 / YPixelsPerInch
End Sub

Public Function OpenOutlookFolder(strFolderPath As String) As Outlook.MAPIFolder
    ' Purpose: Opens an Outlook folder from a folder path.'
    ' Written: 4/24/2009'
    ' Author:  BlueDevilFan'
    ' Outlook: All versions'
    Dim arrFolders As Variant, _
        varFolder As Variant, _
        bolBeyondRoot As Boolean
    On Error Resume Next
    If strFolderPath = "" Then
        Set OpenOutlookFolder = Nothing
    Else
        Do While Left(strFolderPath, 1) = "\"
            strFolderPath = Right(strFolderPath, Len(strFolderPath) - 1)
        Loop
        arrFolders = Split(strFolderPath, "\")
        For Each varFolder In arrFolders
            Select Case bolBeyondRoot
                Case False
                    Set OpenOutlookFolder = Outlook.Session.Folders(varFolder)
                    bolBeyondRoot = True
                Case True
                    Set OpenOutlookFolder = OpenOutlookFolder.Folders(varFolder)
            End Select
            If Err.Number <> 0 Then
                Set OpenOutlookFolder = Nothing
                Exit For
            End If
        Next
    End If
    On Error GoTo 0
End Function

Part 3.

Follow these instructions to add this code to Outlook.

  1. If not already expanded, expand Microsoft Office Outlook Objects
  2. Right-click on Class Modules, select Insert > Class Module
  3. In the Properties panel click on Name and enter FolderMonitor
  4. Copy the code from the Code Snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
  5. Edit the code as needed. I included comments wherever something needs to or can change
  6. Click the diskette icon on the toolbar to save the changes
Private WithEvents olkItems As Outlook.Items
Private timStart As Date, _
        timEnd As Date, _
        sngHt As Single, _
        sngWt As Single, _
        objFrm As frmNotification

Private Sub Class_Initialize()
    sngWt = GetSystemMetrics(SM_CXFULLSCREEN) - 20
    sngHt = GetSystemMetrics(SM_CYFULLSCREEN) - 10
    ConvertPixelsToPoints sngWt, sngHt
    Set objFrm = New frmNotification
    objFrm.setScreen sngWt, sngHt
End Sub

Private Sub Class_Terminate()
    Set olkItems = Nothing
    Set objFrm = Nothing
End Sub

Public Sub FolderToWatch(objFolder As Outlook.Folder)
    Set olkItems = objFolder.Items
End Sub

Private Sub olkItems_ItemAdd(ByVal Item As Object)
    Dim lngHandle As Long, lngReturn As Long
    If (Time() >= timStart) And (Time <= timEnd) Then
        sndPlaySound SOUND_TO_PLAY, SND_ASYNC
        With objFrm
            .SetMsg "You have a new message!" & vbCrLf & "From: " & Item.SenderName & vbCrLf & "Subject: " & Item.Subject
            .ShowNotification
        End With
    End If
End Sub

Public Property Let ActivateAt(ByVal datValue As Date)
    timStart = datValue
End Property

Public Property Let DeactivateAt(ByVal datValue As Date)
    timEnd = datValue
End Property

Part 4.

Follow these instructions to add this code to Outlook.

  1. If not already expanded, expand Microsoft Office Outlook Objects and click on ThisOutlookSession
  2. Copy the code from the Code Snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
  3. Edit the code as needed. I included comment lines wherever something needs to or can change
  4. Click the diskette icon on the toolbar to save the changes
  5. Close the VB Editor
  6. Click Tools > Trust Center
  7. Click Macro Security
  8. Set Macro Security to “Warnings for all macros”
  9. Click OK
  10. Close Outlook
  11. Start Outlook. Outlook will display a dialog-box warning that ThisOutlookSession contains macros and asking if you want to allow them to run. Say yes.
Dim objFM1 As FolderMonitor
Dim objFM2 As FolderMonitor

Private Sub Application_Quit()
    Set objFM1 = Nothing
    Set objFM2 = Nothing
End Sub

Private Sub Application_Startup()
    Set objFM1 = New FolderMonitor
    With objFM1
        'Edit the folder path on the next line as needed.'
        .FolderToWatch OpenOutlookFolder("Mailbox - Doe, John\Inbox")
        'Set the times that monitoring should start/end'
        .ActivateAt = #12:00:00 AM#
        .DeactivateAt = #11:59:59 PM#
    End With
    Set objFM2 = New FolderMonitor
    With objFM2
        'Edit the folder path on the next line as needed.'
        .FolderToWatch OpenOutlookFolder("Mailbox - Brown, Bob\Inbox")
        'Set the times that monitoring should start/end'
        .ActivateAt = #10:00:00 PM#
        .DeactivateAt = #06:00:00 AM#
    End With
End Sub

51 comments on “New Mail Notification for an Additional Mailbox – Part Three

  1. Has anyone tried using this with Outlook 2013? I tried and I get an error: Run-time error ’91’: Object variable or With block variable not set.
    any ideas welcome. Thanks!

    • objFM1.FolderToWatch OpenOutlookFolder(“Mailbox – UNL Insight\Inbox”)

      UNL Insight is the additional mailbox I have added through my exchange account (o365).

      Seth Burkey

    • I got this resolved. Now I am wondering if there is a way to have a button to allow you to open the email from the notification window?

    • Hi, Seth.

      Yes, that’s possible, but it means changing how this works. Right now the code displays the notification dialog, sleeps for 2 seconds, then removes the dialog. We could add a button to open the item, but the sleep command prevents any interaction with the button or anything else on the dialog. The solution would be to remove the sleep command, but doing so has ramifications. Without the sleep command we don’t have a way to keep the dialog on screen for a set amount of time and close it afterward. This would mean that the dialog would remain open on screen until explicitly closed. I can probably overcome this by adding a timer function, but that means making significant changes to the code. Let me see what I can do.

    • sorry, i may have posted the initial question on the wrong area. I am not using the sleep function; i have to close the notification manually which is fine with me so that way i know there is new mail in there without checking the inbox all the time. Many thanks!

    • Seth,

      Sorry, I’m getting ahead of myself. Which version of the solution are you using? That will determine what needs to change.

    • Seth,

      With that code the simplest solution is to change the two lines in the olkItems_ItemAdd subroutine found in the FolderMonitor class code that begin with MessageBox. Change the first of those lines from

      MessageBox &amp;00, strMessage, olkItems.Parent.Name, vbInformation + vbOkOnly + vbSystemModal
      

      to

      If MessageBox(&amp;00, strMessage, olkItems.Parent.Name, vbInformation + vbYesNo + vbSystemModal) = vbYes Then
          Item.Display
      End if
      

      Change the second of those lines from

      MessageBox &amp;00, strMessage &amp; vbCrLf &amp; strAdditionalInfo, olkItems.Parent.Name, vbInformation + vbOkOnly + vbSystemModal
      

      to

      If MessageBox(&amp;00, strMessage &amp; vbCrLf &amp; strAdditionalInfo, olkItems.Parent.Name, vbInformation + vbYesNo + vbSystemModal) = vbYes Then
          Item.Display
      End if
      

      Now when the dialog-box appears it will have “Yes” and “No” buttons instead of an “Ok” button. Clicking “Yes” will display the message. Clicking “No” will close the dialog-box.

    • This is amazing! Thanks so much for your help and very quick replies! This will help me out immensely.

      Have a great holiday season!

      Seth

  2. Hi David,

    I moved 2 two Dim statement lines to the top of ThisOutlookSession but still gets compile error. : User-defined type not defined Outlook 2007.

  3. Hi David,

    I moved the two Dim statement lines to the top of ThisOutlookSession.

    Still not working. Compile error : User-defined type not defined
    Outlook 2007

    • Hi, Ben.

      Code written in VBA, as this is, should run in any version of Outlook. Have you tried it on a machine running 64-bit Outlook?

  4. Hi David … as someone in Carolina Blue it kills me to say this to ‘ Author: BlueDevilFan’
    but … that worked great for me. Thanks a lot. You saved me a ton of hassles and headaches. Much appreciated!

    • Hi, JT.

      *laughing* I can imagine. It just goes to show that Tar Heels and Duke fans can get along.

      I’m glad it was useful.

      Cheers!

  5. Hi David,

    Thank you for the great notification tool in Outlook, I have a question is there any reason why the notification box will hang outlook if you are typing a new email and a notification is triggered ? I have getting this allot at the moment and all I can see if that the notification is not going away but spinning in the background ?

    Thank you
    Marrc

    • Hi, Marc.

      Hmmmm. It shouldn’t. What should happen is the notification appears and causes Outlook to pause for about 2 seconds. The notification should then disappear and you should be able to continue on with what you’re doing. I’ll see if I can create the same condition and see what happens.

    • Hi David,

      I set the timeout to six seconds and then it appeared to happen. Perhabs that makes things easier to reproduce.

      Thank you
      Marc

  6. Hi David, you’re code for this is proving very popular where I work. The only problem I’ve heard comes from our mainframe production support team who report that when the macro fires, Outlook immediately steals focus from whatever app they happen to be in. Is there any way to have just the new mail notification pop up over whatever app they happen to be in without Outlook popping up as well?

    Best regards,
    Mike

    • Hi, Mike.

      I’m glad the people at your workplace have fond the solution useful. The answer to your question is “yes”, but not without other consequences. The notification dialog I use in this solution is an Outlook userform. I used it because it’s the only way I could add code to make the box disappear automatically like the built-in notification popup. The alternative is to use a msgbox. If we use that, then there’s no means of making the dialog box go away. it will require the user to click a button to make it go away. It’s a choice between losing focus combined with automatically closing the dialog and not losing focus but having to manually close the dialog. I used a msgbox in the first two versions of the solution.

    • I just came across the following. Would something like this work in place of the Messagebox function?
      CreateObject(“WScript.Shell”).Popup “Test.”, 2, “Test”

    • It looks like it would. I didn’t know the WshShell object had a Popup function that timed out. I learned something new. Thanks!

    • I have changed it to 5 seconds and it appears a little better now … at least its not happening at the moment if it happens again will let you know

  7. First, thank you for your great work.
    I tested this for our environment (Win 7 Pro 64bit, Outlook 2010 64bit).
    There was a little problem, he complained about 64bit compatibility, so i put “PtrSafe” between every “Declare” and “Sub/Function” as he suggested and it worked.
    But there is another problem, the window appears only in front of any other window if the Outlook Window is the active one, otherwise it is behind the browser or something else.
    This is a big downside for us because the notification sound is not really an option for us and mostly we have other windows active when we really need to be notified.
    I’m not really into vba so i allready wasted some hours on this without any luck of coming even near a solution. I would appreaciate if you can explain how i can fix this, or point me in the right direction.

    Thanks from germany
    Christian

    • Hi, Christian.

      Thanks!

      I’m glad you found the solution useful. I can make the pop-up notification appear on top of all windows, but to do that I have to change the underlying mechanism. Instead of displaying the notification with a VBA UserForm I’ll have to use a MsgBox. Switching to a MsgBox means losing the capability to make the notification disappear automatically after a couple of seconds. You’ll have to click a button to make the notification go away. If that’s an acceptable trade-off, then I can make the change.

      Whereabouts in Germany?

    • hi David.

      Jena, Thuringia (thats in east germany)

      I think you reffered to the possibility that you have discribed in “New Mail Notification for an Additional Mailbox – Part Deux”. Tested this today and suggested both possibilities to our support team.
      After all we now use neither, we just push all mails coming into that mailbox additionally into a distribution group, so everyone gets their notification (quick and dirty but it fits for now). The downside of this is that every mail gets multiplied , so hopefully everyone cleans up from time to time 🙂
      It’s really a shame that Microsoft hasn’t implemented that feature years ago.

      Keep up your good work!
      I will watch your blog, maybe i can pick up some other useful stuff in the future ;o)

    • Hi, Christian.

      I’ve been to Germany a couple of times, but never that was prior to the reunification.

      Thanks and thanks for following. Hopefully there will be some posts that are useful.

      Cheers!

  8. David, thanks. We have users that have been requesting this for a while. One question, please: Why does the pop-up notice display vbCrLf as paragraph marks? It seems your intent was to show a new message’s sender address, subject, etc. on three separate lines. Thanks for any help.

    • Hi, Mike. Prior to saving and uploading the form I apparently set the MultiLine property of the textbox control to False. That prevents the vbCrLf from working so the control shows them as paragraph marks. If you edit the form and set the MultiLine property to True, then the vbCrLf codes will work and you won’t see paragraph marks.

      Sorry about that. I’ll fix the form and upload a new version as soon as I can.

    • Thank you, David. No big deal. I’m new to messing with VBA and this has been very instructional for me.

      All the best,
      Mike

  9. Under ThisOutlookSession there was already an existing script and I pasted yours below it (just below the End Sub of the above script). It looks like the two Dim statements are being treated as part of the script above it. When I run the other script (from a toolbar button), I get a compile error because “Only comments may appear after End Sub”. Do you know how to fix that?

    Thanks,

    Mark

    • That worked! One more thing… I can’t find where you set the duration of the popup. Mine is staying up less than a second and I can barely see it.

      Mark

    • Hi, Mark.

      Look at the code in the form. There you should see a line that reads

      Sleep 2000
      

      That command tells Outlook to keep the form open for 2000 milliseconds (2 seconds). You can change the value to whatever you want. For example, to keep the form open for 5 seconds change the command to

      Sleep 5000
      
    • Hello David,

      Thanks a lot for this code, it is very usefull.
      I also miss the sleep settings….unfortunately there is no sleep line in the code, at least I could not find it at all…could you show me exactly where can I find it?

      Thnaks in advance
      Ginger

    • David,

      I had double-clicked on the form and didn’t see any code for it. Now that you pointed it out, I found I could select the form, right-click, and choose View Code. Now I see the sleep line you mentioned.

      Excellent work on this BTW. A Google search on this topic turns up tons of people having this same problem and you were the only one who actually provided a solution (other than moving to Outlook 2010).

      Thanks,

      Mark

    • Thanks, Mark. Glad you found the solution useful. I’m always looking for things to do in Outlook, so if you have any suggestions for other capabilities/missing features you’d like I’d love to hear them. While I can’t promise anything I will consider them. Cheers!

  10. I am using Office 2007 and seem to to be getting an error saying “Line is not an executable statement’ showing the error in the ‘Sub ShowNotification()’ call within the Notification Form, highlighting the ‘sleep 2000’ line.

    Is there something I am missing?

    Also, have been using your second version of this and works great!!!

    • Hi, Nick.

      It appears I forgot to include the necessary declaration for the Sleep command. I’ve added the missing declaration to the code in Part 2. Replace the code from part 2 with the updated version and you should be in business.

      Glad you like the second version.

      Cheers!

Leave a comment