一个COM示例程序

来源:互联网 发布:服装数据 编辑:程序博客网 时间:2024/06/05 11:56
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;
}