2014년 10월 27일 월요일

VS6에서 ActiveX 만들고 페이지에 링크시켰지만, 메소드가 없다는 스크립트 에러가 나온다.

ActiveX의 ctrl.h파일에...아래 내용 추가

#include <objsafe.h>

    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파일에 아래 내용 추가.

ULONG FAR EXPORT CEMODIOCtrl::XObjSafe::AddRef()
{
    METHOD_PROLOGUE(CEMODIOCtrl, ObjSafe)
        return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CEMODIOCtrl::XObjSafe::Release()
{
    METHOD_PROLOGUE(CEMODIOCtrl, ObjSafe)
        return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CEMODIOCtrl::XObjSafe::QueryInterface(
                                                            REFIID iid, void FAR* FAR* ppvObj)
{
    METHOD_PROLOGUE(CEMODIOCtrl, ObjSafe)
        return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

const DWORD dwSupportedBits =
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~ dwSupportedBits;

HRESULT STDMETHODCALLTYPE
CEMODIOCtrl::XObjSafe::GetInterfaceSafetyOptions(
                                                    /* [in] */ REFIID riid,
                                                    /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
                                                    /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
    METHOD_PROLOGUE(CEMODIOCtrl, 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
CEMODIOCtrl::XObjSafe::SetInterfaceSafetyOptions(
                                                    /* [in] */ REFIID riid,
                                                    /* [in] */ DWORD dwOptionSetMask,
                                                    /* [in] */ DWORD dwEnabledOptions)
{
    METHOD_PROLOGUE(CEMODIOCtrl, 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);
}

위 코드를 추가하지 않았을 경우, IE 버전별로 반응하는 것이 틀린데...IE6의 경우 ActiveX의 실행을 묻게되고, IE8의 경우 실행할 수 있는 메소드가 없다고 나와버린다. 즉 스크립트 에러가 나온다. 위 코드를 꼭 추가해주자. 수동으로 해줘야 한다.

댓글 없음: