本文的對象是COM編程初學者,其目的旨在描述如何用ATL創建COM服務器,以及如何在VC或VB編寫的客戶端應用程序中調用COM服務器。為了不給初學者增加負擔,本文不打算深入討論COM和IDL的細節,而是展示用ATL創建簡單的COM對象所需要的步驟。希望通過這篇文章能刺激你學習COM編程的欲望。
第一步:運行ATL COM向導(參見圖一)
你要做的第一件事情是啟動VC創建一個新的工程。選擇“ATL COM AppWizard”。注意這個向導創建的工程並沒有包含任何初始的COM對象,在完成這個向導之後,要從“ClassView”中用“New ATL Object”命令來指定你想要增加到這個工程中的對象類型。
在“Project name”編輯框中為工程取個名字:“Simple_ATL”。在“Location”編輯框中指定工程的存放位置,如“E:\samples\Simple_ATL”,然後單擊OK按鈕。
(圖一)
你會看到一個選擇屏幕(圖二)。
(圖二)
第一部分單選按鈕選項是要創建的服務器類型“Server Type”。因為我們要創建一個進程內服務器(Server DLL),所以應該選擇的類型是動態鏈接庫“Dynamic Link Library——DLL”,注意所有進程內服務器都是DLL。下面是三個復選框不用去管它,它和我們創建的這個工程沒關系。單擊“Finish”按鈕。向導將自動產生相應的文件。然後出現“New Project Information”窗口告訴你向導將要創建一些什麼文件(圖三)。確認後單擊OK按鈕。
(圖三)
第二步:創建新的ATL對象
確定在VC的IDE環境中見到“Workspace View”。也就是工作間視圖。你也可以進入“View”菜單,然後選擇“Workspace”。這個視圖中由三個標簽,單擊“ClassView”標簽。你會看到其中的“Simple_ATL Classes”。選中後單擊右鍵並從彈出菜單中選擇“New ATL Object”。你會見到如下窗口:(圖四)
(圖四)
我們就用缺省選擇(Simple Object),也就是簡單對象。單擊“Next”按鈕進入“ATL Object Wizard Properties”,也就是ATL對象向導的屬性對話框(圖五)。
(圖五)
在“Short Name”文本編輯框中輸入“First_ATL”。注意向導會自動填寫其余的文本編輯框。單擊“Attributes”標簽。其中有幾組單選按鈕選項和幾個復選框。第一組單選按鈕是線程模型“Threading Model”,我們取缺省值“Apartment Model”。第二組單選按鈕是接口“Interface”,單擊“Dual”,也就是雙接口。最後,第三組單選按鈕是聚合“Aggregation”,因為我們不想涉及接口的聚合,所以在此選擇“No”。至於底下的三個復選框,我們不用管它,單擊OK按鈕讓向導創建新的“ATL Simple Object”
第三步:添加方法
如果你單擊工作間的“ClassView”標簽,你會注意到向導在裡面添加了一些內容。添加一個方法很容易,(圖六)選中“IFirst_ATL”後單擊右鍵並選擇“Add Method”。
(圖六)
單擊“Add Method”後,你會看到“Add Method to Interface”對話框(圖七)。
(圖七)
在“Return Type”編輯框中(已成灰色)這個方法的返回值已經缺省為 “HRESULT”。大多數情況下都應該是這個值類型。下一個編輯框是方法名“Method Name”,輸入方法名“AddNumbers”。最後一個編輯框是要你輸入希望使用的參數“Parameters”。由於我們打算將兩個數字相加,然後返回相加結果,所以要使用三個參數。最後一個參數是一個指針。現在你不用去關心繁雜的接口定義語言IDL,只要在這個參數編輯框中輸入如下內容:
[in] long Num1, [in] long Num2, [out] long *ReturnVal
它的意思是聲明兩個long類型輸入[in]參數和一個指針返回值[out](剛開始可能會不習慣這樣怪怪的寫法,但等你閱讀了一兩本關於COM的書之後,會慢慢接收它的)。單擊OK按鈕。展開所有“ClassView”的節點“+”號。從這個視圖可以清楚地了解Simple_ATL各個類之間的層次關系。雙擊最上面“IFirst_ATL”(接口)節點下的“AddNumbers”(方法)節點,右邊屏幕將會顯示這個方法的實現代碼。添加如下的代碼:
STDMETHODIMP CFirst_ATL::AddNumbers(long Num1, long Num2, long *ReturnVal)
{
// TODO: Add your implementation code here
*ReturnVal = Num1 + Num2;
return S_OK;
}
第四步:編譯這個DLL
不管你想不相信,到目前為止,我們用ATL所創建的COM服務器已經完全能運行!當然,還需要編譯它才行。按下“F7”功能鍵,幾秒鐘之後,VC++便會完成編譯並注冊你所創建的DLL服務器。這樣其它的應用程序就可以使用這個COM服務器了。試一試吧!
第五步:用VB測試這個服務器
為了用VB來測試COM服務器,首先你必須安裝VB的開發環境。(如果你沒有安裝VB或不想用VB測試,可以跳過這一步到下一步:用VC++測試COM服務器。)首先啟動VB,選擇創建標准EXE“Standard EXE”工程。在對話框中放一個按鈕。然後我們要引用COM服務器。單擊“Project”菜單並選擇“References”。然後下翻頁直到可以看見“Simple ATL 1.0 Type Library”(如圖八),然後選中它。
(圖八)
單擊OK按鈕。現在雙擊前面在對話框中創建的命令按鈕,VB將會帶你到這個按鈕的代碼窗口。然後添加以下代碼:
Private Sub Command1_Click()
Dim objTestATL As SIMPLE_ATLLib.First_ATL
Set objTestATL = New First_ATL
Dim lngReturnValue As Long
objTestATL.AddNumbers 5, 7, lngReturnValue
MsgBox "The value of 5 + 7 is: " & lngReturnValue
Set objTestATL = Nothing
End Sub
如果你是個VB程序員,這對你來說簡直太容易了。聲明變量和對象,調用COM服務器的“AddNumbers”方法,然後顯示結果。按下“F5”功能鍵運行這個VB工程,單擊對話框中的命令按鈕,你會看到輸出的結果。(如圖九)
(圖九)
下面再讓我們用VC++測試這個COM服務器。
第六步:用VC測試這個服務器
保存並關閉Simple_ATL工程,然後創建一個新的Win32 控制台應用程序。選擇“Win32 Console Application”並取名為“Test_ATL”。單擊OK按鈕並接受對話框中的缺省設置(空的工程)。單擊“Finish”按鈕,然後再按OK按鈕。這樣就創建好了一個空的工程。按下“Control+N”鍵向工程中添加一個文件。從彈出的窗口中選擇“C++ Source File”並為它取名為“Test_ATL.cpp”。按下OK按鈕。這樣工程中就有了一個空的.CPP文件。我們要在這個文件中添加一些測試COM服務器的代碼:
// 將頭文件的目錄指到Simple_ATL工程所在的目錄
#include "..\Simple_ATL\Simple_ATL.h"
#include
// 從Simple_ATL 工程所在目錄的Simple_ATL_i.c 文件中拷貝以下內容
// 注意: 你也可以不拷貝這些東西,而是把文件Simple_ATL_i.c包含進來。
// 我之所以將它拷進來,是想更清楚地展示這些敞亮來自什麼地方一擊它們的代碼
const IID IID_IFirst_ATL =
{0xC8F6E230,0x2672,0x11D3,{0xA8,0xA8,0x00,0x10,0x5A,0xA9,0x43,0xDF}};
const CLSID CLSID_First_ATL =
{0x970599E0,0x2673,0x11D3,{0xA8,0xA8,0x00,0x10,0x5A,0xA9,0x43,0xDF}};
void main(void)
{
// 聲明HRESULT和Simple_ATL接口指針
HRESULT hr;
IFirst_ATL *IFirstATL = NULL;
// 初始化COM
hr = CoInitialize(0);
// 使用SUCCEEDED 宏並檢查我們是否能得到一個接口指針
if(SUCCEEDED(hr))
{
hr = CoCreateInstance( CLSID_First_ATL, NULL, CLSCTX_INPROC_SERVER,
IID_IFirst_ATL, (void**) &IFirstATL);
// 如果成功,則調用AddNumbers方法,否則顯示相應的出錯信息
if(SUCCEEDED(hr))
{
long ReturnValue;
IFirstATL->AddNumbers(5, 7, &ReturnValue);
cout << "The answer for 5 + 7 is: " << ReturnValue << endl;
IFirstATL->Release();
}
else
{
cout << "CoCreateInstance Failed." << endl;
}
}
// 釋放COM
CoUninitialize();
}
第七步:編譯並運行測試程序
按下“F5”功能鍵,編譯測試程序,然後按“Control+F5”功能組合鍵運行測試程序。在DOS窗口中,你應該能看到輸出的結果。
本文配套源碼