一个COM示例程序

本文介绍了一个COM组件的实现方式,包括组件的创建、接口的注册及调用过程。通过具体代码展示了如何利用CLSID从ProgID中获取,如何通过CoGetClassObject获取类工厂对象,进而创建组件实例并调用其方法。
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

Code

// Spaceship.cpp : implementation file

Code

正规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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值