一个COM示例程序

void  CEx24cView::OnTestSpaceship() 
{
    CLSID clsid;
    LPCLASSFACTORY pClf; 
    LPUNKNOWN pUnk;
    IMotion
*  pMot;
    IVisual
*  pVis;
    HRESULT hr;

    
if  ((hr  =  ::CLSIDFromProgID(L " Spaceship " & clsid))  !=  NOERROR) 
    {
        TRACE(
" unable to find Program ID -- error = %x\n " , hr);
        
return ;
    }
    
if  ((hr  =  ::CoGetClassObject(clsid, CLSCTX_INPROC_SERVER,
        NULL, IID_IClassFactory, (
void   ** & pClf))  !=  NOERROR) {;
        TRACE(
" unable to find CLSID -- error = %x\n " , hr);
        
return ;
    }

    pClf
-> CreateInstance(NULL, IID_IUnknown, ( void ** & pUnk);
    pUnk
-> QueryInterface(IID_IMotion, ( void ** & pMot);  //  All three
    pMot -> QueryInterface(IID_IVisual, ( void ** & pVis);  //   pointers
                                                       
//   should work
    TRACE( " main: pUnk = %p, pMot = %p, pDis = %p\n " , pUnk, pMot, pVis);
    
    
//  Test all the interface virtual functions
    pMot -> Fly();
    
int  nPos  =  pMot -> GetPosition();
    TRACE(
" nPos = %d\n " , nPos);
    pVis
-> Display();

    pClf
-> Release();
    pUnk
-> Release();
    pMot
-> Release();
    pVis
-> Release();
    AfxMessageBox(
" Test succeeded. See Debug window for output. " );
}

// interface.h

struct  IMotion :  public  IUnknown
{
    STDMETHOD_(
void , Fly) ()  =   0 ;
    STDMETHOD_(
int & , GetPosition) ()  =   0 ;
};

struct  IVisual :  public  IUnknown
{
    STDMETHOD_(
void , Display) ()  =   0 ;
};

// Spaceship.h : header file

ContractedBlock.gif ExpandedBlockStart.gif Code

void ITrace(REFIID iid, const char* str);

/////
// CSpaceship command target

class CSpaceship : public CCmdTarget
{
    DECLARE_DYNCREATE(CSpaceship)
private:
    
int m_nPosition; // We can access this from all the interfaces
    int m_nAcceleration;
    
int m_nColor;
protected:
    CSpaceship();           
// protected constructor used by dynamic creation

// Attributes
public:

// Operations
public:

// Overrides
    
// ClassWizard generated virtual function overrides
    
//{{AFX_VIRTUAL(CSpaceship)
    public:
    
virtual void OnFinalRelease();
    
//}}AFX_VIRTUAL

// Implementation
protected:
    
virtual ~CSpaceship();

    
// Generated message map functions
    
//{{AFX_MSG(CSpaceship)
        
// NOTE - the ClassWizard will add and remove member functions here.
    
//}}AFX_MSG

    DECLARE_MESSAGE_MAP()
    DECLARE_OLECREATE(CSpaceship)

    BEGIN_INTERFACE_PART(Motion, IMotion)
        STDMETHOD_(
void, Fly) ();
        STDMETHOD_(
int&, GetPosition) ();
    END_INTERFACE_PART(Motion)
    
    BEGIN_INTERFACE_PART(Visual, IVisual)
        STDMETHOD_(
void, Display) ();
    END_INTERFACE_PART(Visual)

    DECLARE_INTERFACE_MAP()
};

// Spaceship.cpp : implementation file

ContractedBlock.gif ExpandedBlockStart.gif Code
//
// CSpaceship

// {692D03A4-C689-11CE-B337-88EA36DE9E4E}
static const IID IID_IMotion =
0x692d03a40xc6890x11ce,
    { 
0xb30x370x880xea0x360xde0x9e0x4e } };

// {692D03A5-C689-11CE-B337-88EA36DE9E4E}
static const IID IID_IVisual =
0x692d03a50xc6890x11ce,
    { 
0xb30x370x880xea0x360xde0x9e0x4e } };

IMPLEMENT_DYNCREATE(CSpaceship, CCmdTarget)

CSpaceship::CSpaceship()
{
    TRACE(
"CSpaceship ctor\n");
    m_nPosition 
= 100;
    m_nAcceleration 
= 101;
    m_nColor 
= 102;
    
// To keep the application running as long as an OLE automation
    
//   object is active, the constructor calls AfxOleLockApp.
    
    AfxOleLockApp();
}

CSpaceship::
~CSpaceship()
{
    TRACE(
"CSpaceship dtor\n");
    
// To terminate the application when all objects created with
    
//   OLE automation, the destructor calls AfxOleUnlockApp.
    
    AfxOleUnlockApp();
}

void CSpaceship::OnFinalRelease()
{
    
// When the last reference for an automation object is released
    
//   OnFinalRelease is called. This implementation deletes the 
    
//   object. Add additional cleanup required for your object before
    
//   deleting it from memory.

    delete 
this;
}


BEGIN_MESSAGE_MAP(CSpaceship, CCmdTarget)
    
//{{AFX_MSG_MAP(CSpaceship)
    
// NOTE - the ClassWizard will add and remove mapping macros here.
    
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_INTERFACE_MAP(CSpaceship, CCmdTarget)
    INTERFACE_PART(CSpaceship, IID_IMotion, Motion)
    INTERFACE_PART(CSpaceship, IID_IVisual, Visual)
END_INTERFACE_MAP()

// {692D03A3-C689-11CE-B337-88EA36DE9E4E}
IMPLEMENT_OLECREATE(CSpaceship, "Spaceship"0x692d03a30xc689,
                    
0x11ce0xb30x370x880xea0x360xde,
                    
0x9e0x4e)

STDMETHODIMP_(ULONG) CSpaceship::XMotion::AddRef()
{
    TRACE(
"CSpaceship::XMotion::AddRef\n");
    METHOD_PROLOGUE(CSpaceship, Motion)
    
return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CSpaceship::XMotion::Release()
{
    TRACE(
"CSpaceship::XMotion::Release\n");
    METHOD_PROLOGUE(CSpaceship, Motion)
    
return pThis->ExternalRelease();
}

STDMETHODIMP CSpaceship::XMotion::QueryInterface(
    REFIID iid, LPVOID
* ppvObj)
{
    ITrace(iid, 
"CSpaceship::XMotion::QueryInterface");
    METHOD_PROLOGUE(CSpaceship, Motion)
    
return pThis->ExternalQueryInterface(&iid, ppvObj);
}


STDMETHODIMP_(
void) CSpaceship::XMotion::Fly()
{
    TRACE(
"CSpaceship::XMotion::Fly\n");
    METHOD_PROLOGUE(CSpaceship, Motion)
    TRACE(
"m_nPosition = %d\n", pThis->m_nPosition);
    TRACE(
"m_nAcceleration = %d\n", pThis->m_nAcceleration);
    
return;
}

STDMETHODIMP_(
int&) CSpaceship::XMotion::GetPosition()
{
    TRACE(
"CSpaceship::XMotion::GetPosition\n");
    METHOD_PROLOGUE(CSpaceship, Motion)
    TRACE(
"m_nPosition = %d\n", pThis->m_nPosition);
    TRACE(
"m_nAcceleration = %d\n", pThis->m_nAcceleration);
    
return pThis->m_nPosition;
}

//
STDMETHODIMP_(ULONG) CSpaceship::XVisual::AddRef()
{
    TRACE(
"CSpaceship::XVisual::AddRef\n");
    METHOD_PROLOGUE(CSpaceship, Visual)
    
return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CSpaceship::XVisual::Release()
{
    TRACE(
"CSpaceship::XVisual::Release\n");
    METHOD_PROLOGUE(CSpaceship, Visual)
    
return pThis->ExternalRelease();
}

STDMETHODIMP CSpaceship::XVisual::QueryInterface(
    REFIID iid, LPVOID
* ppvObj)
{
    ITrace(iid, 
"CSpaceship::XVisual::QueryInterface");
    METHOD_PROLOGUE(CSpaceship, Visual)
    
return pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP_(
void) CSpaceship::XVisual::Display()
{
    TRACE(
"CSpaceship::XVisual::Display\n");
    METHOD_PROLOGUE(CSpaceship, Visual)
    TRACE(
"m_nPosition = %d\n", pThis->m_nPosition);
    TRACE(
"m_nColor = %d\n", pThis->m_nColor);
}

//
void ITrace(REFIID iid, const char* str)
{
    OLECHAR
* lpszIID;
    ::StringFromIID(iid, 
&lpszIID);
    CString strTemp 
= (LPCWSTR) lpszIID;
    TRACE(
"%s - %s\n", (const char*) strTemp, (const char*) str);
    AfxFreeTaskMem(lpszIID);
}

正规DLL部分代码


/// //
//  CEx24bApp initialization

BOOL CEx24bApp::InitInstance()
{
    
//  Register all OLE server (factories) as running.  This enables the
    
//   OLE libraries to create objects from other applications.
    COleObjectFactory::RegisterAll();

    
return  TRUE;
}

/// //
//  Special entry points required for inproc servers

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID
*  ppv)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
return  AfxDllGetClassObject(rclsid, riid, ppv);
}

STDAPI DllCanUnloadNow(
void )
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
return  AfxDllCanUnloadNow();
}

//  by exporting DllRegisterServer, you can use regsvr.exe
STDAPI DllRegisterServer( void )
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    COleObjectFactory::UpdateRegistryAll();
    
return  S_OK;
}

要想运行客户端和组件程序,必须先注册组件来更新注册表,可以使用如下的代码:

BOOL CRegCompApp::InitInstance()
{
    SetRegistryKey(_T(
" Local AppWizard-Generated Applications " ));
    
//  make sure to set Explorer options to allow DLLs to be visible
    CSpecialFileDialog dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY  |  OFN_OVERWRITEPROMPT,
        
" OCX files (*.ocx)|*.ocx|DLL files (*.dll)|*.dll|| " );
    dlgFile.m_ofn.lpstrTitle 
=   " 注册OCX/DLL File " ;
    
if (dlgFile.DoModal()  !=  IDOK)   return  FALSE;
    CString strDllPath 
=  dlgFile.GetPathName(); // 获取文件名
    
//  this wouldn't work for a dynamically linked Regular DLL
    HINSTANCE h  =  ::LoadLibrary(strDllPath); // 加载dll
     if (h  ==  NULL)
    {
        CString msg;
        msg.Format(
" Failed to find server %s " , strDllPath);
        AfxMessageBox(msg);
        
return  FALSE;
    }
    FARPROC pFunc 
=  ::GetProcAddress((HMODULE) h,  " DllRegisterServer " );
    
if (pFunc  ==  NULL) {
        AfxMessageBox(
" Failed to find DllRegisterServer function " );
        
return  FALSE;
    }
    (
* pFunc)();     //  call the function to register the server 注册
    AfxMessageBox( " Server registered OK " );
    
return  FALSE;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值