在网上找了很多文章了,但都没有解决,比如要实现IObjectSafety接口的:#include "objsafe.h"class MyCtrl : public COleControl, IObjectSafetyImpl<MyCtrl,INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA> 
{
...
但报错误:IObjectSafetyImpl' : base class undefined修改注册表的方法也试了,但是还是没有成功
希望哪位兄弟给一个完整的实现IObjectSafety接口的例子,高分酬谢

解决方案 »

  1.   

    标记控件为安全的 是实现IObjectSafety
    具体做法
    atl com app wizard 工程增标记安全控件在你dll控件的接口实现类的 .h 中继承类列表的末尾,并在上一行中添加一个逗号: 
    public IObjectSafetyImpl<"类名", INTERFACESAFE_FOR_UNTRUSTED_CALLER>
    将下行添加到 .h 中的 COM 映射: 
    COM_INTERFACE_ENTRY(IObjectSafety)
    即可如果IObjectSafetyImpl 未定义
    则包含  Atlctl.h
      

  2.   

    public COleControl, IObjectSafetyImpl??
    support.microsoft.com/kb/161873
      

  3.   

    to:zhucde(【風間苍月】) 
    数据签名应该是在开发完控件以后做的事情吧,我现在想做的是在开发的过程中就标记控件是安全的。
    to:akirya(坏[其实偶不是什么所谓的坏人])
    atl com app wizard 工程增标记安全控件? 
    但我开发的FMC ActiveX Contrl呀,不是alt的,所以你说的方法不行吧,而且我按你的方法做以后报d:\program files\microsoft visual studio\vc98\atl\include\atlwin.h(19) : fatal error C1189: #error :  atlwin.h requires atlbase.h to be included first
    然后我在myappCtl.h里加入:
    #include "atlbase.h"
    #include "objsafe.h"
    #include "Atlctl.h" 然后报更多的错了,比如:
    d:\program files\microsoft visual studio\vc98\atl\include\atlwin.h(65) : error C2065: '_Module' : undeclared identifier
    d:\program files\microsoft visual studio\vc98\atl\include\atlctl.h(516) : error C2146: syntax error : missing ';' before identifier 'm_spAmbientDispatch'
    等等,都是atlwin.h和atlctl.h的错
    所以说你说的方法应该是使用atl开发dll时用的,对于使用FMC开发ActiveX控件不行的
      

  4.   

    MFC的话,在DllRegisterServer的时候写注册表
    将自己标志为安全的
    vckbase上面有具体的做法
      

  5.   

    1、使用atl开发dll时标记为安全时可以实现IObjectSafety接口,但这个具体我还不知道怎么做。
    2、使用MFC开发ActiveX控件时可以修改注册表来标记控件为安全的,具体做法:
        YourApp.ccp里增加
        #include "comcat.h"
        #include "Objsafe.h"
    // 本控件的CLSID,注册表用-
    const GUID CDECL CLSID_SafeItem =
    { 0x94BE7FE8, 0xCF75, 0x4FD3, { 0x8A,0x41,0x9D,0x5F,0xE7,0x13,0x55,0x11} };  //这个需要根据你的控件的classid来修改,也就是YourApp.odl里的 [ uuid(94BE7FE8-CF75-4FD3-8A41-9D5FE7135511),
      helpstring("UTPKES Control"), control ]这个.const CATID CATID_SafeForScripting     =
          {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
    const CATID CATID_SafeForInitializing  =
          {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
    加这两句的时候可能会报重复定义,把旧的找到删除掉然后在YourApp.ccp中加入下面三方方法:
    // 创建组件种类
    HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
    {
        ICatRegister* pcr = NULL ;
        HRESULT hr = S_OK ;    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
                NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
        if (FAILED(hr))
            return hr;    // Make sure the HKCR\Component Categories\{..catid...}
        // key is registered.
        CATEGORYINFO catinfo;
        catinfo.catid = catid;
        catinfo.lcid = 0x0409 ; // english    // Make sure the provided description is not too long.
        // Only copy the first 127 characters if it is.
        int len = wcslen(catDescription);
        if (len>127)
            len = 127;
        wcsncpy(catinfo.szDescription, catDescription, len);
        // Make sure the description is null terminated.
        catinfo.szDescription[len] = '\0';    hr = pcr->RegisterCategories(1, &catinfo);
            pcr->Release();    return hr;
    }// 注册组件种类
    HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
    {
        // Register your component categories information.
        ICatRegister* pcr = NULL ;
        HRESULT hr = S_OK ;
        hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
                    NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
        if (SUCCEEDED(hr))
        {
           // Register this category as being "implemented" by the class.
           CATID rgcatid[1] ;
           rgcatid[0] = catid;
           hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
        }
        if (pcr != NULL)
            pcr->Release();
        return hr;
    }
    // 卸载组件种类
    HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
    {
        ICatRegister* pcr = NULL ;
        HRESULT hr = S_OK ;    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
                NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
        if (SUCCEEDED(hr))
        {
           // Unregister this category as being "implemented" by the class.
           CATID rgcatid[1] ;
           rgcatid[0] = catid;
           hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
        }    if (pcr != NULL)
            pcr->Release();    return hr;
    }
    然后修改YourApp.cpp里的STDAPI DllRegisterServer(void)方法和STDAPI DllUnregisterServer(void)方法:STDAPI DllRegisterServer(void)
    {
    HRESULT hr; AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
    return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
    return ResultFromScode(SELFREG_E_CLASS);    // 标记控件初始化安全.
        // 创建初始化安全组件种类
        hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!");
        if (FAILED(hr))
            return hr;
        // 注册初始化安全
        hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
        if (FAILED(hr))
            return hr;    // 标记控件脚本安全
        // 创建脚本安全组件种类 
        hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");
        if (FAILED(hr))
            return hr;
        // 注册脚本安全组件种类
        hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
        if (FAILED(hr))
            return hr; return NOERROR;
    }
    /////////////////////////////////////////////////////////////////////////////
    // DllUnregisterServer - Removes entries from the system registrySTDAPI DllUnregisterServer(void)
    {
    HRESULT hr; AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
    return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
    return ResultFromScode(SELFREG_E_CLASS);    // 删除控件初始化安全入口.
        hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
        if (FAILED(hr))
            return hr;
        // 删除控件脚本安全入口
        hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
        if (FAILED(hr))
            return hr;//////////////////////////
    return NOERROR;
    }
    这样就标记你的控件是安全的了3、这样开发完以后还需要用数字证书签名才可以让浏览器下载,如果不签名的话可以使用
    regsvr32 c:\YourApp.ocx来手动注册也可以使用了,当然也可以修改浏览器的设置运行不经过签名的控件也可以执行这样也可以使用。