且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

一个COM示例程序

更新时间:2022-08-19 14:32:37

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


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/11/17/962867.html,如需转载请自行联系原作者