ActiveX/IObject Safety인터페이스구현


Active-X 컨트롤에 Safe 옵션을 추가하는 방법은 컨트롤이 인스톨 되거나 그 후에 Certains function을 컨트롤이 직접 호출하는 방법과 그 컨트롤에 직접 IobjectSafety 인터페이스를 직접구현하는 방법 두가지가 있습니다.

레지스터에 등록하는 동안 컨트롤을 마크하는 방법

CONTROL NAME CTRL.CPP에 HELPERS.H와 OBJSAFE.H를 Include한 다음 ControlClass::ControlClassFactory::UpdateRegistry 에 다음 코드를 삽입
    // Mark as safe for scripting-failure OK.
    HRESULT hr = CreateComponentCategory(CATID_SafeForScripting, 
        L"Controls that are safely scriptable");
    
    if (SUCCEEDED(hr))
        // Only register if category exists.
        RegisterCLSIDInCategory(m_clsid, CATID_SafeForScripting);
        // Don't care if this call fails.
    
    // Mark as safe for data initialization.
    hr = CreateComponentCategory(CATID_SafeForInitializing, 
        L"Controls safely initializable from persistent data");
    
    if (SUCCEEDED(hr))
        // Only register if category exists.
        RegisterCLSIDInCategory(m_clsid, CATID_SafeForInitializing);
        // Don't care if this call fails.


IobjectSafety 인터페이스를 구현하는 방법

이 인터페이스를 구현하기위해서는 GetInterfaceSafetyOptions와 SetInterfaceSafetyOptions 두개의 함수가 필요합니다. 이것은 퍼즐ocx를 예를 들어 설명하겠습니다. 우선 [Controlname]Ctrl.h 파일에 ObjSafe.h를 Include하고 클래스에 다음과 같은 코드를 삽입합니다.
    class COcxPuzCtrl : public COleControl
    {
        DECLARE_DYNCREATE(COcxPuzCtrl)
    
        DECLARE_INTERFACE_MAP()
    
        BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
            STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) ( 
                /* [in] */ REFIID riid,
                /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
                /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions
            );
            
            STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) ( 
                /* [in] */ REFIID riid,
                /* [in] */ DWORD dwOptionSetMask,
                /* [in] */ DWORD dwEnabledOptions
            );
        END_INTERFACE_PART(ObjSafe);


그리고 cpp 파일에 다음과 같은 코드를 삽입해 주면 됩니다.

    /////////////////////////////////////////////////////////////
    // Interface map for IObjectSafety
    
    BEGIN_INTERFACE_MAP( COcxPuzCtrl, COleControl )
        INTERFACE_PART(COcxPuzCtrl, IID_IObjectSafety, ObjSafe)
    END_INTERFACE_MAP()
    
    /////////////////////////////////////////////////////////////
    // IObjectSafety member functions
    
    ULONG FAR EXPORT COcxPuzCtrl::XObjSafe::AddRef()
    {
        METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe)
        return pThis->ExternalAddRef();
    }
    
    ULONG FAR EXPORT COcxPuzCtrl::XObjSafe::Release()
    {
        METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe)
        return pThis->ExternalRelease();
    }
    
    HRESULT FAR EXPORT COcxPuzCtrl::XObjSafe::QueryInterface(
        REFIID iid, void FAR* FAR* ppvObj)
    {
        METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe)
        return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
    }
    
    const DWORD dwSupportedBits = 
            INTERFACESAFE_FOR_UNTRUSTED_CALLER |
            INTERFACESAFE_FOR_UNTRUSTED_DATA;
    const DWORD dwNotSupportedBits = ~ dwSupportedBits;
            
    HRESULT STDMETHODCALLTYPE 
        COcxPuzCtrl::XObjSafe::GetInterfaceSafetyOptions( 
            /* [in] */ REFIID riid,
            /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
            /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
    {
        METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe)
    
        HRESULT retval = ResultFromScode(S_OK);
    
        // does interface exist?
        IUnknown FAR* punkInterface;
        retval = pThis->ExternalQueryInterface(&riid, 
                        (void * *)&punkInterface);
        if (retval != E_NOINTERFACE) {  // interface exists
            punkInterface->Release(); // release it--just checking!
        }
        
        // we support both kinds of safety and have always both set,
        // regardless of interface
        *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;
    
        return retval; // E_NOINTERFACE if QI failed
    }
    
    HRESULT STDMETHODCALLTYPE 
        COcxPuzCtrl::XObjSafe::SetInterfaceSafetyOptions( 
            /* [in] */ REFIID riid,
            /* [in] */ DWORD dwOptionSetMask,
            /* [in] */ DWORD dwEnabledOptions)
    {
        METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe)
        
        // does interface exist?
        IUnknown FAR* punkInterface;
        pThis->ExternalQueryInterface(&riid,
            (void**)&punkInterface);
        if (punkInterface) {    // interface exists
            punkInterface->Release(); // release it--just checking!
        }
        else { // interface doesn't exist
            return ResultFromScode(E_NOINTERFACE);
        }
    
        // can't set bits we don't support
        if (dwOptionSetMask & dwNotSupportedBits) { 
            return ResultFromScode(E_FAIL);
        }
        
        // can't set bits we do support to zero
        dwEnabledOptions &= dwSupportedBits;
        // (we already know there are no extra bits in mask )
        if ((dwOptionSetMask & dwEnabledOptions) !=
             dwOptionSetMask) {
            return ResultFromScode(E_FAIL);
        }                               
        
        // don't need to change anything since we're always safe
        return ResultFromScode(S_OK);
    }


ID
Password
Join





- 전 이런 놈입니다.

격언> 성공하는 사람이 되려고 애쓰지 말고 가치있는 사람이 되려고 노력하라. (아인슈타인)

Recent Changes

D  Echoes Of War(The... @ 2012-05-18 [03:44 pm] by windlesszone
D  Diablo3 @ 2012-05-15 [04:49 pm] by windlesszone
D  Diablo3/story/wizard @ 2012-05-15 [04:48 pm] by windlesszone 4 changes
D  Diablo3/story/wit... @ 2012-05-15 [04:16 pm] by windlesszone
D  Diablo3/story/monk @ 2012-05-15 [04:14 pm] by windlesszone





Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2006-04-03 13:05:10
Processing time 0.0666 sec