您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
COM编程技术基础之四
[文章信息]
作者:中国电波传播研究所青岛分所郎锐
时间:2004-02-02
出处:yesky
责任编辑:方舟
[文章导读]
所谓自动化对象,指的是实现了IDispatch接口的COM对象,IDispatch接口是自动化对象的一个重要标志
advertisement
热点推荐
· 11.10软件精选 FW实用设计
· IE最新安全漏洞补救几大措施
· M牛的网络生活之下载篇
· Norton Ghost 9.0全新体验
· InstallShield简明使用教程之前言
[正文]
天极IT资讯短信服务 电脑小技巧
资费:包月5元
手机:
介绍:细处着手,巧处用功。高手和菜鸟之间的差别就是:高手什么都知道,菜鸟知道一些。电脑小技巧收集最新奇招高招,让你轻松踏上高手之路。


  所谓自动化对象,指的是实现了IDispatch接口的COM对象,IDispatch接口是自动化对象的一个重要标志。使用自动化技术的一个主要目的就是对COM的一些底层操作进行简化。包括自动化组件和自动化客户两方面的内容,分别用来定义和使用自动化对象。 自动化对象包含有属性和方法这两种重要的组成。属性类似于类中的数据成员,方法则类似于类成员函数,只不过这里的属性只能被读取而不允许被写入。自动化组件除了定义自动化对象外,还将内部可编程对象展现给自动化客户,而自动化客户则对这些暴露的自动化对象进行操作。具体的操作包括:创建一个新的自动化对象,获取、设置自动化对象的属性,以及调用自动化对象的方法等。IDispatch接口作为自动化对象的重要特征,可以通过QuereyInterface()函数查询此接口来确定组件是否是自动化对象。IDispatch接口直接从IUnknown接口派生,接口定义如下:

interface IDispatch : IUnknown
{
 virtual HRESULT GetTypeInfoCount(UINT* pctinfo) = 0;
 virtual HRESULT GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) = 0;
 virtual HRESULT GetIDsOfNames (REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) = 0;
 virtual HRESULT Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr ) = 0;
}

  其中,接口成员函数GetTypeInfoCount()用于获取自动化组件支持的ITypeInfo接口的数目。GetTypeInfo()用于获取指针ITypeInfo接口的指针,通过该指针将能够判断自动化服务程序所提供的自动化支持。剩下的这两个函数是比较重要的,其中GetIDsOfNames()将读取一个函数的名称并返回其调度ID(DISPID),DISPID只是一个long类型的数据,对于IDispatch的一个特定实现,此DISPID值应该是唯一的。其参数riid为保留参数,必须设置为IID_NULL,在rgszNames中指定了成员的函数名及其参数,由cNames标识了名字的个数,lcid参数用于指定本地化标识,得到的DISPID 将保存到rgdispid中。Invoke()提供了访问自动化对象暴露出来的方法和属性的方法。可以将DISPID作为函数指针数组的索引传入dispidMember参数,Invoke()将实现一组按此索引来访问的函数。riid和lcid的含义与在GetIDsOfNames()中的定义相同,分别为保留参数和本地化标识。WFlags参数指定了要访问的是接口的属性还是方法,pdispparams参数包括了方法和属性调用的参数数组、DISPID数组以及数组中参数个数等信息。pvarResult参数保存有返回值信息。pexcepinfo指向一个有效的异常信息结构,puArgErr参数包含了第一个产生错误的参数指针。通过GetIDsOfNames()和Invoke()的结合使用,将可以根据函数名称对方法和属性进行调用。这样,函数地址、AddRef()、Release()以及接口指针等细节问题将无需考虑。下面结合一段实例代码来说明对IDispatch接口的使用:

// 从ProgID得到CLSID
wchar_t progid[] = L"MSCAL.Calendar.7";
CLSID clsid;
if (FAILED(::CLSIDFromProgID(progid, &clsid)))
 return;
 // 得到IDispatch接口指针
IDispatch* pIDispatch = NULL;
if (FAILED(::CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pIDispatch)))
 return;
// 得到DISPID
DISPID dispid;
OLECHAR* func = L"Today";
if (FAILED(pIDispatch->GetIDsOfNames(IID_NULL, &func, 1, GetUserDefaultLCID(), &dispid)))
 return;
// 通过DISPID使用Today方法
DISPPARAMS dispparams = {NULL};
if (FAILED(pIDispatch->Invoke(dispid, IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &dispparams, NULL, NULL, NULL)))
 return;
// 将日期移动到今天
AfxMessageBox("日期成功移动到今天");

  这段代码使用的是Calendar组件,并通过IDispatch接口完成对Today()方法的调用。CLSIDFromProgID()将Calendar组件的ProgID转换为CLSID,并以此CLSID和IID_IDispatch作为参数去调用CoCreateInstance()以得到IDispatch接口指针。通过其成员函数GetIDsOfNames()得到将要调用的Today方法的DISPID,最后使用Invoke()成员函数执行此方法。

·"WAP天极之IT新闻资讯,50万元等你拿"    ·天极WAP之游戏狂图,50万元等你下载


发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容阅读排行榜
  • 简析Visual C++中的活动数据对象
  • VC++.NET实现应用程序XP风格
  • VC++编程调用Windows关机对话框
  • Visual C++中OpenGL编程入门
  • 为OpenFile对话框增添预展功能
  • 用Visual C++设计窗体探测器
  • 用VC++6.0编写注册表管理程序
  • COM编程技术基础之三
  • COM编程技术基础之二
  • COM编程技术基础之一
  • 11.10软件精选 FW实用设计
  • 精英主板全面迈进P5时代
  • 详解11月三大硬件杀手游戏及四大凶器
  • 选硬盘 用好希捷互动存储专家
  • NDS十大最受期待游戏
  • 中国星际个人联赛第6轮综述
  • 教你破解GeForce6800变Ultra
  • 魔兽UD必胜的几大原因
  • Advertisement

    天极无线
    待机彩图    >>更多
    多彩动画    >>更多
    美妙和弦    >>更多
    天使在唱歌
    壁虎漫步
    PrettyBoy
    LoveLoveLove
    我是你的小小狗
    单身情歌
    十面埋伏
    祝酒歌
    回心转意
    波斯猫
    太委屈
    S.H.E
    潘玮柏
    M2M
    蔡依林
    阿牛
    林志炫
    陈弈迅
    刀郎
    黑龙
    S.H.E
    陶晶莹
    情人玫瑰坊
    音乐风云
    新片速递
    神秘测试
    都市约会
    ·天极彩信天天精彩
    ·图铃梦工厂下载无限!
    ·找寻童真,卡通专题
    ·夏日激情交友社区!
    ·星座运程,预测人生

    CSEEK搜索