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.