bcb 中使用 msxml

Windows自帶Activex控鍵,在Bcb中安裝一下就可以了

 下面我們依次列舉使用的步驟:

1、 用C++Builder引入MSXML2.0

    使用C++BuilderImport 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)。

    點擊PackageInstall按鈕,安裝包。(如右圖)又一次經過漫長的等待後,再次出現了錯誤!這次的前三個錯誤與上一次很類似,只需要按照相似的方法進行修改就可以了。

    最後一個錯誤比較特殊,但也基本類似。

將:

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++BuilderAnsiString 必須使用專門針對COM使用的WideString,在上面例子中的紅色部分就是一個例子,如果使用一般的“AnsiString(“Like”)”或者簡單的“”Like””都不能達到正常的效果。感謝Borland公司已經作了AnsiStringWideString的轉換,用起來還是很順手的!

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; //設置xdeRootXML文件的根節點

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文件的所有節點都必須是它的子節點,這個根節點保存在XMLDocumentdocumentElement屬性中。因此在上面的例子中我們可以看到再讀去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下)。保存後,所有多餘的顯示就會消失。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章