2013-06-04 84 views
1

我无法设置我的控件安全。 我发现这个thread,它解释了它是如何完成的。 我做的解释:在C++中继承安全的javascript activex控件的IObjectSafetyImpl

class myctrl: public COleControl, public IObjectSafetyImpl<myctrl,INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA> 
{ 

然后,我增加了以下内容:

BEGIN_COM_MAP(myctrl) 
    COM_INTERFACE_ENTRY(IObjectSafety) 
END_COM_MAP() 

的 “BEGIN_COM_MAP” 使我烦恼,我不知道为什么。 它说“锁”&“解锁”不是myctrl的成员。 我无法找到任何有关它什么,我需要这两个成员 做我也得到了错误:

Error 3 error C2660: 'CCmdTarget::InternalQueryInterface' : function does not take 4 arguments 
+0

你混合MFC COM和ATL COM - 我不知道你会得到那样的很远。请看[MSDN here](http://msdn.microsoft.com/en-us/library/aa751977(v = vs.85).aspx)。 –

+0

@RogerRowland这个控件曾经注册过DllRegisterServer,它工作正常(在链接中解释的第一种方法)。现在我想将它从注册表中删除,并通过IObjectSafety控制。但我不知道如何。我究竟混合什么? – buddy123

+0

在VC++中有两种主要的COM方法 - 一种是使用活动模板库(ATL),另一种是通过'COleControl'使用MFC。你去了MFC路由,但你使用的链接只用于ATL COM对象 - 完全不同的代码。我在答案中添加了一些MFC代码。 –

回答

2

对于MFC COM,你需要一些样板代码添加到您的COleControl派生类。警告 - 一些大的复制/粘贴,所以请原谅错字!

首先,在控制的头文件,添加以下

DECLARE_INTERFACE_MAP() 
BEGIN_INTERFACE_PART(ObjectSafety, IObjectSafety) 
    STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions); 
    STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions); 
END_INTERFACE_PART(ObjectSafety) 

然后,在实现文件,添加此

BEGIN_INTERFACE_MAP(myctrl, COleControl) 
    INTERFACE_PART(myctrl, IID_IObjectSafety, ObjectSafety) 
END_INTERFACE_MAP() 

// Implementation of IObjectSafety 
STDMETHODIMP myctrl::XObjectSafety::GetInterfaceSafetyOptions(
    REFIID riid, 
    DWORD __RPC_FAR *pdwSupportedOptions, 
    DWORD __RPC_FAR *pdwEnabledOptions) 
{ 
    METHOD_PROLOGUE_EX(myctrl, ObjectSafety) 

     if (!pdwSupportedOptions || !pdwEnabledOptions) 
     { 
      return E_POINTER; 
     } 

     *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; 
     *pdwEnabledOptions = 0; 

     if (NULL == pThis->GetInterface(&riid)) 
     { 
      TRACE("Requested interface is not supported./n"); 
      return E_NOINTERFACE; 
     } 

     // What interface is being checked out anyhow? 
     OLECHAR szGUID[39]; 
     int i = StringFromGUID2(riid, szGUID, 39); 

     if (riid == IID_IDispatch) 
     { 
      // Client wants to know if object is safe for scripting 
      *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; 
      return S_OK; 
     } 
     else if (riid == IID_IPersistPropertyBag 
      || riid == IID_IPersistStreamInit 
      || riid == IID_IPersistStorage 
      || riid == IID_IPersistMemory) 
     { 
      // Those are the persistence interfaces COleControl derived controls support 
      // as indicated in AFXCTL.H 
      // Client wants to know if object is safe for initializing from persistent data 
      *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; 
      return S_OK; 
     } 
     else 
     { 
      // Find out what interface this is, and decide what options to enable 
      TRACE("We didn't account for the safety of this interface, and it's one we support.../n"); 
      return E_NOINTERFACE; 
     } 
} 
STDMETHODIMP myctrl::XObjectSafety::SetInterfaceSafetyOptions(
    REFIID riid, 
    DWORD dwOptionSetMask, 
    DWORD dwEnabledOptions) 
{ 
    METHOD_PROLOGUE_EX(myctrl, ObjectSafety) 

     OLECHAR szGUID[39]; 
    // What is this interface anyway? 
    // We can do a quick lookup in the registry under HKEY_CLASSES_ROOT/Interface 
    int i = StringFromGUID2(riid, szGUID, 39); 

    if (0 == dwOptionSetMask && 0 == dwEnabledOptions) 
    { 
     // the control certainly supports NO requests through the specified interface 
     // so it's safe to return S_OK even if the interface isn't supported. 
     return S_OK; 
    } 

    // Do we support the specified interface? 
    if (NULL == pThis->GetInterface(&riid)) 
    { 
     TRACE1("%s is not support./n", szGUID); 
     return E_FAIL; 
    } 


    if (riid == IID_IDispatch) 
    { 
     TRACE("Client asking if it's safe to call through IDispatch./n"); 
     TRACE("In other words, is the control safe for scripting?/n"); 
     if (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions) 
     { 
      return S_OK; 
     } 
     else 
     { 
      return E_FAIL; 
     } 
    } 
    else if (riid == IID_IPersistPropertyBag 
     || riid == IID_IPersistStreamInit 
     || riid == IID_IPersistStorage 
     || riid == IID_IPersistMemory) 
    { 
     TRACE("Client asking if it's safe to call through IPersist*./n"); 
     TRACE("In other words, is the control safe for initializing from persistent data?/n"); 

     if (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions) 
     { 
      return NOERROR; 
     } 
     else 
     { 
      return E_FAIL; 
     } 
    } 
    else 
    { 
     TRACE1("We didn't account for the safety of %s, and it's one we support.../n", szGUID); 
     return E_FAIL; 
    } 
} 
STDMETHODIMP_(ULONG) myctrl::XObjectSafety::AddRef() 
{ 
    METHOD_PROLOGUE_EX_(myctrl, ObjectSafety) 
     return (ULONG)pThis->ExternalAddRef(); 
} 
STDMETHODIMP_(ULONG) myctrl::XObjectSafety::Release() 
{ 
    METHOD_PROLOGUE_EX_(myctrl, ObjectSafety) 
     return (ULONG)pThis->ExternalRelease(); 
} 
STDMETHODIMP myctrl::XObjectSafety::QueryInterface(
    REFIID iid, LPVOID* ppvObj) 
{ 
    METHOD_PROLOGUE_EX_(myctrl, ObjectSafety) 
     return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); 
} 
+0

谢谢。它绝对是一个进步。然而,一旦我继承像:'class myctrl:public COleControl,public IObjectSafety',我从'DECLARE_DYNCREATE(myctrl)'和'IMPLEMENT_DYNCREATE(myctrl)'引发错误:'错误\t错误C2259:'myctrl':can not实例化抽象类'所以我改为'动态',它解决了错误,但它似乎我的控制目前无法正常工作 – buddy123

+1

我没有任何词语来描述你对我的帮助。我在ATL和MFC之间感到困惑。所有这些代码取自哪里?我想多了解一点。这个问题可能是固定的,但说实话,它不是我开始的工作,而且这个领域大部分对我来说都是未知的。 – buddy123

+0

它大部分看起来都是来自微软的“SafeCtl.exe在ActiveX控件中实现IObjectSafety”的例子 - http://support.microsoft.com/kb/164119 –