VC6.0 MFC创建OCX入门-详细完整流程(JS调用测试, 去除安全提示, exe打包)
2017-11-26 18:01
786 查看
一.前言
本文将采用VC6.0 MFC创建OCX, OCX提供两个简单接口供JS在网页中调用,分别是:Long AddNumber(Long, Long):返回数字相加之和, 整形传入传出.
BSTR AddString(LPCTSTR, LPCTSTR):返回字符串拼接结果, 字符串传入传出.
二.VC6.0制作OCX
创建工程:输入工程名ocxTest, 点OK, 接下来选择默认选项直到完成.添加方法:
添加Long AddNumber(Long, Long)方法:
添加BSTR AddString(LPCTSTR, LPCTSTR)方法:
添加方法后, VC3个文件共4处新增了代码, 不关注文档结构的同学此处可略过.
ocxTest.odl文件:
OcxTestCtl.h文件:
OcxTestCtl.cpp文件上方:(该文件还有一处改动在下方, 就是我们一会要为方法添加代码的地方, 详见下一步此处略.)
为方法添加代码:
生成OCX并注册:
点击Build->Rebuild All生成ocxTest.ocx.
注册:将ocx根据操作系统位数放到对应目录,
32位放到C:\Windows\System32,64位放到C:\Windows\SysWOW64;
我的是64然后以管理员身份打开CMD窗口运行命令:regsvr32 C:\Windows\SysWOW64\ocxTest.ocx
三.JS调用
调用说明:以下代码需保存在以.html为后缀的文件,并修改OBJECT标签下的CLASSID;
CLASSID是每个OCX独有的, 它的值存在ocxTest.odl文件最下方的uuid(5E5397D6-B705-49C2-A6AF-7EA9F036F206)括号内;
ID=”myocx”, 这个ID值可以是任意名字, 用来标识OCX对象, 在JS函数调用时使用.
<HTML> <HEAD> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"/> <TITLE>Add Func Test</TITLE> <script language="javascript" type="text/javascript"> function Button1_onclick() { var num1 = form1.Num1.value; var num2 = form1.Num2.value; try{ var result = myocx.AddNumber(num1, num2); alert(result); } catch(e){ alert(e.name + ": " + e.message); } } function Button2_onclick() { var str1 = form1.Str1.value; var str2 = form1.Str2.value; try{ var result = myocx.AddString(str1, str2); alert(result); } catch(e){ alert(e.name + ": " + e.message); } } </script> </HEAD> <BODY> <OBJECT ID="myocx" CLASSID="CLSID:5E5397D6-B705-49C2-A6AF-7EA9F036F206"></OBJECT> <form id="form1"> Num1: <input name="Num1" id="Num1" type="text" size=20><br/> Num2: <input name="Num2" id="Num2" type="text" size=20><br/> <input id="Button1" type="button" value="AddNumber" onclick="return Button1_onclick()" /><br/><br/> Str1: <input name="Str1" id="Str1" type="text" size=20><br/> Str2: <input name="Str2" id="Str2" type="text" size=20><br/> <input id="Button2" type="button" value="AddString" onclick="return Button2_onclick()" /> </form> </BODY> </HTML>
调用结果:
注:请用IE打开, 如果网页无法打开, 在工具->internet选项中将127.0.0.1加入受信任的站点, 并在自定义级别中将activeX启用.
四.去除网页安全提示
说明:网页打开后的会有如下安全提示, 不介意的同学可忽略此步.
在XXXCtrl.h中:(XXX为工程名)
1.添加头文件: #include <objsafe.h>
2.在class COcxTestCtrl{}中添加以下代码:
//safety begin DECLARE_INTERFACE_MAP() BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)//去IE安全检测 STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (//去IE安全检测 REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions); STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (//去IE安全检测 REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions); END_INTERFACE_PART(ObjSafe);//去IE安全检测 //safety end
在OcxTestCtl.cpp中添加以下代码:
//safety begin BEGIN_INTERFACE_MAP(COcxTestCtrl, COleControl) INTERFACE_PART(COcxTestCtrl, IID_IObjectSafety, ObjSafe) END_INTERFACE_MAP() ///////////////////////////////////////////////////////////////////////////// // IObjectSafety member functions // Delegate AddRef, Release, QueryInterface ULONG FAR EXPORT COcxTestCtrl::XObjSafe::AddRef() { METHOD_PROLOGUE(COcxTestCtrl, ObjSafe) return pThis->ExternalAddRef(); } ULONG FAR EXPORT COcxTestCtrl::XObjSafe::Release() { METHOD_PROLOGUE(COcxTestCtrl, ObjSafe) return pThis->ExternalRelease(); } HRESULT FAR EXPORT COcxTestCtrl::XObjSafe::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(COcxTestCtrl, ObjSafe) return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; const DWORD dwNotSupportedBits = ~dwSupportedBits; ///////////////////////////////////////////////////////////////////////////// // CXXXCtrl::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 STDMETHODCALLTYPE COcxTestCtrl::XObjSafe::GetInterfaceSafetyOptions( REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions) { METHOD_PROLOGUE(COcxTestCtrl, 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 } ///////////////////////////////////////////////////////////////////////////// // CXXXCtrl::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 STDMETHODCALLTYPE COcxTestCtrl::XObjSafe::SetInterfaceSafetyOptions( REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) { METHOD_PROLOGUE(COcxTestCtrl, 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); } //safety end
最后, 重新编译注册即可.
五.打包成exe安装包
说明:安装包的作用是, 在执行以后将自动根据操作系统位数,将ocx文件拷贝到系统对应目录(system32 or SysWOW64), 并执行注册.
步骤:
1.准备材料:
(1).ocx文件
(2).register.bat文件
新建文件, 将文件名改为register.bat并写入以下内容:
只需将set fileName=后面改为实际的ocx文件名.
@echo off set fileName=XXX.ocx if exist %windir%\SysWOW64 (goto x64) else (goto x86) :x64 set sys=SysWOW64 set dir=%WINDIR%\%sys%\ set cmd=%dir%%fileName% xcopy /y "%~dp0%fileName%" "%dir%" regsvr32 %cmd% exit :x86 set sys=System32 set dir=%WINDIR%\%sys%\ set cmd=%dir%%fileName% xcopy /y "%~dp0%fileName%" "%dir%" regsvr32 %cmd% exit
用好压选中上述两个文件打包为setup.zip:
双击setup.zip, 选择自解压->解压标签:
在解压后运行一栏写入:.\register.bat
点确定即可生成setup.exe文件
最后, 以管理员身份运行setup.exe,选择路径解压后即可自动注册!
相关文章推荐
- 补充 ActiveX打包后在JS中调用时不提示安全问题
- VC6.0利用CreateProcess创建子进程,MFC调用Win32生成的.exe文件为例
- VC6.0 MFC方式的OCX 去除安全警告框
- OCX 打包 CAB 与 JS 调用详细教程
- OCX 打包 CAB 与 JS 调用详细教程
- vc6.0生成ocx,然后使用js调用
- 使用jsonp跨域调用百度js实现搜索框智能提示,并实现鼠标和键盘对弹出框里候选词的操作【附源码和在线测试地址】
- vc6.0生成ocx,然后使用js调用
- iOS集成环信推送,最详细流程(证书创建、环信集成、测试)
- 史上最详细MFC调用mapX5.02.26步骤(附地图测试GST文件)
- iOS集成环信推送,最详细流程(证书创建、环信集成、测试)
- vs2010开发activex(MFC)控件/ie插件(三),js调用ocx控件的接口函数
- php打包zip文件,完整实例(附类,附调用方法),已经测试OK的
- iOS集成环信推送,最详细流程(证书创建、环信集成、测试)
- maven入门浅析(一)-----maven安装、配置、创建项目骨架、编译、测试、打包、运行
- Maven3命令行创建微web程序,并导入Myeclipse2014(有史以来最详细的从Maven的安装到打包发布Maven的完整过程)
- 一个关于把JS打包进DLL里,然后调用的完整例子
- 【electron】electron入门 教你如何创建第一个electron应用 并进行打包【超详细】
- js创建调用ocx对象的几种方法,检测ocx是否可用
- OCX 打包 CAB 与 JS 调用具体教程