Click here to Skip to main content
Licence 
First Posted 27 Nov 2001
Views 458,358
Bookmarked 44 times

Handling COM Events in a Console Application

By | 26 Jan 2003 | Article
Simple source code that handles COM events easily without the help of MFC, etc.

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 刘向阳



United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionHow can I Fire Message from COM Server to its its client ? Pinmemberjags_vc17:49 4 Feb '06  
GeneralGetting the events PinmemberTravis Smith11:12 27 Jul '05  
GeneralRe: Getting the events PinmemberXiangyang Liu21:51 27 Jul '05  
Travis Smith wrote:
I was really anticipating a function in the console app to be called when events get fired.
 
It is not easy to do that using the code I provided here. This is my experiment with com events, it can be hacked to do what you want but it is definitely not the easy way and not for beginners.
 
Good luck.
 




My articles and software tools





GeneralTrigger an event in a COM addin PinmemberAnthony_Yio20:34 28 Sep '04  
QuestionHandling COM Events in a Console Application? PinsussAnonymous16:34 18 Feb '04  
AnswerRe: Handling COM Events in a Console Application? PinmemberXiangyang Liu1:32 19 Feb '04  
GeneralGetting 0x800706f4 PinmemberMohammad Asim Shaikh0:04 31 Jan '04  
GeneralRe: Getting 0x800706f4 PinmemberXiangyang Liu3:53 31 Jan '04  
GeneralRe: Getting 0x800706f4 PinmemberMohammad Asim Shaikh15:42 1 Feb '04  
GeneralRe: Getting 0x800706f4 PinmemberXiangyang Liu16:22 1 Feb '04  
Generalto a "not a COM expert, the first time using the IConnectionPoint interface" PinsussAnonymous7:19 18 Jan '04  
GeneralBut how COM post a message to app? I own both the COM and app. Pinmemberxiaochnegwx15:28 29 Mar '03  
GeneralCatching excel events inside DLL Pinmemberfrisco23:59 19 Jun '02  
GeneralAlternative simple sink approach PinmemberChopper3:19 25 Mar '02  
GeneralRe: Alternative simple sink approach PinmemberXiangYangLiu1:06 29 Mar '02  
GeneralRe: Alternative simple sink approach PinmemberChopper22:43 7 May '03  
GeneralRe: Alternative simple sink approach PinmemberXiangyang Liu2:21 8 May '03  
GeneralExcellent work... PinmemberAkash Kava8:59 14 Feb '02  
GeneralUpdate 2002/01/28 PinmemberXiangYangLiu4:14 28 Jan '02  
GeneralI'm lost... Pinmemberigor196019:45 10 Dec '01  
GeneralRe: I'm lost... PinmemberXiangYangLiu0:27 11 Dec '01  
GeneralRe: I'm lost... Pinmemberigor196017:50 11 Dec '01  
GeneralRe: I'm lost... PinmemberXiangYangLiu2:46 12 Dec '01  
QuestionSo where are the events? PinmemberAndy Friedman7:12 5 Dec '01  
AnswerRe: So where are the events? PinmemberXiangYangLiu8:07 5 Dec '01  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120529.1 | Last Updated 27 Jan 2003
Article Copyright 2001 by Xiangyang Liu 刘向阳
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid