Click here to Skip to main content
Licence 
First Posted 22 Nov 1999
Views 184,249
Bookmarked 41 times

Using ActiveX Control Within A Console Application

By | 22 Nov 1999 | Article

As we know, using an ActiveX control in an MFC application is very easy. However, on many occasions I need to use an ActiveX control within a console application. For example, I need to send e-mail from an NT service program in one of my recent projects. Here is what I did to solve this problem.

  1. Create an ActiveX control using simple MAPI calls that exposes only a SendMail method.
  2. Write a few simple functions that can be used in a console app to create the ActiveX control and call its methods.
  3. Send e-mail within my NT service program using the above functions.

Note: The functions I wrote in step 2 can handle methods that take only string arguments (the return type is not restricted). But they can be modified easily to handle more complicated arguments.

Here is a piece of sample code in a console application that sends an e-mail message using the ActiveX control I built.

//*************** sample code ************************ 

 static CLSID clsid = {0xfd543ffb, 0x9664, 0x11d3, {0x8b, 0xd9, 0x40, 0, 0x31, 
                                                    0x3, 0x95, 0xe3}}; 
 VARIANT varOutput; 
 IDispatch* pInterface = 0; 

 // create my ActiveX control 
 if(CreateComDispatch(clsid,&pInterface)) 
 { 
        // prepare arguments: send a test message to "xliu" and cc to "jrao". 
        const char * pParams[] = {"xliu", "jrao", "test message title", 
                                  "test message text"}; 

        // invoke the SendMail method 
        if(CallStringMethodByName(pInterface, "SendMail", 4, pParams,
                                  &varOutput)) 
        { 
                // success 
        } 
        else 
        { 
                // failure 
        } 
 } 

//*********** end of sample code ******************* 

Here is header file for the fucntions in step 2.

// *************** file: ConsoleUtility.h *************************** 

#ifndef CONSOLEUTILITY_H 
#define CONSOLEUTILITY_H 

#include <wtypes.h> 

// create an ActiveX control object 
// return a pointer to the IDispatch interface if successful 
// return 0 otherwise 
IDispatch* CreateComDispatch(REFCLSID clsid,IDispatch** ppDisp); 

// call a method specified by its dispatch id with the given IDispatch pointer 
// return 1 if successful, otherwise return 0 
int CallStringMethodByID(IDispatch* pDisp, 
                         const DISPID dispid, 
                         const int nParamCount, 
                         const char* pInputParam[], 
                         VARIANT* pOutput);

// call a method specified by its name with the given IDispatch pointer 
// return 1 if successful, otherwise return 0 
int CallStringMethodByName(IDispatch* pDisp, 
                           const char* pName, 
                           const int nParamCount, 
                           const char* pInputParam[], 
                           VARIANT* pOutput);
#endif 

//*************** end: ConsoleUtility.h ************************ 

Here is the implementation file.

//*************** file: ConsoleUtility.cpp ******************* 

#include "ConsoleUtility.h" 

IDispatch* CreateComDispatch(REFCLSID clsid,IDispatch** ppDisp) 
{ 
        // initialize COM 
        static int init = 1; 
        if(init) 
        { 
                if(CoInitialize(NULL)!=S_OK) return 0; 
                init = 0; 
        } 
        // create the control 
        HRESULT hRet = CoCreateInstance(clsid, 
                                        NULL,  
                                        1, 
                                        IID_IDispatch, 
                                        (void**)(ppDisp) ); 
        // examine return value 
        if(hRet!=S_OK) 
        { 
                *ppDisp = 0; 
        } 
        return *ppDisp; 
} 

// local helper function to convert char string to unicode string 
static unsigned short* GetBuffer(const char* input) 
{ 
        int nSize = 1; 
        if(input!=0) 
        { 
                nSize += strlen(input); 
        } 
        short* output = new short[nSize]; 
        for(int i=0;i<nSize-1;i++) 
        { 
                output[i] = input[i]; 
        } 
        output[nSize-1] = 0; 
        return (unsigned short*)output; 
} 

int CallStringMethodByID(IDispatch* pDisp, 
                         const DISPID dispid, 
                         const int nParamCount, 
                         const char* pInputParam[], 
                         VARIANT* pOutput)  
{ 
        HRESULT hRet; 
        // build parameter list 
        DISPPARAMS callParams = {NULL,NULL,0,0}; 
        if(nParamCount>0) 
        { 
                callParams.cArgs = nParamCount; 
                callParams.rgvarg = new VARIANTARG[nParamCount]; 
                unsigned short * output; 
                for(int i=0;i<nParamCount;i++) 
                { 
                        output = GetBuffer(pInputParam[nParamCount-i-1]); 
                        callParams.rgvarg[i].bstrVal = ::SysAllocString(output); 
                        callParams.rgvarg[i].vt = VT_BSTR; 
                        delete []output; 
                } 
        } 
        
        // invoke the method 
        unsigned int nArgErr; 
        hRet = pDisp->Invoke(dispid, 
                            IID_NULL, 
                            LOCALE_SYSTEM_DEFAULT, 
                            DISPATCH_METHOD, 
                            &callParams, 
                            pOutput, 
                            NULL, 
                            &nArgErr); 
                            
        // examine the return value 
        if(hRet!=S_OK) 
        { 
                if(nParamCount>0) delete [](callParams.rgvarg); 
                return 0; 
        } 
        if(nParamCount>0) delete [](callParams.rgvarg); 
        return 1; 
} 

int CallStringMethodByName(IDispatch* pDisp, 
                           const char* pName, 
                           const int nParamCount, 
                           const char* pInputParam[], 
                           VARIANT* pOutput) 
{ 
        HRESULT hRet; 
        DISPID dispid; 
        unsigned short* pOLEName = GetBuffer(pName); 
        // get the id of the method 
        hRet = pDisp->GetIDsOfNames(IID_NULL, 
                                    &pOLEName, 
                                    1, 
                                    LOCALE_SYSTEM_DEFAULT, 
                                    &dispid); 
        delete []pOLEName; 
        if(hRet!=S_OK) 
        { 
                return 0; 
        } 
        // invoke the method by id 
        return CallStringMethodByID(pDisp, 
                                    dispid, 
                                    nParamCount, 
                                    pInputParam, 
                                    pOutput); 
} 

//*************** end: ConsoleUtility.cpp ************************ 
  

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
QuestionWhy are you not using MultiByteToWideChar?? PinmemberHanbo14:56 21 Nov '06  
GeneralUsing ActiveX Control Within A Console Application Pinmemberashok1233:40 13 Sep '05  
GeneralUse of new operator PinmemberDJ_Toot0:26 4 Feb '04  
GeneralRe: Use of new operator PinmemberXiangyang Liu1:13 4 Feb '04  
GeneralRe: Use of new operator PinmemberDJ_Toot1:49 4 Feb '04  
GeneralRe: Use of new operator PinmemberXiangyang Liu5:15 4 Feb '04  
GeneralRe: Use of new operator PinmemberDJ_Toot0:47 5 Feb '04  
GeneralRe: Use of new operator PinmemberXiangyang Liu8:16 5 Feb '04  
GeneralRe: Use of new operator PinmemberDJ_Toot22:27 5 Feb '04  
GeneralWCHAR * to usnigned short * Pinsussanon786511:47 15 Oct '03  
GeneralRe: WCHAR * to usnigned short * PinmemberXiangyang Liu0:58 16 Oct '03  
GeneralRe: WCHAR * to usnigned short * Pinsussanon78565:38 16 Oct '03  
GeneralMS FlexGrid PinmemberRobert Williams9:24 13 May '02  
GeneralTroubles Accessing ocx funcions Pinmembermark722:30 16 Feb '02  
GeneralRe: Troubles Accessing ocx funcions PinmemberXiangYangLiu3:36 16 Feb '02  
GeneralRe: Troubles Accessing ocx funcions Pinmembermark728:38 16 Feb '02  
GeneralRe: Troubles Accessing ocx funcions PinsussAnonymous9:36 13 Sep '02  
GeneralRe: Troubles Accessing ocx funcions PinsussXiangYangLiu23:39 13 Sep '02  
GeneralUpdates from the Author PinmemberXiangYangLiu5:18 5 Oct '01  
GeneralMicrosoft FlexGrid Control PinmemberAnonymous22:05 2 Jul '01  
GeneralRe: Microsoft FlexGrid Control PinmemberAnonymous23:43 2 Jul '01  
Questionexample.zip ? PinmemberAnonymous10:00 26 Dec '00  
QuestionHow to use events from ActiveX in this sample ? PinsussRyszard Krakowiak20:21 15 Mar '00  

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.120517.1 | Last Updated 23 Nov 1999
Article Copyright 1999 by Xiangyang Liu 刘向阳
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid