【ATL/DLL】VS2005 互发消息

来源:互联网 发布:人物杂志 知乎 编辑:程序博客网 时间:2024/05/02 01:58

【目的】:创建两 DLL,使两 DLL 能互发消息

【工具】:VS2005

【步骤简介】:

1、创建 MFC APPLICATION 工程 Message

2、创建 MFC DLL 工程 Common

3、再创建两 ATL SIMPLE 工程 Sender 和 Receiver。如下图。


【Wizard】:

1、Common工程选择自动化

2、Sender和Receiver都选上两附加选项:

【属性设置】:

1、输出:

我把输出文件都放在bin目录下,源文件发在src目录下。VS在生成Message工程后,关闭工程,然后再Message文件夹下新建src文件夹,将Message、Message.sln等文件(夹)移入src。再创建common、sender、receiver工程。



生成文件都输出到bin文件夹

2、特殊设置

将类型库放入lib


【代码】:

1、message调用sender接口启动消息的发送

#import "../../bin/Sender.dll" no_namespacevoid CMessageDlg::OnBnClickedButton1(){// TODO: 在此添加控件通知处理程序代码try{ISendMsgPtr pSender;HRESULT hr = pSender.CreateInstance(__uuidof(SendMsg));if(SUCCEEDED(hr)){pSender->Start();}}catch(...){}}

2、common.idl 为 common.dll 声明 IAdapter 接口

// Common.idl : Common.dll 的类型库源// 此文件将由 MIDL 编译器处理以产生// 类型库 (Common.tlb)。[ uuid(7520BCC4-AA02-4037-9E27-9141FACD3BD6), version(1.0) ]library Common{importlib("stdole32.tlb");importlib("stdole2.tlb");[object,uuid(8FDED875-8019-4c79-9EB6-A9A4C412A91D),dual,nonextensible,helpstring("IAdapter 接口"),pointer_default(unique)]interface IAdapter : IDispatch{[id(1), helpstring("方法Attach")] HRESULT Attach([in] IDispatch* pDispatch);[id(2), helpstring("方法Detach")] HRESULT Detach();[id(3), helpstring("方法OnMsg")] HRESULT OnMsg([in] BSTR bstrMsg);};};

3、Sender 头文件

//导入依赖库文件#import "../../lib/Common.tlb"no_namespace raw_interfaces_only named_guids#import "../../lib/Receiver.tlb"no_namespace raw_interfaces_only named_guids// CSendMsgclass ATL_NO_VTABLE CSendMsg :public CComObjectRootEx<CComSingleThreadModel>,public CComCoClass<CSendMsg, &CLSID_SendMsg>,public IDispatchImpl<ISendMsg, &IID_ISendMsg, &LIBID_SenderLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,public IDispatchImpl<IAdapter, &__uuidof(IAdapter), &LIBID_SenderLib>//继承 IAdapter{public:CSendMsg(){}DECLARE_REGISTRY_RESOURCEID(IDR_SENDMSG)BEGIN_COM_MAP(CSendMsg)COM_INTERFACE_ENTRY(ISendMsg)//COM_INTERFACE_ENTRY(IDispatch)COM_INTERFACE_ENTRY(IAdapter)//暴露接口COM_INTERFACE_ENTRY2(IDispatch, IAdapter)//暴露接口END_COM_MAP()DECLARE_PROTECT_FINAL_CONSTRUCT()HRESULT FinalConstruct(){return S_OK;}void FinalRelease(){}protected:CComPtr<IReceiveMsg> m_pAgent;void CreateAgent();public:STDMETHOD(Start)(void);//供message调用的方法STDMETHODIMP Attach(IDispatch* pDispatch);//实现IAdapter接口方法STDMETHODIMP Detach();//实现IAdapter接口方法STDMETHODIMP OnMsg(BSTR bstrMsg);//实现IAdapter接口方法};OBJECT_ENTRY_AUTO(__uuidof(SendMsg), CSendMsg)

sender实现文件:

STDMETHODIMP CSendMsg::Start(void){AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: 在此添加实现代码CreateAgent();if(m_pAgent){BSTR bstrMsg = _com_util::ConvertStringToBSTR("来自 Sender 的消息!");m_pAgent->OnMsg(bstrMsg);SysFreeString(bstrMsg);}return S_OK;}


STDMETHODIMP CSendMsg::Attach(IDispatch* pDispatch){AFX_MANAGE_STATE(AfxGetStaticModuleState())return S_OK;}STDMETHODIMP CSendMsg::Detach(){AFX_MANAGE_STATE(AfxGetStaticModuleState())return S_OK;}//消息发送与接收STDMETHODIMP CSendMsg::OnMsg(BSTR bstrMsg){AFX_MANAGE_STATE(AfxGetStaticModuleState())char *pszMsg = _com_util::ConvertBSTRToString(bstrMsg);if( IDOK == MessageBox(AfxGetApp()->GetMainWnd()->m_hWnd, CString(pszMsg), _T("Sender Box"), MB_OKCANCEL)){BSTR bstrMsg = _com_util::ConvertStringToBSTR("来自 Sender 的消息!");m_pAgent->OnMsg(bstrMsg);//发送消息SysFreeString(bstrMsg);}delete []pszMsg;return S_OK;}//创建与receiver的联系void CSendMsg::CreateAgent(){if(m_pAgent != NULL)return;try{HRESULT hr = CoCreateInstance(__uuidof(ReceiveMsg), NULL,\CLSCTX_INPROC, __uuidof(IReceiveMsg), (LPVOID *)&m_pAgent);if(SUCCEEDED(hr)){m_pAgent->Attach((IDispatch*)(IReceiveMsg*)this);}}catch(...){}}

4、receiver的头文件部分代码,receiver自身只要提供以下三个方法并实现就可以了:

#import "../../lib/Common.tlb"no_namespace raw_interfaces_only named_guids


STDMETHOD(Attach)(IDispatch* pDispatch);//自身提供的方法STDMETHOD(Detach)(void);//自身提供的方法STDMETHOD(OnMsg)(BSTR bstrMsg);//自身提供的方法

receiver的实现:

STDMETHODIMP CReceiveMsg::Attach(IDispatch* pDispatch){AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: 在此添加实现代码try{if(pDispatch == NULL){return S_FALSE;}/*在 Sender 中,创建 IReceiveMsg 接口,并调用 CReceiveMsg::Attach, 将 Sender 接口 pDispatch 传进来,在CReceiveMsg::Attach中查询 IAdapterPtr 接口,赋给 m_pAdapter*/IAdapterPtr pAdapter;HRESULT hr = pDispatch->QueryInterface(__uuidof(IAdapter), (void **)&pAdapter);if(SUCCEEDED(hr)){m_pAdapter = pAdapter;}}catch(...){}return S_OK;}STDMETHODIMP CReceiveMsg::Detach(void){AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: 在此添加实现代码return S_OK;}STDMETHODIMP CReceiveMsg::OnMsg(BSTR bstrMsg){AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: 在此添加实现代码char *pszMsg = _com_util::ConvertBSTRToString(bstrMsg);if( IDOK == MessageBox(AfxGetApp()->GetMainWnd()->m_hWnd, CString(pszMsg), _T("Receiver Box"), MB_OKCANCEL)){BSTR bstrMsg = _com_util::ConvertStringToBSTR("来自 Receiver 的消息!");m_pAdapter->OnMsg(bstrMsg);SysFreeString(bstrMsg);}delete []pszMsg;return S_OK;}

【效果】:




0 0