Tuesday, September 20, 2011

simple com component creation - 1


I just want to share how to create simple com interface...
This is a sample program for creating simple com component by using IUnknown Interace...

I am executing each and every program before posting here.... you need to have visual studio 6.0 on your system....

#include <iostream.h>
#include <objbase.h>


// Interface One
interface IOne : IUnknown
{
    virtual void __stdcall FOne() = 0 ; //pure virtual function
} ;

// Interface Two
interface ITwo : IUnknown
{
    virtual void __stdcall FTwo() = 0 ;
} ;

// Interface Three
interface IThree : IUnknown
{
    virtual void __stdcall FThree() = 0 ;
} ;

// defining all the functions withing interfaces as purevirtual

// Forward references for GUIDs
extern const IID IID_IOne ;
extern const IID IID_ITwo ;
extern const IID IID_IThree ;

//----------declaration of interfaces is completed---------------------------------------//
now we look into creating of component class
//
// Creating Component Class
//
class CComponent : public IOne, public ITwo
{
    //IUnknown implementation
    virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;           
    virtual ULONG __stdcall AddRef()
    {
        return 0 ;
    }
    virtual ULONG __stdcall Release()
    {
        return 0 ;
    }

    // Interface IOne implementation
    virtual void __stdcall FOne()
    {
        cout << "FOne" << endl ;
    }

    // Interface ITwo implementation
    virtual void __stdcall FTwo()
    {
        cout << "FTwo" << endl ;
    }
} ;
//implementation/definition  of QueryInterface....
HRESULT __stdcall CComponent::QueryInterface(const IID& iid, void** ppv)
{    
    if (iid == IID_IUnknown)
    {
        trace("QueryInterface: Return pointer to IUnknown.") ;
        *ppv = static_cast<IOne*>(this) ;
    }
    else if (iid == IID_IOne)
    {
        trace("QueryInterface: Return pointer to IOne.") ;
        *ppv = static_cast<IOne*>(this) ;
    }
    else if (iid == IID_ITwo)
    {
        trace("QueryInterface: Return pointer to ITwo.") ;
        *ppv = static_cast<ITwo*>(this) ;
    }
    else
    {        
        trace("QueryInterface: Interface not supported.") ;
        *ppv = NULL ;
        return E_NOINTERFACE ;
    }
    reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
    return S_OK ;
}

//
// Creation of instance function
//
IUnknown* CreateInstance()
{
    IUnknown* pI = static_cast<IOne*>(new CComponent) ;
    pI->AddRef() ;
    return pI ;
}

// now its turn of client to use the created component....
// Client to acess the component

int main()
{
    HRESULT hr ;

    IUnknown* pIUnknown = CreateInstance() ;

  
    IOne* pIOne = NULL ;
    hr = pIUnknown->QueryInterface(IID_IOne, (void**)&pIOne) ;
    if (SUCCEEDED(hr))
    {
        pIOne->FOne() ;          // Use interface IOne.
    }

    ITwo* pITwo = NULL ;
    hr = pIUnknown->QueryInterface(IID_ITwo, (void**)&pITwo) ;
    if (SUCCEEDED(hr))
    {
        pITwo->FTwo() ;          // Use interface ITwo.
    }
   
    IThree* pIThree = NULL ;
    hr = pIUnknown->QueryInterface(IID_IThree, (void**)&pIThree) ;
    if (SUCCEEDED(hr))
    {
        pIThree->FThree() ;
    }
    else
    {
        // client could not ge the interface
    }


    ITwo* pITwofromIOne = NULL ;
    hr = pIOne->QueryInterface(IID_ITwo, (void**)&pITwofromIOne) ;
    if (SUCCEEDED(hr))
    {   
        pITwofromIOne->FTwo() ;
    }


    IUnknown* pIUnknownFromITwo = NULL ;
    hr = pITwo->QueryInterface(IID_IUnknown, (void**)&pIUnknownFromITwo) ;
    if (SUCCEEDED(hr))
    {
        cout << "Are the IUnknown pointers equal?  " ;
        if (pIUnknownFromITwo == pIUnknown)
        {
            cout << "Yes, pIUnknownFromITwo == pIUnknown." << endl ;
        }
        else
        {
            cout << "No, pIUnknownFromITwo != pIUnknown." << endl ;
        }
    }

    // Delete the component.
    delete pIUnknown ;

    return 0 ;
}
// you can execute this program straight away and don't forget the code for create iids.... he is the code.... you just need to copy and paste it on your program...
//
// IIDs
//
// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}
static const IID IID_IOne =
    {0x32bb8320, 0xb41b, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;

// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}
static const IID IID_ITwo =
    {0x32bb8321, 0xb41b, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;

// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}
static const IID IID_IThree =
    {0x32bb8322, 0xb41b, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;
 
any doubts please feel free to ask me....

this is just basic com program and will write other program how we can create component in a better way.