客户端使用COM组件(整理个人学习思路)
- 博客分类:
- 技术杂绘
我是属于驱动型的人,无法自主的去做某事。只有等到火烧眉头才知道着急。
现在社会技术的发展也是在被商业用途所驱动着,只要有着广阔的商业前景的技术,其发展必然叙述。
在学习COM技术的时候,也是首先要知道我能够用他来干什么,对我有什么用,才会去学。于是,学习时就要先看看如果给我一个
现成COM组件我该怎么使用它呢。好比,要写游戏就要先玩玩游戏一样了。
于是有了下面的COM组件的使用,也是个人在学习时梳理学习思路:
COM组件其实并不复杂,也就是一个特殊的DLL而已。但是一般的DLL我们只要知道它导出了哪些函数。我们该怎样调用即可。
而COM组件,我们的目的不是使用它导出的函数,而是要利用它来实现某个具体的功能。
一般来说,COM组件的DLL导出的函数一般有
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer
函数。当然不是必须的。其中DllRegisterServer和DllUnregisterServer是用来将COM组件注册到系统中。至于其他的函数以后学
习中在说。既然是说COM组件在客户端的使用。就开始了。
首先。COM组件在注册表中注册,就是把组件的代号写在注册表中。该代号就是在写组件时给定的。然后注册时就是告诉系统该代号对应的组件在系统中的什么位置,以及该组件名称是什么。比如在我的系统中有一个组件是COM.dll,在编写主键的时候已确定其
GUID是54BF6563-1007-11D1-B0AA-444553540000,组件名是server.object.在使用Regsvr32 COM.dll注册后,就会在
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\下生成一子项为:{54BF6563-1007-11D1-B0AA-444553540000},该子项下又对应两个子项:InProcServer32和ProgID通过注册表导出得到该组件注册后注册表信息为:
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{54BF65 63-1007-11D1-B0AA-444553540000}]
@="server.object"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{54BF65 63-1007-11D1-B0AA-444553540000}\InProcServer32]
@="E:\\PROGRA~1\\MICROS~1\\MYPROJ~1\\COM\\Debug\\c om.dll"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{54BF65 63-1007-11D1-B0AA-444553540000}\ProgID]
@="server.object"
注册后的组件就可以被客户端使用了。在程序代码中。要使用COM组件。首先调用CoInitialize()函数进行初始化COM库工作。
与其对应的是在使用完成后调用CoUninitialize()清理COM环境。 一般来说,组件的{54BF6563-1007-11D1-B0AA-444553540000}是唯一的。可以直接使用它来创建组件实例,查找组件接口。但是由于该值不容易记忆。一般使用其ProgID值来间接查找。其中通过函数CLSIDFromProgID 来转换。记忆ProgID这样一个有意思的字符串就比较容易了。下面是是一个使用实例。集合注释很清楚的表示了使用过程。int main() { HRESULT hResult = 0; IUnknown *pUnknown; ITestInterFace* pTestCom;//接口指针 if (CoInitialize(NULL) != S_OK) //初始化COM库 printf("Initialize COM library failed!\n"); return -1; } GUID TestComCLSID;//组件标识ID,全球唯一,在注册表中可以直接查找到 //TestCom.Object是注册表中的ProgID的值,通过它就可以查找到组件的标识ID hResult = ::CLSIDFromProgID(L"TestCom.Object", &TestComCLSID); if (hResult != S_OK) { printf("Can't find the TestCom CLSID!\n"); return -2; } //通过组件标识ID创建一个组件实例,pUnknown返回组件的一个通用接口,通过它 //可以查询我们想要的接口 //CLSTX_INPROC_SERVER表示是进程类主键 //其实此处也通过InProcServer32查找到组件的路径并加载到内存 hResult = CoCreateInstance(TestComCLSID, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&pUnknown); if (hResult != S_OK) { printf("Create object failed!\n"); return -2; } //查找要使用的接口,IDD_TestCom是组件的标识符,通过该标识符也就查找到对应的接口了 //该标识符由服务端组件告知,否则写的组件也就失去其意义。 hResult = pUnknown->QueryInterface(IID_TestCom, (void **)&pTestCom); if (hResult != S_OK) { pUnknown->Release(); printf("QueryInterface ITestInterFace failed!\n"); return -3; } //查找到接口后调用接口提供的功能 pTestCom->TestCom(); //告诉接口,不在使用 pTestCom->Release(); //判断该接口是否还被使用 if (pUnknown->Release() == 0) { printf("Com Free Succeeded!\n"); } //清理环境 CoUninitialize(); return 0; } 整个组件的使用过程如代码中所示,很简单。恩,有了饭,还怕不会吃吗,开始还是会怯生,一回生二回熟吧。
发表评论
-
【转】DOS批处理的字符串功能
2012-07-06 09:51 656http://blog.163.com/tanjiuzhe ... -
常见正则表达式
2012-07-06 09:45 644常用的正则表达式 ... -
JAVA正则表达式4种常用功能
2012-07-06 09:37 523正则表达式在字符 ... -
wbc特征提取
2012-07-06 09:30 647/* CvBox2D skin_rect; CvMem ... -
Javascript倒计时 支持自定义样式
2012-07-05 20:45 693在上个版本改进的,这样控制样式更加灵活。 JS脚本: ... -
Flex4 中使用ModuleLoader为子容器 动态加入到TabNavigator导航器容器中的例子
2012-07-02 10:28 622经常在一些工程中看到 选择左侧目录树 右侧添加TAB加载内 ... -
第4课 Flex应用程序结构概述
2012-07-02 10:28 247第4课 Flex应用程序结构概述 --------- ... -
Flex TXT文件导入
2012-07-02 10:28 506在上一篇文章中,我们做了一个文件上传、导入组件,其实就是一 ... -
Flex屏蔽默认右键菜单。
2012-07-02 10:28 536首先需要修改index.template.html生成的静 ... -
Flex缓存客户端
2012-07-01 00:05 485flex或者flash客户端 ... -
QTP测试Flex页面的步骤
2012-07-01 00:05 466需要的环境: ... -
Hello,Flex
2012-07-01 00:05 542一篇《用Flex开发Go ...
相关推荐
使用microsoft.web.ui.webcontrols的TabStrip与IFame组件,达到页的切换效果 HttpModule 实现 ASP.Net (*.aspx) 中文简繁体的自动转换,不用修改原有的任何代码,直接部署即可! 服务器自定义开发二之客户端脚本回发 Web...
8.2.4 使用Jmail组件接收邮件 186 8.2.5 邮件发送类的使用 188 8.2.6 使用正则表达式验证邮件格式 190 8.3 设计过程 191 8.3.1 数据库设计 191 8.3.2 系统登录 191 8.3.3 邮件发送实现 192 8.3.4 为...
8.2.4 使用Jmail组件接收邮件 8.2.5 邮件发送类的使用 8.2.6 使用正则表达式验证邮件格式 8.3 设计过程 8.3.1 数据库设计 8.3.2 系统登录 8.3.3 邮件发送实现 8.3.4 为邮件上传多个附件 8.3.5 邮件接收实现 8.3.6 ...
8.2.4 使用Jmail组件接收邮件 8.2.5 邮件发送类的使用 8.2.6 使用正则表达式验证邮件格式 8.3 设计过程 8.3.1 数据库设计 8.3.2 系统登录 8.3.3 邮件发送实现 8.3.4 为邮件上传多个附件 8.3.5 邮件接收实现 8.3.6 ...
8.2.4 使用Jmail组件接收邮件 8.2.5 邮件发送类的使用 8.2.6 使用正则表达式验证邮件格式 8.3 设计过程 8.3.1 数据库设计 8.3.2 系统登录 8.3.3 邮件发送实现 8.3.4 为邮件上传多个附件 8.3.5 邮件接收实现 8.3.6 ...
最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料;本资料仅用于学习。 【课程内容】 第1周 开课介绍 python发展介绍 第一个python程序 变量 字符编码与二进制 字符编码的区别与介绍 用户交互程序 if ...
答:服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置。 24.在C#中,string str = null 与 string str = “” 请尽量使用文字或图象说明其中的区别。 答:string str = null 是不给他分配...
作者从事了多年的软件开发和培训教学,非常清楚那些容易使新手困惑的问题,在学习过程中会碰到的拦路虎,作者结合了多年实际开发与教学经验,收集了众多学员在学习中常提到的问题,对平时讲课的内容进行了精心整理。...
python入门到高级全栈工程师培训视频学习资料;本资料仅用于学习,请查看后24小时之内删除。 【课程内容】 第1章 01 计算机发展史 02 计算机系统 03 小结 04 数据的概念 05 进制转换 06 原码补码反码 07 物理层和...
-实际上IE7下所以的回发都慢,原因是客户端的Base64编码速度慢,已经使用encodeURIComponent来代替Base64编码。 -俄语翻译(feedback:vbelyaev)。 +2010-06-30 v2.3.1 -ExtAspNet控件将不在依赖ViewState,...
-Button的Pressed属性值能够正确的反映客户端的变化。 -优化Tree控件的AJAX实现。 +为页面的Form添加autocomplete="off"属性。 -参考http://www.cnblogs.com/sanshi/archive/2009/09/04/1560146.html#1635830 ...