Windows自带Activex控键,在Bcb中安装一下就可以了
下面我们依次列举使用的步骤:
1、 用C++Builder引入MSXML2.0库
使用C++Builder的Import Type Library可以引入COM组件,对COM组件进行封装生成容易使用的VCL对象。下面介绍引入的方法:
运行C++Builder5.0,使用菜单[Project]/[Import Type Library…]调用C++Builder引入类型库对话框(如右图)在弹出对话框中选择Microsoft XML Version 2.0 [Version 2.0],同时在Class names中列出了其中包含的主要COM类。
在Palette Page中选择你要将封装了COM组件VCL控件放置的Palette Page(就是在C++Builder右上方放置控件的地方)你可以选择一个面板或者定义一个新面板。
在Unit dir name中输入生成的代码存放的路径。
下面的按钮,Create Unit按钮生成封装代码,但是不安装,也就是用户还不能直接使用封装以后的代码。Install按钮,生成封装代码,并打包(Package)安装到C++Buider中,以后就可以使用啦!
点击Install…按钮,(如右图)两个选项卡分别是安装到一个现有包文件(Into existing package)和安装到一个新的包文件(Into new package)。为了便于以后卸载,我选择安装到一个新的包文件。输入文件名和路径。如果愿意可以输入一些描述性信息。点击OK按钮。
系统在进行一段时间的处理后,弹出一个对话框问是否安装这个包,这里选择No,不进行安装。因为不知道为什么,系统生成的代码中存在错误不能够安装需要在下一部中排除错误。这也许是Borland或者Microsoft公司的一个Bug。:-)
2、 修改引入文件中的错误并且安装
如果读者再看第一部的最后选择了Ok,就会发现再进行了漫长的等待后,编译器报告发现拾几个错误,对于这一点笔者一直没有明白为什么。好在笔者通过一段时间的试验后,修正了这些错误。下面我们一起来修改这些错误:
产生的错误都是由于属性(root,readyState,version,doctype)的类型和属性对应的函数的返回类型不同以及函数内部类型不匹配引起的,下面以root属性为例介绍一下修改方法:
找到Get_root这个成员函数。
Msxml_tlb::IXMLElement2Ptr __fastcall Get_root(Msxml_tlb::IXMLElement2Ptr* p/*[out,retval]*/)
{
return GetDefaultInterface()->get_root(p/*[out,retval]*/);
}
改为:
Msxml_tlb::IXMLElement2Ptr __fastcall Get_root()
{
Msxml_tlb::IXMLElement2Ptr p; //类似参数的声明一个局部变量
GetDefaultInterface()->get_root(/*强制类型转换*/ (Msxml_tlb::IXMLElement2Ptr *)&p/*[out,retval]*/);
return p;
}
限于篇幅,这里笔者不对其中的技术细节进行详细的讨论,具体工作就是将函数的参数删除,并在函数体内声明一个与参数类型相同但不是指针型的一个局部变量。然后删除原有语句中的return,并将参数p改为&p并添加强制类型转换。(这一点也是笔者一直不能理解的,但是不这样做似乎又不行),然后将p作为函数的返回值!在笔者的网站上有修改好的代码,可以下载(http://bcsl.cn99.com/cpp/doc/xml8bcb.htm)。
点击Package的Install按钮,安装包。(如右图)又一次经过漫长的等待后,再次出现了错误!这次的前三个错误与上一次很类似,只需要按照相似的方法进行修改就可以了。
最后一个错误比较特殊,但也基本类似。
将:
Msxml_tlb::IXMLElement2Ptr __fastcall createElement(TVariantInParam vType/*[in]*/,
TVariantInParam var1/*[in,opt]*/,
Msxml_tlb::IXMLElement2Ptr* ppElem/*[out,retval]*/)
{
return GetDefaultInterface()->createElement(vType/*[in]*/, var1/*[in,opt]*/,
ppElem/*[out,retval]*/);
}
改为:
Msxml_tlb::IXMLElement2Ptr __fastcall createElement(TVariantInParam vType/*[in]*/,
TVariantInParam var1/*[in,opt]*/,
Msxml_tlb::IXMLElement2Ptr* ppElem/*[out,retval]*/)
{
GetDefaultInterface()->createElement(vType/*[in]*/, var1/*[in,opt]*/,
ppElem/*[out,retval]*/);
return *ppElem;
}
怀着一个忐忑的心,又一次经过漫长的等待。。。。。。成功了!右图的对话框显示注册的主要COM对象。好了!现在就可以使用了!
3、 建立第一个演示程序
上面我们引入并安装了MSXML2.0库,我们可以在开始选择的控件面板上找到COM组件的VCL封装对象,(如右图)其中四个对象分别是:TDOMFreeThreadedDocument, TXMLHTTPRequest, TXMLDSOControl, TXMLDocument。这里我们做一个演示程序,利用TDOMDocument读取一个XML文件,文件的内容是:
<Cajon>
<I Like = "XML"/>
</Cajon>
文件存储在“C:/temp/1.xml”;
首先建立一个新的应用,在主窗体上添加一个DOMDocument对象,起名为xddMain,添加一个按钮,为该按钮添加点击事件,源程序如下:
void __fastcall TwForm1::Button1Click(TObject *Sender)
{
IXMLDOMElementPtr xdeRoot; //定义根节点对象
Msxml_tlb::IXMLDOMElementPtr xdeFirstChild; //定义根节点的第一个子节点对象
if(xddMain->load("c://temp//1.xml")==false){ //读入XML文件
ShowMessage("error"); //如果文件错误或者文件不存在,显示错误信息,退出。
return;
};
xdeRoot = xddMain->documentElement; //提取根节点
ShowMessage(xdeRoot->nodeName); //显示根节点名称
xdeFirstChild = xdeRoot->firstChild; //提取第一个子节点
ShowMessage(xdeFirstChild->nodeName); //显示第一个子节点的名称
ShowMessage(xdeFirstChild->getAttribute(WideString("Like")));
//显示第一个子节点的Like属性
}
在读者建立自己的应用程序时,需要注意的是所有使用字符串的地方都不能够使用C++Builder的AnsiString 必须使用专门针对COM使用的WideString,在上面例子中的红色部分就是一个例子,如果使用一般的“AnsiString(“Like”)”或者简单的“”Like””都不能达到正常的效果。感谢Borland公司已经作了AnsiString到WideString的转换,用起来还是很顺手的!
4、 制作一个写XML文件的例子
在上面的例子中我们读取了一个XML文档,并且显示了其中的信息。这个例子我们将建立一个XML文件,并且想其中写入一些数据。结果生成一个XML文件并且保存为c:/temp/2.XML
内容如下:
<Cajon>
<I Like = "XML"/>
</Cajon>
同样建立一个新的项目,在窗体上添加一个XMLDocument对象,并且命名为xddMain,添加一个按钮,按钮的点击事件代码如下:
void __fastcall TwForm1::Button1Click(TObject *Sender)
{
Msxml_tlb::IXMLDOMElementPtr xdeRoot; //定义根节点对象
Msxml_tlb::IXMLDOMElementPtr xdeFirstChild; //定义第一个子节点对象
xdeRoot = xddMain->createElement(WideString("Cajon")); //建立根节点
xddMain->documentElement = xdeRoot; //设置xdeRoot为XML文件的根节点
xdeFirstChild = xddMain->createElement(WideString("I")); //建立第一个子节点
xdeFirstChild->setAttribute(WideString("Like"),WideString("XML")); //设置子节点的Like属性
xdeRoot->appendChild(xdeFirstChild); //添加子节点到根节点
xddMain->save("c://temp//2.xml"); //保存文档
return;
}
5、 其他要说明的问题
在上面的两个例子中,我们给出了使用C++Builder去读写一个XML文件,下面对于其中一些技术上的细节给以说明:
对于一个XML文件必须拥有一个唯一的根节点,XML文件的所有节点都必须是它的子节点,这个根节点保存在XMLDocument的documentElement属性中。因此在上面的例子中我们可以看到再读去XML文件时必须先读去它的根节点(例程一中蓝色的部分),然后读去它的子节点。同样,建立一个新的XML文件时,也必须先建立它的根节点(例程二中蓝色的部分)并且将它保存到XML文档对象的documentElement属性中。
6、 学习新的方法的途径
以上为各位读者介绍了简单的XML操作方法,由于篇幅的限制,这里不能将笔者所掌握的所有方法介绍给大家,只能向大家介绍一下笔者的学习方法。
当打开开始建立的Package时,会在Class Explorer中显示XMLDOM中所包含的所有的类(如右图),读者可以从这里学到不少的东西(学习编程还是要看源程序的!)。在一个项目的窗体上放置XMLDOM组件后,在ClassExplorer中也会显示并且可以通过ClassExplorer直接察看函数的声明。如果读者已经很好的掌握了XMLDOM,认为这些显示没有用处但是又妨碍正常的编程,可以在窗体的头文件中将#i nclude "MSXML_OCX.h" 改为 #i nclude <MSXML_OCX.h>(注意:需要将这个文件复制到$BCB/Include/vcl下)。保存后,所有多余的显示就会消失