atlActiveXdllinfcabweb调用总结篇.docx
- 文档编号:7308163
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:18
- 大小:87.71KB
atlActiveXdllinfcabweb调用总结篇.docx
《atlActiveXdllinfcabweb调用总结篇.docx》由会员分享,可在线阅读,更多相关《atlActiveXdllinfcabweb调用总结篇.docx(18页珍藏版)》请在冰豆网上搜索。
atlActiveXdllinfcabweb调用总结篇
atl-ActiveX-dll-inf-cab-web调用(总结篇)
分类:
c++2011-07-1815:
451086人阅读评论(7)收藏举报
【dll-ActiveX调用dll-生成dll-2个dll外加1个inf生成cab-嵌入web网页】
【写在前面的话】
参与的项目让我第一次略深层次地接触C++。
我的项目里需要用ActiveX调用密码小键盘的动态活动库dll,然后嵌入到网页。
在网上搜了很多很多,几乎没有这方面的知识,那么一两个相关的介绍也不是很详细。
所以我按照最实用的一篇文章,结合自己的思路整理下来。
供后来者略作参考。
一、综述
VC++、dll及ActiveX控件
dll(动态链接库):
分WIN32dll和MFCdll
ActiveX:
分ATL控件和MFC控件两类(也是一个dll)
WEB:
JavaScript调用->ActiveX调用->dll完成加法运算并返回值,在页面上显示。
二、开发(MicrosoftVisualStudio2010)
1、dll库编写:
--------------【此部分密码键盘自带动态库dll】【以下为举例,简单小dll】
文件->新建->WIN32控制台->填写项目名称->选择dll->空项目->完成。
(1)在解决方案面板中,加入一个头文件testdll.h,【解决方案资源管理器,右击“头文件”->添加->新建项->头文件】
[cpp]viewplaincopyprint?
1.#ifndef_DLLTUT_DLL_H_
2.
3.#define_DLLTUT_DLL_H_
4.
5.#ifdefinedDLL_EXPORT
6.
7.#defineDECLDIR__declspec(dllexport)
8.
9.#else
10.
11.#defineDECLDIR__declspec(dllimport)
12.
13.#endif
14.
15.extern"C"//告诉编译器该部分可以在C/C++中使用。
16.
17.{
18.
19.DECLDIRintAdd(inta,intb);
20.
21.DECLDIRvoidFunction(void);
22.
23.}
24.
25.#endif
(2)在解决方案面板中,加入一个实现文件testdll.cpp【解决方案资源管理器,右击“源文件”->添加->新建项->c++文件】
[cpp]viewplaincopyprint?
1.#include
2.
3.#defineDLL_EXPORT
4.
5.#include"testdll.h"
6.
7.extern"C"
8.
9.{
10.
11.DECLDIRintAdd(inta,intb)
12.
13.{
14.
15.return(a+b);
16.
17.}
18.
19.DECLDIRvoidFunction(void)
20.
21.{
22.
23.std:
:
cout<<"DLLCalled!
"< : endl; 24. 25.} 26. 27.} 以上为一个项目,保存 2、小测试程序【可选,小哆当时什么都不懂,所以觉得先写个小测试调用一下,以便熟悉熟悉。 挺好。 】 新建一个WIN32控制台类,测试这个DLL【文件->新建->WIN32控制台->填写项目名称->选择控制台程序->空项目->完成】 在解决方案面板中,加入一个实现文件loaddll.cpp内容: [cpp]viewplaincopyprint? 1.#include 2. 3.#include 4. 5.usingnamespacestd; 6. 7.typedefint(*AddFunc)(int,int);//定义指针函数、接口。 8. 9.typedefvoid(*FunctionFunc)(); 10. 11.intmain() 12. 13.{ 14. 15.AddFunc_AddFunc; 16. 17.FunctionFunc_FunctionFunc; 18. 19.cout<<"---获取DLL---."< 20. 21.//L表示使用UNICODE字符集,要和项目的字符集保持一致。 22. 23.HINSTANCEhInstLibrary=LoadLibrary(L"D: \\MyDocuments\\VisualStudio2010\\Projects\\test_test\\Debug\\dll_test.dll"); 24. 25.//这里调用时的路径,跟网上找到的不一样,虽然我觉得相对路径好些。 但是奈何有点糊涂。 26. 27.//相对路径首先一点我明白,文件不能乱放么,最好同一路径下。 各位客官有明白的,还望指点一二【小哆拜谢】 28. 29.if(hInstLibrary==NULL) 30. 31.{ 32. 33.cout<<"Dll加载【失败】."< 34. 35.FreeLibrary(hInstLibrary); 36. 37.}else{ 38. 39.cout<<"Dll加载【成功】."< 40. 41.} 42. 43._AddFunc=(AddFunc)GetProcAddress(hInstLibrary,"Add"); 44. 45._FunctionFunc=(FunctionFunc)GetProcAddress(hInstLibrary,"Function"); 46. 47.if((_AddFunc==NULL)||(_FunctionFunc==NULL)) 48. 49.{ 50. 51.FreeLibrary(hInstLibrary);//释放 52. 53.}else{ 54. 55.cout<<"---获取DLL函数【OK】---."< 56. 57.} 58. 59.cout<<_AddFunc(1,1)< 60. 61._FunctionFunc();// 62. 63.cin.get();//获得焦点,这样就不会程序就不会一闪而过了。 64. 65.FreeLibrary(hInstLibrary);//调用完后,要释放内存。 66. 67.return (1); 68. 69.} 完成,运行一下生成。 会在文件夹的debug路径下产生一个exe文件,运行。 哦耶~~ 2、ActiveX控件(ATL)实现: 这里选择ATL控件实现。 文件->新建->ATL项目->填写项目名称(“Test_ActiveX”)->选择动态链接库(DLL)->完成。 完成后,会在右边“解决方案资源管理器”生成很多头H文件和CPP实现文件,这些都是默认的不要修改。 (1)添加一个ALT简单对象: 【鼠标右键点击项目名称(刚才起的名字)选择->添加类->选择ATL简单对象】 下一步起一个名字: “test_op”->下一步: 其他不变,在支持中,选择“连接点”和“IE对象支持”->完成。 下一步给“test_op”添加一个方法,以便WEB页面调用。 在“类视图”选择“itest_op”(有个灰色的钥匙图标)鼠标右键添加->添加方法。 方法起名为“GetContent”->参数属性选择IN,参数类型选择LONG参数名a->添加;继续;参数属性选择IN,参数类型选择LONG参数名B->添加;继续;参数属性选择OUT和RETVAL,参数类型选择LONG*参数名out->添加->点击完成。 属性in指输入参数,属性out指输出参数。 这样就在test_op.H头文件中添加了一个(在最后一行): STDMETHOD(GetContent)(LONGa,LONGb,LONG*out); 并在test_op.CPP文件中添加了一个实现类: STDMETHODIMPCCaluNumCtrl: : GetContent(LONGa,LONGb,LONG*out) { //TODO: 在此添加实现代码 returnS_OK; } (2)在test_op.H文件中,调用DLL类库。 代码如下: [cpp]viewplaincopyprint? 1.//test_op.h: Ctest_op的声明 2. 3.#pragmaonce 4. 5.#include"resource.h"//主符号 6. 7.#include 8. 9.#include"testweb_i.h" 10. 11.#include"_Itest_opEvents_CP.h" 12. 13.#ifdefined(_WIN32_WCE)&&! defined(_CE_DCOM)&&! defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) 14. 15.#error"WindowsCE平台(如不提供完全DCOM支持的WindowsMobile平台)上无法正确支持单线程COM对象。 定义_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA可强制ATL支持创建单线程COM对象实现并允许使用其单线程COM对象实现。 rgs文件中的线程模型已被设置为“Free”,原因是该模型是非DCOMWindowsCE平台支持的唯一线程模型。 " 16. 17.#endif 18. 19.usingnamespaceATL; 20. 21.//Ctest_op 22. 23.classATL_NO_VTABLECtest_op: 24. 25.//增加下一行by莫小哆_ly: 安全提示解除,--当运行浏览器调用时,不会提示安全问题。 26. 27.publicIObjectSafetyImpl 28. 29.publicCComObjectRootEx 30. 31.publicCComCoClass 32. 33.publicIConnectionPointContainerImpl 34. 35.publicCProxy_Itest_opEvents 36. 37.publicIObjectWithSiteImpl 38. 39.publicIDispatchImpl 40. 41.{ 42. 43.public: 44. 45.//以下三行实现定义modifiedby莫小哆_ly。 46. 47.typedefint(*AddFunc)(int,int);//类型定义,对应DLLADD方法。 Func自定义,随便写。 48. 49.HINSTANCEhInstLibrary; 50. 51.AddFunc_AddFunc;//类映射 52. 53.Ctest_op() 54. 55.{ 56. 57.//开始调用DLL,进行计算。 58. 59.hInstLibrary=LoadLibrary(L"dll_test.dll");//把写好的dll_test.dll文件放在此项目生成的目录debug下。 60. 61.//小哆觉得这应该就是相对路径的成功应用了。 以后打包时,因为一直在同一路径下,所以,只要同时移动就不会出问题。 62. 63.if(hInstLibrary==NULL) 64. 65.{ 66. 67.FreeLibrary(hInstLibrary);//资源释放 68. 69.}else{ 70. 71.} 72. 73.//调用方法,返回方法句柄。 74. 75._AddFunc=(AddFunc)GetProcAddress(hInstLibrary,"Add"); 76. 77.} 78. 79.DECLARE_REGISTRY_RESOURCEID(IDR_TEST_OP) 80. 81.BEGIN_COM_MAP(Ctest_op) 82. 83.COM_INTERFACE_ENTRY(Itest_op) 84. 85.COM_INTERFACE_ENTRY(IDispatch) 86. 87.COM_INTERFACE_ENTRY(IConnectionPointContainer) 88. 89.COM_INTERFACE_ENTRY(IObjectWithSite) 90. 91. 92. 93.//增加下一行by莫小哆_ly: 安全提示解除,--当运行浏览器调用时,不会提示安全问题。 94. 95.COM_INTERFACE_ENTRY(IObjectSafety) 96. 97.END_COM_MAP() 98. 99.BEGIN_CONNECTION_POINT_MAP(Ctest_op) 100. 101.CONNECTION_POINT_ENTRY(__uuidof(_Itest_opEvents)) 102. 103.END_CONNECTION_POINT_MAP() 104. 105.//ISupportsErrorInfo 106. 107.STDMETHOD(InterfaceSupportsErrorInfo)(REFIIDriid); 108. 109.DECLARE_PROTECT_FINAL_CONSTRUCT() 110. 111.HRESULTFinalConstruct() 112. 113.{ 114. 115.returnS_OK; 116. 117.} 118. 119.voidFinalRelease() 120. 121.{ 122. 123.} 124. 125.public: 126. 127.STDMETHOD(Add)(LONGa,LONGb,LONG*sum); 128. 129.}; 130. 131.OBJECT_ENTRY_AUTO(__uuidof(test_op),Ctest_op) (3)回到在test_op.PP文件中,添加实现代码如下: [cpp]viewplaincopyprint? 1.STDMETHODIMPCCaluNumCtrl: : GetContent(LONGa,LONGb,LONG*out) 2. 3.{ 4. 5.//TODO: 在此添加实现代码 6. 7.intsum=this->_AddFunc(static_cast 8. 9.*out=static_cast 10. 11.this->_AtlFinalRelease(); 12. 13.returnS_OK; 14. 15.} (4)生成DLL: 选“生成”,在项目的Debug文件夹里找到dll文件 3、dll和ATLActiveX控件dll打包为CAB文件: (1)首先定义setup.inf文件: 它描述了下载的内容和目标目录还有版本号及相应的DLL文件。 这个要手动编写的(对应名称自行修改): [plain]viewplaincopyprint? 1.[version] 2. 3.signature="$CHICAGO{1}quot; 4. 5.AdvancedINF=2.0 6. 7.[Add.Code] 8. 9.testweb.dll=testweb.dll 10. 11.dll_test.dll=dll_test.dll 12. 13.[install.files] 14. 15.testweb.dll=testweb.dll 16. 17.dll_test.dll=dll_test.dll 18. 19.[testweb.dll] 20. 21.file-win32-x86=thiscab 22. 23.RegisterServer=yes 24. 25.clsid={125FFB0B-F4B9-4BFC-944D-7DF811E00852} 26. 27.DestDir=11 28. 29.FileVersion=1,0,0,1 30. 31.[dll_test.dll] 32. 33.file-win32-x86=thiscab 34. 35.DestDir=11 36. 37.FileVersion=1,0,0,1 38. 39.[RegisterFiles] 40. 41.%11%/testweb.dll 【怎么写inf】 [Version]区: 不用修改 [version] signature="$CHICAGO$" AdvancedINF=2.0 接下来就[Add.Code]区: [Add.Code] testweb.dll=testweb.dll dll_test.dll=dll_test.dll 前面是要下载的文件名,后面是对应这个文件的区域名,可以是任何名字,建议前后名字相同,方便维护。 还有需要注意是在[Add.Code]区出现的文件要根据依赖性进行排序,例如testweb.dll要依赖于dll_test.dll,则dll_test.dll在dll_test.dll的下面。 因为安装时是按照相反的顺序进行的,先安装dll_test.dll,然后才是testweb.dll。 再接下来是各个文件的区域了 [testweb.dll] file-win32-x86=thiscab RegisterServer=yes clsid={125FFB0B-F4B9-4BFC-944D-7DF811E00852} DestDir=11 FileVersion=1,0,0,1 [testweb.dll]区域中的第一个file值告诉IE到哪里得到这个dll。 file包括三部分,file永远都是这样的(至少目前来说);第二部分声明支持的OS,win32表示windows,mac就是苹果MACOX了;第三部分CPU类型,比如说x86、ppc(PowerPC)、mips或者alpha了。 file的值可以取三种值: URL、ignore和thiscab,URL说明到URL所在的位置去下;ignore说明对于这种OS和CPU,不需要下载这个文件(ctrl1.dll);thiscab很明显就在当前的cab文件中了。 接下来是RegisterServer,可以取两个值yes和no,yes说明IE要注册该dll,no就不必了; 如何寻找clsid值: 项目里的idl文件中,有一段这么记录: [cpp]viewplaincopyprint? 1.librarytestwebLib 2. 3.{ 4. 5.importlib("stdole2.tlb"); 6. 7.[ 8. 9.uuid(125FFB0B-F4B9-4BFC-944D-7DF811E00852) 10. 11.] 那就选这个uuid吧,别问我为什么,我也不知道。 反正很多个,试了好久,用这个最后可以运行出来。 再下来是DestDir,它的值是dll将要存到本地硬盘的位置。 10,则将dll放到\Windows或者\WinNT下;11,则放到\Windows\System或者\WinNT\System32下;空(就是没有值)则会放到\Windows或者\WinNT下的DownloadedProgramFiles目录下; 最后是FileVersion,这个就比较明显了,说明了testweb.dll的版本号。 (2)整合资源: 将所用到的DLL全部放到一个目录下包括setup.inf文件,然后在开始运行: IExpress命令去生成CAB包。 运行后,选择“CreatenewSelf...”,下一步,选择第三个“Createcompressed...(ActiveXInstalls)”,下一步,添加文件(选择用到的2个dll和INF文件),下一步,选择一个输出目录并创建一个CAB文件名,再选择第二个选项“storefilesusing...”,下一步,选择第二个选项“Don'tsave”,然后一直下一步。 这样就生成了一个CAB文件。 (3)WEB页面调用ActiveX控件进行加法运算: 写一个test.htm网页和CAB文件放在一个目录,test.htm内容如下: [html]viewplaincopyprint? 1. 2. 3. 4. 5. 6. 7.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- atlActiveXdllinfcabweb 调用 总结