[推薦] 用 C++Builder 寫 COM 版的 Hello world |
|
axsoft
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:681 回覆:1056 積分:969 註冊:2002-03-13 發送簡訊給我 |
用 C++Builder 寫 COM 版的 Hello world 作者: 猛禽 資料來源:http://www.dbgnu.com/bcb/doc/view.asp?page=121 前幾日用 OICQ 聯系上一位快有兩年不見的朋友,閒聊中得知他在用 BCB 做 COM ,碰上一些麻煩,我便自告奮勇要教他,剛講了沒幾句便被同事拉去吃飯,便和朋友約好發 e-Mail 給他。第二天我便開始做一個 COM 版的 Hello world! ,仗著用 Delphi 寫過幾個簡單的 COM ,以為用 BCB 也差不多,給果碰到不少問題(幸好沒有當時教他,不然一定出醜)。弄了半天才成功,于是把那個發給他的 Mail 整理了一下貼到這里來。
開始本來想寫個 EXE 的(即 Out of process 的) COM object ,但發現很多 COM 做成 EXE 都有問題,而我又不知道我那朋友熟不熟 DLL (即 In process ),而且 DLL 又不好調試,只好改為 EXE 型的 Automation ,這是最容易的 COM 類型了吧。 開始做 Automation :
1.File|New Application (做 Automation 要有 Form ,即使是個空的也不要拿掉);
2.File|New... 選 ActiveX 頁上的 Automation Object;
在對話框中輸入 COM 名: AutoTest ,其它就用默認值。
3.在打開的 Type Library Editor (就是那個標題為 Project1.tlb 東東)中,左邊的樹中的 IAutoTest 上點右鍵, New 一個 Property ,會產生兩個同名的東東,分別用于 Get 和 Set ,取名為 Hello (兩個會自動變為一樣的),然后在右邊找到 Parameters 頁,將 Type 改為 BSTR(Set) 和 BSTR *(Get ,注意,列表中的 BSTR 沒有*,要自已輸入一個)。
4.然后點頂上那個 Refresh Implementation 的按鈕(按鈕上的小圖片是一張紙,里面有兩個綠色的箭頭成環繞狀),這一步很重要,每次修改完 TLB 文件都要點這個按鈕再存盤,它將產生相應的代碼。
5.在 AutoTestImpl.h 文件中找到如下內容: // IAutoTest
public: STDMETHOD(get_Hello(BSTR* Value));
STDMETHOD(set_Hello(BSTR Value)); 這是 Refresh Implementation 時自動產生的代碼,在后面加上:
private :
WideString FData; Type Library Editor 產生的 CPP/H 文件除了這個以 Impl (即 Implementation )結尾的以外,還有兩個,分別是以 _ATL 和 _TLB 結尾的: _ATL 是自動產生的,通常不用變它,當然如果你有特別的要求並且你對 ATL 又很熟,也可以改改它; _TLB 是由 Type Library Editor 自動維護,無須修改,改了也沒用,你的任何修改都會在 Refresh Implementation 時被改回來的。
再看 AutoTestImpl.cpp 文件,找到如下內容:
STDMETHODIMP TAutoTestImpl::get_Hello(BSTR* Value) { try { } catch(Exception &e) { return Error(e.Message.c_str(), IID_IAutoTest); } return S_OK; };這也是自動產生的東東,在這個 try 中輸入: try { *Value = FData; // 加在這里 }在 Set 的 Try 中輸入: FData = Value; 注意一定要用 try..catch 括起來,否則..。 Delphi 就不用,這沒辦法,因為 BCB 是用 ATL 的嘛,而 Delphi 是用 Borland 自已搞的 DAX(Delphi ActiveX Extension) , BCB 就是在這點上和 Delphi 有很大不同。 6.Save All ,編譯。 7.在命令行下運行: Project1 /regserver 注冊這個 COM ,注銷則用: Project1 /unregserver 記得刪除 COM 之前一定要先注銷,不然你只好到注冊表里慢慢找了。 使用 Automation (前期聯編用法): 1.File|New Application 2.在 Project2 中加入 Project1_TLB.CPP 3.在 Unit2.h 中加入: #include "Project1_TLB.h" 和: private: // User declarations TCOMIAutoTest MyTest; // 加入的 4.在 Form 上放一個 Label 和一個 Button 。雙擊BUTTON,在事件響應中輸入: try { if ( !MyTest ) { MyTest = CoAutoTest::Create( ); MyTest.Hello = WideString( "Hello world!" ); } Label1->Caption = MyTest.Hello; } catch ( EOleSysError &e ) { ShowMessage( e.Message ); }5.Save All ,編譯。 6.運行后,點 Button ,你會看到 Project1 也運行起來,同時 Label1 顯示 "Hello world!" 。 當 Project2 退出時, Project1 也自動退出。會了吧。 另一種使用 Automation 的方法(后期聯編用法): 1.File|New Application 2.在Unit3.cpp中加入: #include Variant v = CreateOleObject( "Project1.AutoTest" ); v.Exec( PropertySet( "Hello" ) << "Hello world!" ); Label1->Caption = v.Exec( PropertyGet( "Hello" ) );4.Save All ,編譯。 5.運行后,點 Button ,你會看到 Project1 也運行起來,同時 Label1 顯示 "Hello world!" ,然后 Project1 就退出了。 這就是COM,有意思吧。用 BCB ATL 寫 COM 就是這麼簡單。 ![]() |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |