The Office Communicator 2007 SDK is one of a bunch of SDKs available for the Office Communications Server 2007 product suite. This particular one is used to automate a running instance of Communicator 2007. For example, you can interact with Communicator to start text, audio, or video conversations. You can also respond to certain Communicator events in code, such as the creation of a new conversation window.
If you've tried to extract the contents of an IM conversation window using IMessengerConversationWnd::History, you might have noticed that the History property always seems to return null.
The trick here is that the conversation text isn't injected into the IM window at the exact moment that it is created; you have to use a timer to check for when the History property returns something other than null.
Here's some code that shows how to use System.Threading.Timer to poll the conversation window. This code doesn't go into how to use the CommunicatorAPI COM objects to hook into Communicator from within your application and wire up the necessary events - the SDK I linked to above has plenty of examples on how to do that.
If you have any questions about that though, hit me up and I'll try to answer them.
We'll start by declaring a Timer object in our class, and also a plain object to hold a reference to a specific IM conversation window:
private Timer timer = null;
private object convWindow;
Communicator WindowCreated Event Handler
In the Communicator WindowCreated event handler, we can tell whether this is an incoming or outgoing conversation window by comparing the window's HWND property to a local variable called windowHandle.
void communicator_OnIMWindowCreated(object pIMWindow)
{
try
{
IMessengerConversationWndAdvanced imWindow =
(IMessengerConversationWndAdvanced)pIMWindow;
if (((IMessengerConversationWndAdvanced)pIMWindow).HWND == windowHandle)
{
// outgoing
}
else
{
// incoming
windowHandle = imWindow.HWND;
HandleIncomingMessage(pIMWindow);
}
}
}
Setting up the Timer
For this example, I'll use a function called HandleIncomingMessage to handle an incoming conversation. I'll pass the conversation window as a parameter to the function.
void HandleIncomingMessage(object pIMWindow)
{
IMessengerConversationWndAdvanced imWindow =
(IMessengerConversationWndAdvanced)pIMWindow;
if (((IMessengerConversationWndAdvanced)pIMWindow).HWND == windowHandle)
{
convWindow = pIMWindow;
timer = new Timer(new TimerCallback(timer_Tick), null,
TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1));
}
}
Note that we check for matching window handles before doing anything - there could be multiple instances of Communicator windows in existence at the same time; we need to make sure that we are dealing with the right window.
Also note that we set our class variable convWindow to the pIMWindow object. This way, the Timer's tick event can access the window to check its History property.
Tick
private void timer_Tick(object state)
{
IMessengerConversationWndAdvanced imWindow =
(IMessengerConversationWndAdvanced)convWindow;
if (imWindow.History != null)
{
string history = imWindow.History; // Do what you need to do here ...
imWindow.Close();
timer.Change(Timeout.Infinite, Timeout.Infinite);
timer.Dispose();
}
}
When the window's History property is finally not null, you can can run whatever logic you need to. In my scenario, I closed the window, set the timer to never fire again, and then disposed it. This way, the next time this happens, the timer will be reinitialized cleanly.
Tick Durations
You should set up your timer to tick at an interval that's convenient for your needs; for example it shouldn't tick again while the timer_Tick handler is still executing.
Cleaning Up
Remember that these are all COM objects that need to be disposed of property. You should use Marshal.ReleaseComObject(... to clean up when you're done.
I just got back from the Bill Gates keynote at ODC 2008 and wanted to share some tidbits.
This is the second time I've heard Bill speak, and both times I found the Q&A session to be a very valuable part of the keynote. Some conference attendees got a chance to ask Bill some questions and express some frustrations with developing around Office and SharePoint.
Here are some of the more interesting point that came out of the Q&A:
- Office 14
- Microsoft is hard at work on Office 14 (looks like we're skipping v13)
- Office 14 will contain a major "Office in the cloud" piece where there will be web versions of programs such as Word, Excel, etc.
- Bill acknowledged that these wouldn't be as feature-rich, but would contain enough functionality for the most common tasks, e.g. OWA vs. Outlook
- SharePoint
- He acknowledged that SharePoint 2007's success caught Microsoft a little by surprise
- They're doing their best to catch up on documentation and developer tool support
- Increased staffing in SharePoint product support
- Future support for enabling Lists to use their own SQL tables for storage
- Apple
- He pointed out that a lot of effort was made to "Apple'ify" Office 2008 for the Mac
- As a result, there are no plans to support things such as VBA and Ribbon extensibility in Office 2008 for the Mac
- This comment came as a result of someone asking if Microsoft would eventually provide support for programming against the object model in Office 2008 for the Mac
Overall, I was impressed by how everybody who asked a question got a straight and informed answer. Well, except the host who asked: "What's up with Yahoo?"
If you're going to be attending ODC 2008 in San Jose this coming week, drop by and visit us at the Clarity Consulting booth!
Jon Rauschenberger (Clarity's CTO) and I will be presenting a demo application that that our team built for the keynote speech that Gurdeep Singh Pall - Corporate Vice President, Unified Communications Group will be giving on the second day of the conference.
Can't share too much right now about the contents of the demo, but it's good stuff. After ODC is over, I'll post a screencast and some more information on the demo itself.
The application would not have looked as amazing as it does without the help of Clarity's WPF Ninja, Erik Klimczak (that really should be his title). Many thanks to Erik for his help, as our colleague Kevin Marshall likes to say, it was a mERIKle ...
Jon will also be leading a session in the Server track: SER 312 - Business Process Communications with UCMA (Unified Communications Managed API). UCMA allows you to build sip applications using managed code. For example, you could implement an IM bot using the UCMA.
I'm personally looking forward to a bunch of sessions in the server track. If you're into SharePoint development, there's a lot of good material there.
Hope to see you at ODC 2008!