序论
第一步:运行ATL COM Wizard
运行Visual C++ 并创建一个新的工程,选择“ATL COM AppWizard”,项目名称为”Simple_ATL”。设置好项目的保存路径,单击“OK”,你将看到弹出的一个对话框,如下所示:
我们将创建一个Server DLL, 故在“Server Type”项中选择“Dynamic Link Library(DLL)”,下面的三个“Check Box”在该工程中不考虑,保持默认值,单击“Finish”,ATL COM AppWizard将为你创建相应的文件,在弹出的“New Project Information”窗口中显示了这些文件的信息,单击“OK”完成工程的创建。
第二步:创建一个新的ATL对象
在Visual C++的左边的工程视图区(如果没有打开,按“ATL+0”),选中ClassView标签,你将看到”Simple_ATL classes”, 选中它并单击鼠标右键,将弹出如下的对话框:
默认选项“Simple Object”就是我们所要创建的对象,单击“Next”,呈现在你面前的将是“ATL Object Wizard Properties”窗口,在“Short Name”一栏,输入“First_ATL”,注意其它输入栏中的名字将自动填写。选择“Attributes”标签页,此处要进行一些设定。“Threading Model”设为“Apartment”,“Interface”属性设为“Dual”,而“Aggregation”选中“NO”,其余选项不考虑,保留默认值。单击OK,Wizard将为我们创建新的ATL Simple Object。
第三步:添加方法(Method)
此时,工程视图区中增加一个名为CFirst_ATL的组件类。添加方法非常简单,右击“IFirst_ATL”,选中“Add Method…”,如下图:
当选择了“Add Method…”之后,将弹出“Add Method to Interface”的窗口。在返回类型中,方法的默认返回类型为“HRESULT”。在绝大多数情况下,应该保留该类型。在Method Name一栏中,填入方法的名字“AddNumbers”。最后一个输入栏为方法的参数。我们的方法是一个简单的加法运算,需要输入两个数并返回一个计算结果,因此我们需要三个参数。最后一个参数可以用指针。在参数框中我们输入如下内容:
[in] long Num1, [in] long Num2, [out] long *ReturnVal
其中[in]表示输入,[out]表示输出。单击OK,完成方法的添加。在“ClassView”中,展开视图,你将在“IFirst_ATL”接口下看到我们添加的方法和相应的参数。双击打开该方法的实现,并添加相应的代码,如下:
STDMETHODIMP CFirst_ATL::AddNumbers(long Num1, long Num2, long *ReturnVal)
{
// TODO: Add your implementation code here
*ReturnVal = Num1 + Num2;
return S_OK;
}
{
// TODO: Add your implementation code here
*ReturnVal = Num1 + Num2;
return S_OK;
}
第四步:编译
按F7编译,VC++将完成DLL的编译,并且在注册表中注册新的组件DLL,从而使得其它程序能够使用它。
第五步: 在其它VC程序中测试COM Server
打开VC,创建一个新的“Win32 Console Application”工程,添加一个“Test_ATL.cpp”文件,文件中添加如下代码:
#include "..Simple_ATLSimple_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 =
{0x15DF21E3,0x5563,0x4BF4,
{0x9D,0x97,0x7C,0x72,0xAF,0x9A,0x87,0xF3}};
const CLSID CLSID_First_ATL =
{0x582996DD,0xAE11,0x41DF,
{0xA2,0x0E,0xE7,0xA7,0x8A,0xF4,0x68,0x67}};
int main(void)
{
HRESULT hr;
IFirst_ATL *IFirstATL = NULL;
//Initialize 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;
}
}
CoUninitialize();
return 0;
}
#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 =
{0x15DF21E3,0x5563,0x4BF4,
{0x9D,0x97,0x7C,0x72,0xAF,0x9A,0x87,0xF3}};
const CLSID CLSID_First_ATL =
{0x582996DD,0xAE11,0x41DF,
{0xA2,0x0E,0xE7,0xA7,0x8A,0xF4,0x68,0x67}};
int main(void)
{
HRESULT hr;
IFirst_ATL *IFirstATL = NULL;
//Initialize 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;
}
}
CoUninitialize();
return 0;
}
代码比较简单,如有不清楚的,可以通过注释理解,这里不在详细说明。编译,运行结果如下: