Andrew MacNeill (andrew@aksel.com)
(written: December 2001)
If you use any of the services that
Microsoft offers on the web, you are likely aware of the push that Microsoft is
putting on .Net Web services. They recently converted a number of their
Internet offerings to using Passport, a universal login technology powered by,
you guessed it, .Net. We'll be hearing more about Passport in the coming months
as it gives users a way to manage multiple accounts and services on different
machines. This month, I'll showcase one tool that uses Passport and offers an
interesting twist on communication, .Net Messenger.
Instant Messaging technology used to be a
consumer technology that didn't really have much of a home in the business
world. Not any more. One of the concepts that have been floating around for a
while now is the concept of automated responses. You may be used to seeing them
in emails already. For example, you send an email to ask@oraclemobile.com with
a particular word in the subject, and the server responds back with the
weather, flight information or whatever you have requested. The problem with
this approach is that it's email-based, which means you have to actively check
your messages. It's easy to fill up your inbox with these short responses.
Instead, wouldn't it be a lot easier to simply ask for the information and get
a response without having to rely on e-mail?
One of the benefits of the new MSN
Messenger (or Windows Messenger, as it is called in Windows XP) is that it
exposes an interface that can be programmatically controlled. So now, your
application can "live" on the Internet and respond to requests
automatically without requiring email to go back and forth.
While the actual Messenger API supports
various services, the most common (and the default) service is the .Net (or
MSN) Messenger Service. Another service is the Exchange Messenger service, an
instant messaging tool for use in corporate networks that use Microsoft
Exchange. There are special clients required to connect to other services, so
we'll focus our attention on MSN Messenger (see figure 1 if you've never seen
MSN Messenger before).

Figure 1 – Get the Message? .Net Messenger
is one of the most popular applications on the Internet and now you can use it
within your application.
Before we go forward, it's important to
note that the developer documentation available from Microsoft's web site is
primarily geared to C++ developers and the object names and interfaces
mentioned do not match in VFP development. For example, the developer documentation
refers to the Messenger object and refers to using syntax such as CREATEOBJECT("Messenger.Messenger"). This is
incorrect in Visual FoxPro where the actual object to be created is
Messenger.MessengerApp. This means that the learning curve working with Messenger
is lot of hit and miss. This article should put you on the right track.
Let's start by creating a conversation with
someone.
LOCAL loMsg, loWindow
loMsg
= CREATEOBJECT("Messenger.MessengerApp")
** or use
loMsg.LaunchLogonUI to prompt the user to login
loMsg.AutoLogon
** Launch an IM conversation
loWindow
= loMsg.LaunchIMUI("andrew@aksel.com")
IF loWindow.Members.Count>0
loWindow.SendText("Greetings!")
ENDIF
Before you can use the Messenger service,
you have to logon with an existing account. Messenger accounts may be created
easily by creating a new account (see figure 2). Call LaunchLogonUI to prompt
the user for a login. A better bet on a server would be to use the AutoLogon
method that uses the default login stored on the computer.
The LaunchIMUI method opens a conversation
with the contact with the email address that is passed to it. If you pass it a
contact that it cannot recognize, the window is still opened however the
Members collection won't have anyone in it. The method returns a pointer to a
conversation window from which you can send text. The entire conversation is
available from the History property. While both the MessengerApp and
conversation window share the same core properties (shown in table 1), they
each have different methods. The MessengerApp has the methods shown in table 1
whereas each conversation window has its own methods shown in table 2.
The SendText method can also be used to
send emoticons (those funny little faces in figure 1) by using the appropriate
text like : ), : (, etc.
|
Property |
Description |
|
Name FullName Path |
The name of the Messenger application
(usually MSMSGS.EXE). You can also use the FullName and Path properties to
identify the full path and path of the application. |
|
Left Top Height Width |
Numeric values representing the position
of the main Messenger window. |
|
IMWindows |
Pointer to a collection of Instant
Messenger (IM) windows that may be open. The collection includes Count and
Item properties. Each IM window contains the same properties as the main
application. |
|
Statusbar |
Logical value specifying whether the
status bar is visible or not in the IM window. This property exists in the
main Application but doesn't do anything. |
|
StatusText |
Text of the status bar. |
|
TaskbarIcon |
Logical value identifying if the IM
window is visible on the task bar. |
|
Toolbar |
Logical value indicating if the text
toolbar is displayed in a particular IM window. |
|
Visible |
Logical value indicating if the window is
visible or not. |
|
Methods |
Description |
|
AutoLogon |
Logs user onto the Messenger service
using the default logon settings stored on the computer. |
|
LaunchLogonUI |
Displays the .Net Messenger service login
dialog (see figure 2). |
|
LaunchAddContactUI LaunchAudioTuningUI LaunchIMUI LaunchOptionsUI |
Displays the service's built-in dialogs
for specific tasks such as adding contacts, finding contacts, starting
conversations, etc. Note that some of the dialogs require additional
parameters to display. |
|
Quit |
Logs the current user off and stops the
service. |
Table 1 – Core properties and methods. The
properties are available for both the Messenger Application and its Instant
Message (IM) windows but the Methods listed above are only available for
MessengerApp.

Figure 2 – Log Me In. If you don't already
have an account, you can easily create one by clicking Get .Net passport.
|
Property |
Description |
|
History |
Entire text of conversation that is
displayed in the window. |
|
IMSession |
Pointer to the
Session object (see below). |
|
Members |
Pointer to the Members collection of who
is participating in the conversation. |
|
|
|
|
Method |
Description |
|
Close |
Closes the conversation window. |
|
SendText (strText) |
Sends text to participants. |
Table 2 – IM Properties.
Each "conversation" window has its own set of properties and methods
to control how it may be used.
Users involved
in a conversation (via the Members collection) have properties for
EmailAddress, FriendlyName, LogonName as well as State (see table 4). The State
of each member may change during a conversation to indicate if they are busy or
not.
Each IM window
has a Session object (accessed via the IMSession property). This object has a
State property that lets you know the status of the session (see table 4) as
well as a Services property that outlines the functionality of the Messaging
service. A service may expose different properties and elements. As a result,
the object model for each one is slightly different. Properties and methods for
the .Net Messenger service are found in table 3.
|
Property |
Description |
|
Capabilities |
Numeric value specifying the capabilities
of the messenger service. |
|
FriendlyName |
The name that appears when you send
messages. You can change this field during a conversation however when you
change it, it changes for all open windows. |
|
LogonName |
The logon name (usually the email
address) used to log into the service. |
|
ServiceName |
Name of the Messenger service. |
|
Status |
Numeric value specifying state of the
service. Values are: 0 – Logged On 1 – Not Logged On 2 – Logging On 3 – Logging Off |
|
Method Name |
Description |
|
FindUser |
Returns a numeric value and attempts to
log on as that user. |
|
Logoff |
Logs current user off the service. |
|
|
|
Table 3 – About .Net Messenger.
Each service may have its own functionality. Here are the important ones for
.Net Messenger.
|
Value |
Description |
|
0 |
Unknown |
|
1 |
Offline |
|
2 |
Online |
|
6 |
Invisible |
|
66 |
Out to Lunch |
|
50 |
On the Phone |
|
18 |
Idle |
|
34 |
Away |
|
14 |
Be Right Back |
|
512 |
Local Connecting to Server |
|
1024 |
Local Disconnecting from Server |
|
256 |
Local Finding Server |
|
768 |
Local Synchronizing with Server |
Table 4 – Values of State.
The State property, found in IMSession and Member objects, lets you know the
status of a conversation. You can also change your own LocalState with the
MsgrObject.
With the MessengerApp object, you can
communicate with others. If you are implementing a solution where the user may
already have a Messenger or Passport account, you can use the MsgrObject object
to find out about what functionality exists on the user's computer.
LOCAL loUser
loUser
= CREATEOBJECT("Messenger.MsgrObject")
The MsgrObject has a Services collection.
At this time, the .Net Messenger service is the primary service available. From
the MsgrObject, you can find out the current logon name (LocalLogonName), the
friendly name (LocalFriendlyname) as well as the optional information by
accessing the LocalProperty property. These properties are all read-only.
lcUsername
= loUser.LocalFriendlyName
lcWorkPhone
= loUser.LocalProperty(1)
Change the LocalState property to affect
the way your login appears to users.
** Set it to Busy
loUser.LocalState = 10
** Set it to Be Right Back
loUser.LocalState = 14
Change the FriendlyName property of the
Service via MessengerApp to change the way your name appears in current
conversations.
loMsg.IMWindows(0).IMSession.Service.FriendlyName
= "This is Me"
The List collection of MsgrObject returns a
collection of contacts. The contacts returned depends on the parameter you
pass. A value of 0 returns the valid contacts. A value of 2 returns the
contacts that have been blocked from sending messages.
loContacts
= loUser.List(0)
FOR EACH loContact IN loContacts
?
loContact.FriendlyName + " ("+loContact.EmailAddress+")"
ENDFOR
Another side benefit of the .Net Messenger
API is that it automatically accesses the user's HotMail account. Refer to the
UnReadEMail property to identify how many new messages are sitting in the
user's inbox.
While you can do some basic automation by
creating the MessengerApp object and sending some text messages back and forth,
the most useful aspect of Messenger comes when you bind the object to your own
custom classes using the Object Browser and EVENTHANDLER().
The key interface for Messenger
applications is called DmsgrObjectEvents and it hooks into the MsgrObject class,
as opposed to the MessengerApp. MessengerApp may be used to send messages back
and forth but MsgrObject is the actual recipient of messages back and forth.
Using the Object Browser, create a class
that implements DmsgrObjectEvents. An abbreviated version of the code is below.
A full version of it is included on this month's CD.
PUBLIC XOMessage
xoMessage=NEWOBJECT("cMessengerEvents")
PUBLIC myUser
myUser=
CREATEOBJECT("Messenger.MsgrObject")
EVENTHANDLER(myUser,
xoMessage)
DEFINE CLASS cMessengerEvents AS session
OLEPUBLIC
IMPLEMENTS DMsgrObjectEvents IN ;
"c:\program files\messenger\msmsgs.exe"
. . .
PROCEDURE DMsgrObjectEvents_OnTextReceived (;
pIMSession AS VARIANT, pSourceUser AS VARIANT,
;
bstrMsgHeader AS STRING, bstrMsgText AS STRING,
;
pfEnableDefault AS LOGICAL @) AS VOID
?
"Text Received "+ bstrMsgText +;
" from " + pSourceUser.FriendlyName
ENDPROC
. . .
ENDDEFINE
The OnTextReceived event fires whenever the
Messenger service receives a message, even if it is simply a change in status
text. By referring to the IMSession and SourceUser, you can identify exactly
who sent the message and for what purpose. Using this class and approach, you
can hook into a huge number of different events, including logons, file
transfers, receiving email via Hotmail and more.
As you can see, not all .Net components are
going to require full use of web services. .Net Messenger runs directly on the
desktop but sends its information through the Internet. Can't see how this
could work in your application?
Picture a user sitting in front of his
computer. He needs to know the status of an order but he doesn't want to leave
his current web page or go through another application. He brings up Messenger
and sends a message to yourapp@passport.com saying "What is the status of
order 21513?" On the server end, your bound VFP class receives the
message, checks the status and sends back the response "Order 21513 was
shipped at 2pm. It should be arriving tomorrow". There's no email, no
browsing, just the facts. An application that provides basic Internet
connectivity without requiring major redevelopment – now there's an idea that
might be worth communicating…