Click here to Skip to main content
6,295,667 members and growing! (13,016 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » COM / COM+ » COM     Intermediate

Handling COM Events in a Console Application

By Xiangyang Liu 刘向阳

Simple source code that handles COM events easily without the help of MFC, etc.
VC6, VC7Win2K, WinXP, COM, Dev
Posted:27 Nov 2001
Updated:26 Jan 2003
Views:201,705
Bookmarked:36 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
111 votes for this article.
Popularity: 8.46 Rating: 4.14 out of 5
4 votes, 36.4%
1

2
2 votes, 18.2%
3

4
5 votes, 45.5%
5

Introduction

The MFC class library makes handling ActiveX control events so easy that you are misled to believe that handling COM events is no big deal, until you try to do it within a console application. As you may have heard, I wrote the very simple XYDispDriver class, which can be used to create COM objects and call COM methods easily, especially in console applications. It would be nice if we can also use XYDispDriver to handle COM events, so I started to work on its enhancement.

Basically, a COM event is the opposite of COM method. Your code calls the methods in a COM object, and if you set up this thing called "event sink" correctly, the COM object will call your code (i.e. event handlers) when something happens within the object. That's why the COM event interface is called the "outgoing interface" (depending on which side you are standing, I guess).

Here is my idea. If I have a COM object which fires events, I will be able to find out the event interface, including its class ID and function signatures, from the type library. I will build a new COM object as my event handler, whose methods will match those in the event interface of the original COM object (same dispid, same signature, etc.). The magic is, I will use the XYDispDriver class to create both objects and somehow "connect" them together. Whenever the original object fires an event, the corresponding method in the new object will be called to handle the event. Of course, I have to make it easy to use (in console applications). You can add more methods to the event handler object, even passing function pointers to it so that you can call functions defined outside the object when handling events.

As you can see from the source code, I added an Advise method to the XYDispDriver class. This method takes two arguments, the first argument is the IDispatch pointer of the new COM object (the event handler), the second one is the class ID of the event interface of the original COM object. Calling the Advise method is all it takes to "connect" the event handler to the event interface. The Advise method is implemented with some boring COM API calls (QueryInterface, FindConnectionPoint, etc.), but the code is surprisingly simple. By the way, you don't have to bother with Unadvise (if you have heard of it), it is done automatically when the XYDispDriver object goes out of scope.

Now we test the idea. Using the MFC Control Wizard, I first created an ActiveX control TestCon, which has one method called Connect, this method will fire an InvalidLoginData event whenever it fails. Then I created a second ActiveX control TestHndlr as the event handler for the first control. The second control has one method that matches the dispid and signature of the InvalidLoginData event in the first control, the handler method will pop up a message box when it is invoked. Finally, I wrote a console application that uses these two controls. Here is the code of the console app.

#include <stdio.h> 

#include "XYDispDriver.h"


void main() 
{ 
    // declare two XYDispDriver variables 

    XYDispDriver dispCon, dispEvent; 
    // create the TestCon control 

    if(dispCon.CreateObject("TestCon.1")) 
    { 
        // create the TestHndlr control 

        if(dispEvent.CreateObject("TestHndlr.1")) 
        { 
            // the class id of the event interface in the TestCon control 

            CLSID clsidEvent = {0xe77a1f7e,0xe3ff,0x11d5,
               {0x88,0x12,0x00,0xb0,0xd0,0x55,0xb5,0x23}}; 
            // call the Advice method to set up the event handler 

            dispCon.Advise(dispEvent.GetDispatch(),clsidEvent); 
        } 
        else printf("Error: %x\n",dispEvent.GetLastError()); 
        // call the Connect method, passing "username"

        // and "password" parameters 

        // it should generate an event in either one of the following cases: 

        // 1. "username" or "password" is empty 

        // 2. "password" length < 6 

        // 3. "password" equals "username" 

        dispCon.InvokeMethod("Connect","MyName","MyPwd"); 
        // you should see the event message box by now 

    } 
    else printf("Error: %x\n",dispCon.GetLastError()); 
    ::MessageBox(NULL,_T("Done"),_T("Test"),MB_OK); 
}

You can use the same technique with a more complicated event interface, of course. I have tested my XYMessenger.OCX control with this method, so it can now be used even in console applications. The more complicated situations (such as multiple event sinks, etc.) will be dealt with in a separate article.

The zip file included with this article only has source code for the two ActiveX controls and the console app. You can download the source code for XYDispDriver from my other article. You can also find other articles and software from my home page.

Disclaimer

I do not claim that I invented anything new here. I am not a COM expert, this is actually the first time I used the IConnectionPoint interface. There could be other more "standard" ways to do the same thing. Thank you.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Xiangyang Liu 刘向阳


Member

Location: United States United States

Other popular COM / COM+ articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 45 (Total in Forum: 45) (Refresh)FirstPrevNext
GeneralHow can I Fire Message from COM Server to its its client ? Pinmemberjags_vc18:49 4 Feb '06  
GeneralGetting the events PinmemberTravis Smith12:12 27 Jul '05  
GeneralRe: Getting the events PinmemberXiangyang Liu22:51 27 Jul '05  
GeneralTrigger an event in a COM addin PinmemberAnthony_Yio21:34 28 Sep '04  
GeneralHandling COM Events in a Console Application? PinsussAnonymous17:34 18 Feb '04  
GeneralRe: Handling COM Events in a Console Application? PinmemberXiangyang Liu2:32 19 Feb '04  
GeneralGetting 0x800706f4 PinmemberMohammad Asim Shaikh1:04 31 Jan '04  
GeneralRe: Getting 0x800706f4 PinmemberXiangyang Liu4:53 31 Jan '04  
GeneralRe: Getting 0x800706f4 PinmemberMohammad Asim Shaikh16:42 1 Feb '04  
GeneralRe: Getting 0x800706f4 PinmemberXiangyang Liu17:22 1 Feb '04  
Generalto a "not a COM expert, the first time using the IConnectionPoint interface" PinsussAnonymous8:19 18 Jan '04  
GeneralBut how COM post a message to app? I own both the COM and app. Pinmemberxiaochnegwx16:28 29 Mar '03  
GeneralCatching excel events inside DLL Pinmemberfrisco0:59 20 Jun '02  
GeneralAlternative simple sink approach PinmemberChopper4:19 25 Mar '02  
GeneralRe: Alternative simple sink approach PinmemberXiangYangLiu2:06 29 Mar '02  
GeneralRe: Alternative simple sink approach PinmemberChopper23:43 7 May '03  
GeneralRe: Alternative simple sink approach PinmemberXiangyang Liu3:21 8 May '03  
GeneralExcellent work... PinmemberAkash Kava9:59 14 Feb '02  
GeneralUpdate 2002/01/28 PinmemberXiangYangLiu5:14 28 Jan '02  
GeneralI'm lost... Pinmemberigor196020:45 10 Dec '01  
GeneralRe: I'm lost... PinmemberXiangYangLiu1:27 11 Dec '01  
GeneralRe: I'm lost... Pinmemberigor196018:50 11 Dec '01  
GeneralRe: I'm lost... PinmemberXiangYangLiu3:46 12 Dec '01  
GeneralSo where are the events? PinmemberAndy Friedman8:12 5 Dec '01  
GeneralRe: So where are the events? PinmemberXiangYangLiu9:07 5 Dec '01  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 26 Jan 2003
Editor: Smitha Vijayan
Copyright 2001 by Xiangyang Liu 刘向阳
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project