使用 ATL 在 COM 中实现 Hello World






4.41/5 (27投票s)
2002年7月9日
2分钟阅读

201930

4726
本教程的目的是演示如何使用 Visual C++ 6.0 构建 COM 服务器和 MFC 客户端。我们将开发一个 COM 服务器,它接受一个字符串作为输入参数,并返回以“Hello”为前缀的字符串。
引言
本教程的目的是演示如何使用 Visual C++ 6.0 构建 COM 服务器和 MFC 客户端。我们将开发一个 COM 服务器,它接受一个字符串作为输入参数,并返回以 "Hello" 为前缀的字符串。
先决条件
您需要事先在 Windows 中工作过,才能理解诸如对话框、按钮、编辑框等术语。 之前使用过 Visual C++ 将是一个额外的优势。
创建 COM 服务器
- 选择 ATL COM 应用程序向导并输入项目名称。在本例中为
sample1
- 接下来,选择服务器类型为动态链接库,然后单击“完成”。
- 单击“确定”以使类向导生成文件。
- 转到类视图,右键单击
“sample1 classes”
,然后选择“New ATL object”
。 - 现在选择简单对象。
- 键入组件的简称,在本例中为
CGreet
,向导会自动填写其余名称。 - 再次转到类视图
- 右键单击勺子形状的图标,显示
ICGreet
并选择“Add Method”
- 将函数名称键入为
SayHello
,并将参数填写为[in] BSTR name, [out,retval] BSTR *retstr
- 现在转到文件视图,并将以下代码键入到
CGreet.cpp
中,如下所示
//{-----------code added by imran on 18 sept 2k----------------------- // CCGreet STDMETHODIMP CCGreet::SayHello(BSTR name, BSTR *retstr) { // This method's signature is //SayHello([in] BSTR name, [out,retval] BSTR *retstr) char str[20] ; sprintf(str,"hello "); // copy the value of hello into the string variable //create a new variable called temp initialized with the value of str CComBSTR temp(str); //append the input parameter value to the temp variable temp += name ; //send the value back to the calling function *retstr = temp.Detach(); return S_OK; } //-----------code added by imran on 18 sept 2k---------------------------}
创建 COM 客户端
在这里,我们为上述 COM 服务器 DLL 创建一个 COM 客户端。这是一个基于 MFC 对话框的应用程序,带有一个编辑框和两个按钮。- 从项目菜单中选择
New MFC AppWizard
,然后输入项目名称,在本例中为mfcclient
- 选择
Dialog based application
并单击“完成” - 现在您将在资源视图中看到该应用程序。 通过选择
编辑框
将一个编辑框添加到应用程序,然后单击对话框并拖动。 - 还创建一个与之关联的
CString
(值)变量,将其称为 m_edit - 按 CTRL 和 W 以调出类向导。 选择成员变量选项卡并选择IDC_EDIT1
,然后单击“添加变量”,键入名称。 - 现在将生成一个名为
mfcclientdlg.cpp
的文件。 - 双击对话框上的“确定”按钮,向导会弹出一个框,询问函数的名称,选择默认名称“OnOk”以转到
mfcclientdlg.cpp
文件 - 修改文件,使其看起来像下面的文件。
// // mfcclientDlg.cpp : implementation file //{----------------code added by imran ----------------- #include "..\sample1\sample1_i.c" // this is a server file #include "..\sample1\sample1.h" // this is a server file //The above two server files should be included in the client header file #include "Comdef.h" //for usage of BSTR #include "Atlbase.h" // for usage of CComBSTR //----------------code added by imran -----------------} void CMfcclientDlg::OnOK() { //{-----------code added by imran on ---------------------------------- HRESULT hr = CoInitialize(NULL); // Initialize COM library if (FAILED(hr)) //if initialization fails then exit { AfxMessageBox("Failed to initialize COM library"); } //Get the below two constants from the servername_i.c const CLSID CLSID_CGreet = {0x242C8BCE,0x8D72,0x11D4, {0xAC,0x91,0x00,0xB0,0xD0,0x69,0x54,0x6F}}; const IID IID_ICGreet = {0x242C8BCD,0x8D72,0x11D4, {0xAC,0x91,0x00,0xB0,0xD0,0x69,0x54,0x6F}}; char mname[20]; CString cResult; // sprintf(mname,"Imran"); <- can be used to write // a string to a char array // ICGreet is the name of the interface in the CGreet // class (which is the server) // pointer to the interface ICGreet *ptrICGreet = NULL; //create the com hr = CoCreateInstance(CLSID_CGreet, NULL, CLSCTX_INPROC_SERVER,IID_ICGreet, (LPVOID*) &ptrICGreet); if (SUCCEEDED(hr)) { CComBSTR mresult; //get the name typed into the edit box and //copy it into the char array // called mname GetDlgItemText(IDC_EDIT1,mname,20); //typecast the char to a bstr before it is passed to the COM _bstr_t bstresult(mname); //finally... call the COM function via the interface pointer ptrICGreet->SayHello(bstresult,&mresult); //method signature is SayHello([in] BSTR name, //[out,retval] BSTR *retstr) //copy the result into a CString so that //it can be displayed in a message box cResult = mresult; MessageBox(cResult); //copy the result into a CString value variable //associated with the edit box m_edit = mresult; //update the display on the screen UpdateData(FALSE); //free the COM pointer... ptrICGreet->Release(); } //MessageBox(mname); CoUninitialize(); //-----------code added by imran on 18 sept 2k---------------------------} // CDialog::OnOK(); }