现在的位置: 首页 > 综合 > 正文

ATL创建进程外COM

2012年09月09日 ⁄ 综合 ⁄ 共 2149字 ⁄ 字号 评论关闭

12.1.10  使用ATL创建进程外组件

1.问题阐述

在前面创建的组件均属于进程内组件,即组件对象和客户进程在同一个进程,客户进程在同一进程内调用组件对象提供的服务;进程外组件,组件对象和客户进程分属不同的进程,客户进程可以跨进程调用组件对象提供的服务。如何创建一个进程外的组件呢?

2.实现技巧

使用ATL创建组件向导创建一个进程外组件,首先使用ATL COM AppWizard创建一个工程,如图12-11所示。

单击【OK】按钮,选择组件提供服务时所用的类型。在此因为是进程外组件,故选用Executable类型,如图12-12所示。

 

(点击查看大图)图12-11  创建工程

 

 

(点击查看大图)图12-12  选择组件提供服务器的类型

最后添加组件提供的接口,和前面介绍的就基本一致了。

3.实例代码

本例的消费者和生产者的简单模型由COM来实现。

组件服务器具体创建步骤如下。

(1)用ATL COM Appwzard创建一个新的工程,工程名为ProcOut。

(2)选择组件提供服务时所用的类型(.dll或.exe)。

(3)在工程中插入一个对象。在ClassView选项页面,用鼠标右键单击工程名,在弹出的右键菜单中选择【New ATL Object】,在打开的对话框中选中Simple Object,如图12-13所示。

 

图12-13  新建组件对象

(4)单击【Next】按钮,在打开对话框的ShortName中输入 Modu,其他的按默认设置,如图12-14所示。

 

图12-14  组件命名

(5)定义接口函数。在接口IModu上面点击鼠标右键,在弹出的快捷菜单中选择【Add Method】命令。出现添加生产函数对话框,添加接口函数HRESULT,参数Produce([in]long nProduce),如图12-15所示。

 

图12-15  添加生产函数

(6)添加消费函数HRESULT Customer([in]long nProduce),如图12-16所示。

 

图12-16  添加消费函数

(7)添加属性,在ClassView页中用鼠标右键单击接口,选择【Add Property】命令,打开的对话框如图12-17所示。

 

图12-17  添加属性

(8)组件服务的代码,组件服务提供了生产和消费函数及改变属性的两个函数,其代码参考如下。

在类Cobject的头文件Object.h中添加成员变量:

int m_lNum;//表示当前的数量

生产函数的参考代码如下:

STDMETHODIMP CObject::Produce(long nProduce)
{
m_lNum += nProduce;
return S_OK;
}

消费函数的参考代码如下:

STDMETHODIMP CObject::Customer(long nCustomer)
{
m_lNum -= nCustomer;
if(m_lNum<0)
{
MessageBox(NULL,"消耗没了","提示",MB_OK);
m_lNum = 0;
}
return S_OK;
}

接口属性函数的参考代码如下:

STDMETHODIMP CObject::get_CurrentNum(long *pVal)
{
*pVal = m_lNum;
return S_OK;
}

STDMETHODIMP CObject::put_CurrentNum(long newVal)
{
m_lNum = newVal;
return S_OK;
}

(9)在客户端创建一个基于对话框的工程ProcOutTest,放置两个文本框分别表示生产或消耗的数量和当前现存的数量。放置两个按钮,用于响应生产和消费事件。参考代码如下。

在ProcOutTest的InitInstance中添加AfxOleInit( )初始化应用程序COM环境。

在stdafx.h中引入ProcOut.tlb库:

#import "ProcOut.tlb" no_namespace

在ProcOutTestDlg.h中声明接口的智能指针:

IobjectPtr  m_Iobject

在ProcOutTest.cpp中的OinitDialog添加创建接口实例的代码:

HRESULT hr = m_IObject.CreateInstance(L"ProcOut.Object");
if(FAILED(hr))
{
MessageBox("创建接口实例失败!");
return FALSE;
}
m_IObject->put_CurrentNum(100);//初始化数量为100
m_IObject->get_CurrentNum(&m_Cur);

响应生产和消费两个按钮事件的代码:

void CProcOutTestDlg::OnProduceBtn()
{
UpdateData(TRUE);
m_IObject->Produce(m_Num);
m_IObject->get_CurrentNum(&m_Cur);
UpdateData(FALSE);
}

void CProcOutTestDlg::OnCustomerBtn() 
{
UpdateData(TRUE);
m_IObject->Customer(m_Num);
m_IObject->get_CurrentNum(&m_Cur);
UpdateData(FALSE);
}

运行效果如图12-18所示。

抱歉!评论已关闭.