初学者入门:一个COM/ATL简单项目(转)
译注:本文应用是VC6.0,对于其他版本向导可能与本文介绍的不同。
原文地址:http://www.codeproject.com/atl/com_atl.asp
作者: C. Lung.
简介
本教程的目的在于,给读者一个关于使用ATL创建一个COM服务的方法的初步印象,并且让读者在使用VC++或者VB编程的时候,学会调用这个服务。本教程仅仅是为了VC++程序员中的初学者设计,因此笔者不打算深入介绍COM的细节,也不打算增加您学习IDL之类的负担。笔者希望展示的是使用ATL创建一个“简单”COM“对象方法简单易用,并且希望因此能让初学者对此感兴趣而深入学习。
第一步:运行 ATL COM 向导
启动VC++之后的第一步是创建一个新项目。选择“ATL COM AppWizard”。为本项目命名为“Simple_ATL”。设置本项目的保存路径,并点击OK。这是您将看到几个选项。第一个选择是“服务器类型”。我们这里打算建立一个Server DLL(服务器DLL),因此选择服务类型为“Dynamic Link Library(动态链接库)”。下面还有三个选项,不过与我们本次的项目无关,无视。点击结束按钮,保存本项目。这时屏幕上会显示一个“New Project Information新项目信息”的窗口,这个窗口描述了刚才创建的项目内容。点击OK表示接受。
第二步:创建一个新的ATL对象
确保打开VC++ IDE中的Workspace(工作区)视图。如果没打开,您可以点击视图菜单,然后选择“Workspace ”。Workspace显示出来的内容中有三个选项卡,点击“ClassView(类视图)”选项卡,您将看到"Simple_ATL Classes"。鼠标右键点击这个东东,然后选择"New ATL Object(新建ATL对象)"。您将看到如下窗口:
默认选择 (Simple Object)就是我们需要的。点击“下一步”,您将看到"ATL Object Wizard Properties("ATL Object Wizard 属性)"窗口。在“Short Name”中输入"First_ATL",您将看到向导会自动为您填写其他的输入栏。点击上端的"Attributes(属性)"选项卡,将显示下列选项。第一个是Threading Model(线程模式),我们保持默认的Apartment Model就好。对于"Interface(接口)",选择“Dual”。最后,是我们不关心的"Aggregation(集合)",点击“No”选项。我们不需要关心底下的三个选项。点击OK确定就可以了。
第三步:添加一个方法
如果您现在在工作区点击“类视图”选项卡,您将看到向导已经在这里添加了一堆东西。我们要做的第一件事就是添加一个方法。我们可以通过右键点击“IFirst_ATL”然后选择”Add Method“轻松添加。
您点击“Add Method”之后,将看到“添加方法至界面”的窗口。在返回值类型下面,您可以看到默认的方法返回类型为“HRESULT”。大多数情况下,您不需要理会这个选项。下一个文字框允许我们输入方法名。我们在这里输入“AddNumbers”。最后一个文字框要求我们输入实用的参数。如果我们想要两个数相加,并返回一个结果,我们需要三个参数。最后一个参数是一个指针。现在我们先不去看那些三百多页的IDL教程,直接把下面的内容输入到参数框中。
I 在这里,我们生命了两个long型的参数,这两个参数是[in]也就是输入值,而最后一个值是返回的[out]输出值。(第一次看到可能觉得有点搞笑,不 过如果您读过关于COM的书,就能够接受这种东西了)点击确认按钮。点击“ClassView”选项卡并且打开视图中的所有加号。最上面的接口("IFirst_ATL")被打开后,您能看到我们的“AddNumbers”方法,以及我们给他的参数。双击这个东东,将带我们进入编码区,我们修改代码如下:
long Num2, long *ReturnVal)
{
// TODO: Add your implementation code here
*ReturnVal = Num1 + Num2;
return S_OK;
}
第四步:编译DLL
你相信么,现在已经我们已经用ATL建立好一个可以执行的COM服务了!当然,还要编译一下。在VC++的环境中按F7就可以了。编译器会“吱嘎吱嘎”一会儿——计算机在注册你的DLL,以便让其他程序可以使用。接下来,我们试一下。第五步:用VB测试COM服务
首先我们用VB来试验一下COM服务。(如果你没有VB,也可以跳过这章,直接用VC测试)启动VB并选择"Standard EXE(标准EXE)"作为你的项目。在对话框中放一个命令按钮。现在我们要配置COM服务了。点击“项目“菜单,选择“配置”。下拉这个列表,找到"Simple ATL 1.0 Type Library"。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
Not too hard. Lets try this again, except with VC++.
第六步:用VC测试COM服务
保存并关闭以前的 Simple_ATL项目,并创建一个新项目。选择"Win32 Console Application",命名为"Test_ATL",点击确认并接受下一个窗口的默认值”An empty project(空项目)“。用CTRL+N创建一个新文件。选择"C++ Source File(c++源代码文件)"并且命名为"Test_ATL.cpp"。按确认键接受。这时会打开一个空文件,我们需要在这里填入一些代码来测试我们的COM服务。将下列代码填入到这个新的cpp文件中:// you placed the Simple_ATL project
#include "..\Simple_ATL\Simple_ATL.h"
#include <iostream.h>
// Copy the following from the Simple_ATL_i.c file
// from the Simple_ATL project directory
// NOTE: You can actually skip copying these if you want
// and just include the Simple_ATL_i.c file, I simply added
// it for clarity to show where these const variables are
// coming from and what they look like
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)
{
// Declare and HRESULT and a pointer to
// the Simple_ATL interface
HRESULT hr;
IFirst_ATL *IFirstATL = NULL;
// Now we will intilize COM
hr = CoInitialize(0);
// Use the SUCCEEDED macro and see if
// we can get a pointer
// to the interface
if(SUCCEEDED(hr))
{
hr = CoCreateInstance( CLSID_First_ATL, NULL,
CLSCTX_INPROC_SERVER,
IID_IFirst_ATL, (void**) &IFirstATL);
// If we succeeded then call the AddNumbers
// method, if it failed
// then display an appropriate message to the user.
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;
}
}
// Uninitialize COM
CoUninitialize();
}
第七步:编译并运行程序
按“F5”可以编译程序,然后按CTRL+F5可以运行程序。这是您可以看到一个DOS窗口,显示这您需要的结果。C. Lung
本文来源:http://blog.csdn.net/mhoudg/archive/2007/08/25/1758491.aspx