创建一个基于模板的数据库记录集操作类(三)
ado封装
前面讲了建立一个记录的结构和对variant数据结构进行转换,在这篇里面,对ado接口进行封装.微软的ado数据操作接口是以com的形式发布的,在用import指令对com的动态库进行导入之后,会在工程的输出目录下生成tlh和tli两个文件,tlh是于c和c++用于操作com接口的头文件,在其中声明了一些 com接口和com对象的 IID和CLSID,还有接口的属性和方法,都以c/c++可以用的形式做了转换,那个tli文件其实就是tlh文件中声明的一些结构的成员函数的实现,被tlh文件包含.在tlh文件中,通过宏_COM_SMARTPTR_TYPEDEF用模板类_com_ptr_t对接口进行了包装,
_COM_SMARTPTR_TYPEDEF是一个很奇怪的宏,最终生成的是一个以Ptr结尾的类如:
_COM_SMARTPTR_TYPEDEF(Field15, __uuidof(Field15));
实际上生成的类的名称是Field15Ptr类, 类型是_com_ptr_t<Field15, __uuidof(Field15)>
在我实现的模板类中,没有打算在类的整个生命周期中拥有一个ADO接口的记录集成员或者或者ADO连接,我只打算在一些成员函数中,通过局部变量来使用ADO接口.所以对ado进行了部分的封装.
#define MAKE_ADO_COM_CLASS_TYPEDEF(e) typedef CComWrapper
<
e##Ptr
>
CCom##e
template
<
typename
com_class
>
class CComWrapper :
public
com_class
{
private
:
void CreateInstance() {
int
i
=
100
;
}
public
:
com_class
&
operator
=
(
const
com_class
&
cp) {
com_class::operator
=
(cp);
return
*
this;
}
CComWrapper() {}
CComWrapper(CLSID uid) {
::CoInitialize(
NULL
);
HRESULT hr
=
com_class::CreateInstance(uid);
if
(FAILED(hr)) {
//
AfxMessageBox(_T(
"
Create Com Object Error!
"
));
TRACE(_T(
"
Create Com Object Error!\n
"
));
}
}
~CComWrapper() {
if
(GetInterfacePtr())
com_class::Release();
}
};
MAKE_ADO_COM_CLASS_TYPEDEF(_Collection);
MAKE_ADO_COM_CLASS_TYPEDEF(_DynaCollection);
MAKE_ADO_COM_CLASS_TYPEDEF(_ADO);
MAKE_ADO_COM_CLASS_TYPEDEF(Properties);
MAKE_ADO_COM_CLASS_TYPEDEF(
Property
);
MAKE_ADO_COM_CLASS_TYPEDEF(
Error
);
MAKE_ADO_COM_CLASS_TYPEDEF(Errors);
MAKE_ADO_COM_CLASS_TYPEDEF(Command15);
MAKE_ADO_COM_CLASS_TYPEDEF(Connection15);
MAKE_ADO_COM_CLASS_TYPEDEF(_Connection);
MAKE_ADO_COM_CLASS_TYPEDEF(Recordset15);
MAKE_ADO_COM_CLASS_TYPEDEF(Recordset20);
MAKE_ADO_COM_CLASS_TYPEDEF(Recordset21);
MAKE_ADO_COM_CLASS_TYPEDEF(_Recordset);
MAKE_ADO_COM_CLASS_TYPEDEF(Fields15);
MAKE_ADO_COM_CLASS_TYPEDEF(Fields20);
MAKE_ADO_COM_CLASS_TYPEDEF(Fields);
MAKE_ADO_COM_CLASS_TYPEDEF(Field20);
MAKE_ADO_COM_CLASS_TYPEDEF(Field);
MAKE_ADO_COM_CLASS_TYPEDEF(_Parameter);
MAKE_ADO_COM_CLASS_TYPEDEF(Parameters);
MAKE_ADO_COM_CLASS_TYPEDEF(Command25);
MAKE_ADO_COM_CLASS_TYPEDEF(_Command);
MAKE_ADO_COM_CLASS_TYPEDEF(ConnectionEventsVt);
MAKE_ADO_COM_CLASS_TYPEDEF(RecordsetEventsVt);
MAKE_ADO_COM_CLASS_TYPEDEF(ConnectionEvents);
MAKE_ADO_COM_CLASS_TYPEDEF(RecordsetEvents);
MAKE_ADO_COM_CLASS_TYPEDEF(ADOConnectionConstruction15);
MAKE_ADO_COM_CLASS_TYPEDEF(ADOConnectionConstruction);
MAKE_ADO_COM_CLASS_TYPEDEF(_Record);
MAKE_ADO_COM_CLASS_TYPEDEF(_Stream);
MAKE_ADO_COM_CLASS_TYPEDEF(ADORecordConstruction);
MAKE_ADO_COM_CLASS_TYPEDEF(ADOStreamConstruction);
MAKE_ADO_COM_CLASS_TYPEDEF(ADOCommandConstruction);
MAKE_ADO_COM_CLASS_TYPEDEF(ADORecordsetConstruction);
MAKE_ADO_COM_CLASS_TYPEDEF(Field15);
在上面的代码中,通过一个模板类CComWrapper,对ado生成的Ptr类型作了继承,主要是在析构函数中自动释放接口.同时,我把tlh和tli着两个文件改成了一个h文件和一个inl文件,这样在使用的时候,就不用再使用import指令了.