ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MFC로 커스텀 interface COM 클래스 만들기 - IDL, Out Of Process
    컴포넌트(COM)/MFC 2008. 11. 21. 23:35
    #include <afxctl.h>

    BOOL CSpcLocalApp::InitInstance()
    {
    ...
    // {
       if (!AfxOleInit()) {
           AfxMessageBox("Could not initialize OLE subsystem.");
           return FALSE;
       }
    // }
    #ifdef _AFXDLL
        Enable3dControls();            // Call this when using MFC in a shared DLL
    #else
        Enable3dControlsStatic();    // Call this when linking to MFC statically
    #endif
    // {
       CCommandLineInfo CmdInfo;
       ParseCommandLine(CmdInfo);

       // Check to see if launched as OLE server
       if (CmdInfo.m_bRunEmbedded || CmdInfo.m_bRunAutomated)
       {
          // Application was run with /Embedding or /Automation.

          // Register all OLE server (factories) as running.  This enables the
          //  OLE libraries to create objects from other applications.
          COleObjectFactory::RegisterAll();
          return TRUE;
       }

       CString strClassID, strProgID;
       strClassID.LoadString(IDS_CLASSID);
       strProgID.LoadString(IDS_PROGID);
    // }
        CSpcLocalDlg dlg;
    //    m_pMainWnd = &dlg;
        int nResponse = dlg.DoModal();
    // {
        if (nResponse == ID_REGISTER)
        {
            RegisterComponent(strProgID);
        }
        else if (nResponse == ID_UNREGISTER)
        {
            UnregisterComponent(strClassID, strProgID);
        }
    // }
    ...
    }

    VOID CSpcLocalApp::RegisterComponent(const CString &strProgID)
    {
       // Place the server into the system registry
       COleObjectFactory::UpdateRegistryAll();

       CString strMsg;
       strMsg += "The " + strProgID + " server has been registered.";
       AfxMessageBox(strMsg, MB_ICONINFORMATION);
    }

    VOID CSpcLocalApp::UnregisterComponent(const CString &strClassID, const CString &strProgID)
    {
       // Transform the string-format CLASSID into a real CLSID
       CLSID CLSID_Component;
       BSTR bstrClassID = strClassID.AllocSysString();
       CLSIDFromString(bstrClassID, &CLSID_Component);
       SysFreeString(bstrClassID);

       // Unregister the class
       AfxOleUnregisterClass(CLSID_Component, strProgID);

       CString strMsg;
       strMsg += "The " + strProgID + " server has been registered.";
       AfxMessageBox(strMsg, MB_ICONINFORMATION);
    }

    import "wtypes.idl";
    import "unknwn.idl";

    [
        object,
        uuid(2C1FDBD6-556B-4a50-B63C-F2B64A6DDC38),
        helpstring("ISimpleCal interface"),
        pointer_default(unique)
    ]
    interface ISimpleCal:IUnknown
    {
       HRESULT Sum ([in] int x, [in] int y, [out]int* z);
       HRESULT Sub ([in] int x, [in] int y, [out]int* z);
    };

    //
    //  Class information for SimpleCal
    //   
    [ uuid(45C971F6-3A78-4163-A994-FDBB6894F4B2) ]
    coclass COMPONENT
    {
        interface ISimpleCal;
    };


    #ifndef SIMPLECALC_H
    #define SIMPLECALC_H

    #include "..\..\Common\SpcCom2.h"
    //#include "..\Common\spcproxy.h"

    class CSimpleCalc : public CCmdTarget
    {
    public:   
        // Constructor   
        CSimpleCalc();
        // Destructor   
        virtual ~CSimpleCalc();


    protected:   
        BEGIN_INTERFACE_PART(CInnerSimpleCal, ISimpleCal)
            STDMETHOD(Sum)(int x, int y, int* z);
            STDMETHOD(Sub)(int x, int y, int* z);
        END_INTERFACE_PART(CInnerSimpleCal)


        DECLARE_INTERFACE_MAP()
        DECLARE_OLECREATE(CSimpleCalc)
        DECLARE_DYNCREATE(CSimpleCalc)

    };

    typedef CSimpleCalc* PSimpleCalc;

    #endif

    #include "stdafx.h"
    #include "spclocal1.h"
    #include "..\..\Common\SpcCom2_i.c"
    //#include "..\Common\SpcProxy_i.c"

    // Support dynamic creation
    IMPLEMENT_DYNCREATE(CSimpleCalc, CCmdTarget)

    // {60D754D5-DDBA-4d23-A84A-63A812AB2C49}
    // {45C971F6-3A78-4163-A994-FDBB6894F4B2}
    IMPLEMENT_OLECREATE(CSimpleCalc, "CLSID_COMPONENT",
    0x45C971F6, 0x3A78, 0x4163, 0xA9, 0x94, 0xFD, 0xBB, 0x68, 0x94, 0xF4, 0xB2);
    //0x60d754d5, 0xddba, 0x4d23, 0xa8, 0x4a, 0x63, 0xa8, 0x12, 0xab, 0x2c, 0x49);

    BEGIN_INTERFACE_MAP(CSimpleCalc, CCmdTarget)
       INTERFACE_PART(CSimpleCalc, IID_ISimpleCal,     CInnerSimpleCal)
    END_INTERFACE_MAP()

    CSimpleCalc::CSimpleCalc()
    {
       AfxOleLockApp();
    }

    CSimpleCalc::~CSimpleCalc()
    {
       AfxOleUnlockApp();
    }

    // ISimpleCal
    STDMETHODIMP_(ULONG)
    CSimpleCalc::XCInnerSimpleCal::AddRef()
    {
       METHOD_PROLOGUE(CSimpleCalc, CInnerSimpleCal)
       return pThis->ExternalAddRef();
    }

    STDMETHODIMP_(ULONG)
    CSimpleCalc::XCInnerSimpleCal::Release()
    {
       METHOD_PROLOGUE(CSimpleCalc, CInnerSimpleCal)
       return pThis->ExternalRelease();
    }

    STDMETHODIMP
    CSimpleCalc::XCInnerSimpleCal::QueryInterface(REFIID riid, LPVOID* ppv)
    {
       METHOD_PROLOGUE(CSimpleCalc, CInnerSimpleCal)
       return pThis->ExternalQueryInterface(&riid, ppv);
    }

    STDMETHODIMP
    CSimpleCalc::XCInnerSimpleCal::Sum(int x, int y, int* z)   
    {       
        *z = x + y;   
        return S_OK;
    }   

    STDMETHODIMP
    CSimpleCalc::XCInnerSimpleCal::Sub(int x, int y, int* z)   
    {       
        *z = x - y;   
        return S_OK;
    }

    새 "Win32 Dynamic-Link Library" 프로젝트를 생성한다.

    ; SpcProxy.def : Declares the module parameters for the DLL.

    LIBRARY  "SpcProxy.dll"
    DESCRIPTION  'SpcProxy.dll Windows Dynamic Link Library'

    EXPORTS
             DllGetClassObject   @1 PRIVATE
             DllCanUnloadNow     @2 PRIVATE
             DllRegisterServer   @3 PRIVATE
             DllUnregisterServer @4 PRIVATE
             GetProxyDllInfo     @5 PRIVATE

    IDL 파일이 생성한 모든 파일을 프로젝트에 포함한다.
Designed by Tistory.