In the article
Make Those Pesky Outlook Security Warnings
Disappear (Carefully!) Using Express ClickYes – Part 1
(TechTrax, October 2005),
I described a product by ContextMagic called Express ClickYes which
makes those pesky messages disappear that you get in Outlook when you’re
launching your email merge, address book search or email notification
program, or when using a PDA synchronization tool:
Figure 1 – A program is trying to access e-mail addresses you have stored in Outlook
Express ClickYes also takes care of this one when you’re trying
to send a catalog to your customers using your bulk emailing
software:
Figure 2 – A program is trying to automatically send e-mail on your behalf
As promised, this month we‘ll control Express
ClickYes programmatically so you can Suspend and Resume it at will.
We‘ll do this in Outlook VBA, although you can do it
in any programming language. ContextMagic has examples in many
languages on their web site on this page:
Manage Express ClickYes from your own software using command line parameters
(http://www.contextmagic.com/express-clickyes/for-developers.htm).
Using this as our excuse, we‘ll explore the basics of Outlook VBA
programming, write an Application_ItemSend event handler, and
learn about Outlook read receipts and MailItem and Recipient objects.
The Scenario
Let‘s say there‘s a certain person that is
unreliable about responding to your emails. Maybe you‘d like to
get a Read Receipt from that person every time you send them an
email. A Read Receipt is something like sending Certified Mail with a
Return Receipt – you get a notification back by email when the
recipient reads the email (unless they decline to send the receipt
when prompted, and that‘s another story). In any case, you
don‘t want to request a read receipt from everyone you
send email to
– you‘ll drive them all nuts with those prompts to see
if it‘s OK to send the receipt. So you just want to request it
from this one recipient.
When in Outlook, you can request a read receipt while composing a
message by clicking on View / Options… / Voting and
Tracking Options / Request a read receipt for this message.
Easy enough. But maybe it‘s too much trouble to remember to do
that… perhaps you want Outlook to do it automatically for you.
VBA to the rescue!
How to Do It
Go into Outlook, select Tools / Macro / Visual Basic
Editor (or just hit Alt-F11). This opens the
Visual Basic Editor, showing the VbaProject.OTM project. Get more
information about working with the Visual Basic Editor in my article
Did You Forget Something? (TechTrax, April 2004).
In the ThisOutlookSession module, enter the following code:
' ThisOutlookSession:
Option Explicit
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If Item.Class <> olMail Then Exit Sub
Dim r as Recipient
For Each r In Item.Recipients
If StrComp(r.Address, "theemailaddress@thedomain.com", vbTextCompare) = 0 Then
Item.ReadReceiptRequested = True
MsgBox "Requesting Read Receipt from " & r.Name
End If
Next
End Sub
Make sure to put the appropriate email address in the correct spot.
Notice we‘re first making sure this is an MailItem; this is up
to you. Then we‘re checking each Recipient in the Recipients
collection to see if the email address matches the person we want
read receipts from. We use the strcomp function with the
vbTextCompare parameter to perform a case-insensitive
string comparison. strcomp returns 0 if the two strings
match. If they do, we request a read receipt in the MailItem and
alert the sender that we‘re doing this. We exit the
ItemSend event handler normally and Outlook sends the
email with the read receipt requested. Easy enough. Test it by
sending mail to the person who‘s email address is listed and
then checking the email in your Sent Items folder. Open the
email‘s View / Options… dialog and notice
the read receipt was requested.
The Issue
Recent versions of Outlook will pop up the security warning when
referencing the Recipients collection of the MailItem, saying, “A
program is trying to access e-mail addresses you have stored in
Outlook. Do you want to allow this?” As we saw last month, Express
ClickYes can prevent this dialog from appearing. However, you
don‘t want to prevent it all the time, because the
dialog‘s purpose is to protect you from viruses! But if we know
we want to enable Express ClickYes just for this exact purpose, we
can do that programmatically using the API (Application Program
Interface) provided by ContextMagic.
Here are two functions and supporting code which will suspend and
resume Express ClickYes: Create a new module by clicking Insert /
Module, change the name of the module (use the Properties pane)
from Module1 to modClickYes, and then
enter the following code:
' modClickYes:
Option Explicit
' Declare Windows' API functions
Private Declare Function RegisterWindowMessage _
Lib "user32" Alias "RegisterWindowMessageA" _
(ByVal lpString As String) As Long
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" (ByVal lpClassName As Any, _
ByVal lpWindowName As Any) As Long
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
lParam As Any) As Long
' Call this before doing something you want ClickYes to be active on.
Public Sub ResumeClickYes()
Dim hwnd As Long
Dim msg As Long
Dim result As Long
' Register a message to send
msg = RegisterWindowMessage("CLICKYES_SUSPEND_RESUME")
' Find ClickYes Window by classname
hwnd = FindWindow("EXCLICKYES_WND", 0&)
' Send the Resume message to Resume ClickYes (that‘s the 1 in the third parameter)
result = SendMessage(hwnd, msg, 1, 0)
End Sub
' Call this after doing something you wanted ClickYes to be active on.
Public Sub SuspendClickYes()
Dim hwnd As Long
Dim msg As Long
Dim result As Long
' Register a message to send
msg = RegisterWindowMessage("CLICKYES_SUSPEND_RESUME")
' Find ClickYes Window by classname
hwnd = FindWindow("EXCLICKYES_WND", 0&)
' Send the Suspend message to Resume ClickYes (that‘s the 0 in the third parameter)
result = SendMessage(hwnd, msg, 0, 0)
End Sub
Now what you can do is call these two functions when you want to
enable and disable Express ClickYes. Basically your flow would
be this:
- Enable (Resume) Express ClickYes
- Do your thing (in this case, mess with the Recipients collection)
- Disable (Suspend) Express ClickYes
When we‘re done, we disable Express ClickYes so our virus
protection is back in place. We only enable Express ClickYes during
the brief period of time that we‘re accessing the Recipients
collection.
Putting It All Together
Now the code in your ThisOutlookSession module looks like this:
' ThisOutlookSession:
Option Explicit
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If Item.Class <> olMail Then Exit Sub
Dim r as Recipient
ResumeClickYes ' Add this line...
For Each r In Item.Recipients
If StrComp(r.Address, "david@soundsidesoftware.com", vbTextCompare) = 0 Then
Item.ReadReceiptRequested = True
MsgBox "Requesting Read Receipt from " & r.Name
End If
Next
SuspendClickYes ' And this one!
End Sub
When you‘re done, save your VbaProject.OTM project
by hitting File / Save VbaProject.OTM.
Wrap Up
In this article, we:
- revisited the benefits of using the freeware utility Express
ClickYes by ContextMagic (get it here:
http://www.contextmagic.com/express-clickyes/).
- learned about Read Receipts.
- worked with the Visual Basic Editor.
- created an Application ItemSend event handler.
- learned how to access the Recipients collection of a MailItem
just before Outlook sends it out.
- saw how Express ClickYes can bypass the Outlook security warning.
- added a Module to our VbaProject.OTM project.
- entered code into the new Module.
- learned how to Suspend and Resume Express ClickYes
programmatically.
- saved the Project.
Next Month
Next month, we‘ll learn about VBA Classes by turning the
Suspend and Resume code into a Class. In a future article,
we‘ll delve deeper into how the Suspend and Resume code works,
explaining the Declare statement and the
RegisterWindowMessage, FindWindow and
SendMessage Win32 API functions.

|