转载自:https://blog.csdn.net/jiangtongcn/article/details/13629017

默认情况下,编译的MFC Activex控件,只能在本地代码中运行,即便是网页,也只能在本地运行,一旦要想放在Web服务器通过IE访问,需要设置其初始化和脚本运行的安全性,为此您需要作出如下修改:

在“工程名.cpp”文件中,增加以下方法:// 创建组件种类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_s(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;    }然后修改DllRegisterServer和DllUnregisterServer这个两个方法做如下修改:// DllRegisterServer - 将项添加到系统注册表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(BASED_CODE _tlid , CATID_SafeForInitializing);    if (FAILED(hr)) return hr;    // 标记控件脚本安全// 创建脚本安全组件种类hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");    if (FAILED(hr)) return hr;    // 注册脚本安全组件种类hr = RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);    if (FAILED(hr)) return hr;return NOERROR;}// DllUnregisterServer - 将项从系统注册表中移除STDAPI 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(BASED_CODE _tlid , CATID_SafeForInitializing);    if (FAILED(hr)) return hr;    // 删除控件脚本安全入口hr=UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);    if (FAILED(hr)) return hr;return NOERROR;}其中CATID_SafeForInitializing和CATID_SafeForScripting两个是guid,可以通过VC自带的guid生成工具自动生成。下一步,实现IobjectSafety接口,步骤:打开 “工程名Ctrl.h”加入#include<objsafe.h>,搜索DECLARE_DYNCREATE(C工程名Ctrl)在其下面添加:DECLARE_INTERFACE_MAP()BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (REFIID riid,DWORD __RPC_FAR *pdwSupportedOptions,DWORD __RPC_FAR *pdwEnabledOptions);STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (REFIID riid,DWORD dwOptionSetMask,DWORD dwEnabledOptions);END_INTERFACE_PART(ObjSafe);打开“工程名Ctl.cpp”在BOOL C工程名Ctrl::C工程名CtrlFactory::UpdateRegistry(BOOL bRegister)方法上面添加以下代码:/// Interface map for IObjectSafetyBEGIN_INTERFACE_MAP(C工程名Ctrl, COleControl)INTERFACE_PART(C工程名Ctrl, IID_IObjectSafety, ObjSafe)END_INTERFACE_MAP()/// IObjectSafety member functions// Delegate AddRef, Release, QueryInterfaceULONG FAR EXPORT C工程名Ctrl::XObjSafe::AddRef(){METHOD_PROLOGUE(C工程名Ctrl, ObjSafe)return pThis->ExternalAddRef();}ULONG FAR EXPORT C工程名Ctrl::XObjSafe::Release(){METHOD_PROLOGUE(C工程名Ctrl, ObjSafe)return pThis->ExternalRelease();}HRESULT FAR EXPORT C工程名Ctrl::XObjSafe::QueryInterface(REFIID iid, void FAR* FAR* ppvObj){METHOD_PROLOGUE(C工程名Ctrl, ObjSafe)return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);}const DWORD dwSupportedBits =INTERFACESAFE_FOR_UNTRUSTED_CALLER |INTERFACESAFE_FOR_UNTRUSTED_DATA;const DWORD dwNotSupportedBits = ~ dwSupportedBits;/// CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions// Allows container to query what interfaces are safe for what. We're// optimizing significantly by ignoring which interface the caller is// asking for.HRESULT STDMETHODCALLTYPEC工程名Ctrl::XObjSafe::GetInterfaceSafetyOptions(REFIID riid,DWORD __RPC_FAR *pdwSupportedOptions,DWORD __RPC_FAR *pdwEnabledOptions){METHOD_PROLOGUE(C工程名Ctrl, ObjSafe)HRESULT retval = ResultFromScode(S_OK);// does interface exist?IUnknown FAR* punkInterface;retval = pThis->ExternalQueryInterface(&riid,(void * *)&punkInterface);if (retval != E_NOINTERFACE) { // interface existspunkInterface->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}/// CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions// Since we're always safe, this is a no-brainer--but we do check to make// sure the interface requested exists and that the options we're asked to// set exist and are set on (we don't support unsafe mode).HRESULT STDMETHODCALLTYPEC工程名Ctrl::XObjSafe::SetInterfaceSafetyOptions(REFIID riid,DWORD dwOptionSetMask,DWORD dwEnabledOptions){METHOD_PROLOGUE(C工程名Ctrl, ObjSafe)// does interface exist?IUnknown FAR* punkInterface;pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);if (punkInterface) { // interface existspunkInterface->Release(); // release it--just checking!}else { // interface doesn't existreturn ResultFromScode(E_NOINTERFACE);}// can't set bits we don't supportif (dwOptionSetMask & dwNotSupportedBits) {return ResultFromScode(E_FAIL);}// can't set bits we do support to zerodwEnabledOptions &= 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 safereturn ResultFromScode(S_OK);}

至此,该ActiveX组件就注册为安全组件了。

MFC ActiveX ISafeObject的实现相关推荐

  1. VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程

    VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程 开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是 ...

  2. MFC(ActiveX编程,孙鑫C++第十八讲笔记整理)

    2019独角兽企业重金招聘Python工程师标准>>> 一:在VB中调用X控件,添加方法 project->Add components.另外可以用Object Browser ...

  3. C++ 使用VS2010创建MFC ActiveX工程项目

    1.ActiveX的基本概念 ActiveX控件可以看作是一个极小的服务器应用程序,它不能独立运行,必须嵌入到某个容器程序中,与该容器一起运行.这个容器包括WEB网页,应用程序窗体等... Activ ...

  4. VS2008 在IE8中 调试 ActiveX控件 无法进入断点的解决方法 设置VS2008和IE8 调试ATL MFC ActiveX控件

    VS2008 在IE8中 调试 ActiveX控件 无法进入断点的解决方法 设置VS2008和IE8 调试ATL MFC ActiveX控件 参考文章: (1)VS2008 在IE8中 调试 Acti ...

  5. vs2017开发ActiveX(主讲OCX)(十一)、类向导中MFC ActiveX添加方法、添加函数、添加变量、添加事件、添加属性、添加方法的区别

    本文我们就来说说类向导中MFC ActiveX添加方法.添加函数.添加变量.添加事件.添加属性.添加方法的区别.这个问题曾经困扰过我. 此处是向CCreateOcxDemoApp类中添加成员变量,及成 ...

  6. VS2017创建MFC ActiveX工程制作IE OCX插件

    最近看了一个采用MFC ActiveX封装DLL的OCX项目的源码,现将学习到的内容记录下来.本次的学习记录计划写如下几个主题: 1.VS2017创建MFC ActiveX工程制作IE OCX插件 2 ...

  7. mfc随记:基于vs2010创建MFC ActiveX控件并测试

    一.新建一个空项目 以管理员打开vs2010,选择新建一个mfc activeX控件,填写项目名称和路径,其他无需修改,直接默认一直下一步即可 二. 添加测试方法 在底部tab栏切换到类视图,右键添加 ...

  8. MFC ActiveX 打包 CAB

    MFC ActiveX打包CAB 准备打包签名工具和要打包的文件 将需要签名和打包的 OCX .dll和命令放到相同文件夹. 制作签名证书 在命令行运行下面命令: makecert.exe -ss r ...

  9. MFC ActiveX 接口数据类型,伤不起!

    MFC ActiveX 接口数据类型,伤不起! 要不是因为我一直在维护一个曲线绘制控件(www.st-curve.cn),我真的很不想再碰MFC的ActiveX了,其中怎一个乱字了得! 回想起来,似乎 ...

最新文章

  1. iOS酷我音乐导出工具使用说明和原理介绍(提供下载链接及project源代码)
  2. linux 修改分辨率lcd_16.Linux-LCD驱动(详解)
  3. matlab中怎样将字母倒叙,如何用matlab将文档里的数按行倒序输出
  4. 前端学习(2832):小程序事件绑定2
  5. vm客户机隔离不能选_开汽车美容店,这些位置绝对不能选,会让你门可罗雀,生意惨淡...
  6. 教你如何去淘便宜机票
  7. Python笔记-UiSelector文本定位方式(3种定位并点击)
  8. 【问题解决方案】Linux中进入目录下文件夹
  9. duilib 中list控件的扩展
  10. IE主页简单篡改修复
  11. 《剑来》语句摘录(七)
  12. java百度地图离线开发_【“零起点”--百度地图手机SDK】如何使用离线地图?
  13. Oracle rac集群笔记
  14. 【Python • 图片识别】pytesseract快速识别提取图片中的文字
  15. 打印机后台服务器修复,打印机后台服务程序被禁用怎么修复?
  16. C#的新特性(C#核心技术浅解)
  17. 【自用向】【新手向】PHP入门学习(不断更新)
  18. ATM跨行查询也开始收费了
  19. 求四点的交点(两线段的交点)
  20. matplotlib罗列条形图(bottom)

热门文章

  1. Ubuntu 10.10 ThinkPad x200 指点杆移动鼠标速度调整
  2. 如何从 iPhone、iPad 和 Mac 共享 Wi-Fi 密码
  3. python协程的作用_python 协程
  4. Python爬虫笔记——随机函数(random,uniform,randint,randrange,shuffle,sample)
  5. npm run start和npm run serve
  6. 华为p30android,HUAWEI P30 规格参数
  7. 湖南中职一级计算机考试科目,湖南中职教师资格证考试科目及题型有哪些
  8. Hadoop官方文档翻译—— YARN ResourceManager High Availability 2.7.3
  9. 32位进位选择加法器_32位系统即将退出历史舞台,64位成唯一选择,对我们有何影响?...
  10. Tail Loss Probe实现