下载本文示例代码
天极IT资讯短信服务 电脑小技巧 function check4() { if (dn.mobile.value.length!=11) { alert("手机号码不正确!"); dn.mobile.focus(); return false; } return true; } 资费:包月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得到CLSIDwchar_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;// 得到DISPIDDISPID 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()成员函数执行此方法。
天极IT资讯短信服务 电脑小技巧 function check4() { if (dn.mobile.value.length!=11) { alert("手机号码不正确!"); dn.mobile.focus(); return false; } return true; } 资费:包月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得到CLSIDwchar_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;// 得到DISPIDDISPID 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()成员函数执行此方法。
下载本文示例代码
COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四COM编程技术基础之四