atlActiveXdllinfcabweb调用总结篇.docx

上传人:b****6 文档编号:7308163 上传时间:2023-01-22 格式:DOCX 页数:18 大小:87.71KB
下载 相关 举报
atlActiveXdllinfcabweb调用总结篇.docx_第1页
第1页 / 共18页
atlActiveXdllinfcabweb调用总结篇.docx_第2页
第2页 / 共18页
atlActiveXdllinfcabweb调用总结篇.docx_第3页
第3页 / 共18页
atlActiveXdllinfcabweb调用总结篇.docx_第4页
第4页 / 共18页
atlActiveXdllinfcabweb调用总结篇.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

atlActiveXdllinfcabweb调用总结篇.docx

《atlActiveXdllinfcabweb调用总结篇.docx》由会员分享,可在线阅读,更多相关《atlActiveXdllinfcabweb调用总结篇.docx(18页珍藏版)》请在冰豆网上搜索。

atlActiveXdllinfcabweb调用总结篇.docx

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//添加by莫小哆_ly

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(a),static_cast(b));

8.

9.*out=static_cast(sum);

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.NewPage

6.

7.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 畜牧兽医

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1