仔细想一想,ADO中有很多想不通的地方,这儿先提一个:
先看下面的脚本:
set f = rs.fields
msgbox f(0).value
rs.movenext
msgbox f(0).value
结果是f(0).value随rs的movenext而改变,也就是说,fields不是一个单独的与recordset无关的接口,因为rs的变化会引起fields的变化。那么fields接口是如何得到recordset对象的呢?因为ADO的Fileds接口上并没有setparent,setrecordset之类的方法使其与某一recordset相关联。
fields跟recordset不是平面结构的,ADO里面只有Connection,Command,Parameter,Recordset,Record,Stream才具有CLSID,也就是说用户调用CreateInstance只能创建这几个对象,至于各种Properties或者Collections,都只能从通过这几个基本对象直接或间接获取,而不能直接创建。
如果它们具有这么一层嵌套关系,还有什么不可以的?
建议你先用oleview查看一下msado15.dll,看看哪些才是coclass?对象不一定是coclass,只有直接暴露给客户CoCreateInstance,才能称为coclass。例如OLEDB里面有无数种对象,可客户通过CoCreateInstance只能创建Data Source对象,别的对象都只能间接获取。
set f = rs.fields -----1
msgbox f(0).value
rs.movenext -----2
msgbox f(0).value
你在1中已经将f设成了对rs.fiels的一个引用,所以,当2执行的时候,所引用的对象也会随之改变。你的代码等价于:
msgbox rs.field(0).value
rs.movenext
msgbox rs.field(0).value
这样就不难理解了吧。
实际上,fields并不是一个接口,而是Recordset接口暴露的一个对象,为了证明这一点,我用VC将msado15.dll import 成C++代码,可以清晰地看出,field地封装智能指针FieldPtr只是RecordSet的一个成员
下面是部分代码:
struct __declspec(uuid("0000050e-0000-0010-8000-00aa006d2ea4"))
Recordset15 : _ADO
{
//
// Property data
//
__declspec(property(get=GetFields))
FieldsPtr Fields;//-----------------------FieldPtr只是RecordSet的一个成员
__declspec(property(get=GetPageSize,put=PutPageSize))
long PageSize;
......
补充前文:
set f = rs.fields -----1
msgbox f(0).value
rs.movenext -----2
msgbox f(0).value
你在1中已经将f设成了对rs.fiels的一个引用,所以,当2执行的时候,所引用的对象也会随之改变。你的代码等价于:
msgbox rs.field(0).value
rs.movenext
msgbox rs.field(0).value
这样就不难理解了吧。
对一个coclass使用noncreatable来表明用户不能直接通过调用CreateInstance /CoCreateInstance来创建一个新的对象。创建一个新的对象需要通过一个方法调用。这种构造对象树的技术在微软其它产品如Office对象组以及ADO中都有应用。
[
uuid(12345678-1234-1234-1234-123456789ABC),
helpstring("This is MyCOClass"),
noncreatable
]
coclass MyCoClass
{
[default] interface IMyClass;
[default, source] dispinterface IMyClassEvents;
}
-微软全球技术中心 VC技术支持
本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款
(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
为了为您创建更好的讨论环境,请参加我们的用户满意度调查
(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
使用static CComObject::CreateInstance可以创建你的组件对象,并且封装了初始化函数FinalConstruct。最好不要手工new CComObject<>().