本文尽量简洁的介绍ACE与MFC的集成方式,以回复网友的提问。
1. 编译ACE的MFC版本
从DOC ACE网方网站下载的版本,并没有提供编译从mfc的版本。下面给出用MPC工具生成mfc版本的方法
以VC9 (Visual Studio 2008)为例
config.h
// -*- C++ -*- #ifndef ACE_CONFIG_H #define ACE_CONFIG_H #define ACE_DISABLE_WIN32_ERROR_WINDOWS #define ACE_DISABLE_WIN32_INCREASE_PRIORITY #define ACE_HAS_NONSTATIC_OBJECT_MANAGER 1 #include "ace/config-win32.h" #if defined (ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER) #undef ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER #endif #endif /* ACE_CONFIG_H */
cd %ACE_ROOT% cd ace mwc.pl -type vc9 -value_template "configurations = 'MFC Release' 'MFC Debug'" -features mfc=1 -name_modifier "*_mfc_vc9" ACE.mwc
我们可以得到ace_mfc_vc9.sln
用Visual Studio 2008打开编译,我们可以得到 ACEmfcd.lib,ACEmfcd.lib
2. 编写ACE的初始化
MFC程序入口并不是main函数,因此需要手工初始化(init)和结束化(fini)操作
通常可以在MFC的 App:InitInstance()和App:ExitInstance()中分别调用。
本例为了简化和代码可复用,编写了一个初始化的类,可以以全局或作为App的成员,用来确保有ACE的生命期比App类的生命期更长。
代码ACEInitor.h/cpp,分别如下
/* file: ACEInitor.h author: Stone Jiang <jiangtao> blog: http://www.tao-studio.net/blog */</jiangtao> #ifndef ACEInitor_h__ #define ACEInitor_h__ //class ACEInitor class ACEInitor_T { public: ACEInitor_T(); ~ACEInitor_T(); }; #endif // ACEInitor_h__
//file: ACEInitor.cpp #include "ACEInitor.h" #include "ace/ACE.h" ACEInitor_T::ACEInitor_T() { ACE::init(); TRACE("ACEInitor_T::ACEInitor_T()\n"); } ACEInitor_T::~ACEInitor_T() { ACE::fini(); TRACE("ACEInitor_T::~ACEInitor_T()\n"); }
我们这里反ACEInitor类实例g_ACEInit作为全局函数,放在theApp之前,来保证它的生命期比theApp更长。
代码片如下 (ACEwithMFC.cpp Ln 38)
3. 编写运行Reactor事件循环的线程
3.1 编写线程代码
我们有多种方式开一个线程,本例采用从ACE_Task_Base派生子类的方式来创建线程
类名:ACEReactorThread_T (本站的编码风格采用ClassName_T表示类名,蛮多的公司采用呢,关于编码风格我们还不在这里讨论,总之,MFC的匈牙利风格有太多的缺点)
/* file: ACEReactorThread.h author: Stone Jiang <jiangtao> blog: http://www.tao-studio.net/blog */</jiangtao> #ifndef ACEReactorThread_h__ #define ACEReactorThread_h__ #include "ace/Task.h" #include "ace/Reactor.h" class ACEReactorThread_T : public ACE_Task_Base { public: ACEReactorThread_T(ACE_Reactor* r = ACE_Reactor::instance()); virtual ~ACEReactorThread_T(); virtual int open (void *args = 0); virtual int svc(void); ACE_Reactor* reactor(); void reactor(ACE_Reactor* r); void stop(); private: ACE_Reactor* reactor_; }; #endif // ACEReactorThread_h__
3.2 启动线程和结束线程
App::InitInstance()中
this->aceThread_ = new ACEReactorThread_T(); this->aceThread_->open();
App::ExintInstance()中
this->aceThread_->stop(); aceThread_->wait(); delete aceThread_; aceThread_ = 0;
4. 编写ACE事件,并注册进Reactor中
4.1 编写事件
本例与定时器事件为例(这是比较简单的事件)
/* file: MyTimerEventHandler.h author: Stone Jiang <jiangtao> blog: http://www.tao-studio.net/blog */</jiangtao> #ifndef MYTIMEREVENTHANDER_H__ #define MYTIMEREVENTHANDER_H__ #include "ace/Event_Handler.h" class CACEwithMFCDlg; class MyTimerEventHandler_T : public ACE_Event_Handler { public: MyTimerEventHandler_T(CACEwithMFCDlg* pMainWnd); ~MyTimerEventHandler_T(); public: virtual int handle_timeout (const ACE_Time_Value &, const void *arg); private: CACEwithMFCDlg* mainWnd_; }; #endif // MYTIMEREVENTHANDER_H__由于想把事件与主窗口进行交流,所以类MyTimerEventHandler与CACEwithMFCDlg
互相依赖。其中, MyTimerEventHandler与CACEwithMFCDlg是聚合(Aggregation)关系,用UML画出来如下图
4.2 注册事件到反应器
MFC在响应按钮事件的时候,创建事件,并注册到反应器中
void CACEwithMFCDlg::OnBnClickedButtonTimer() { // TODO: Add your control notification handler code here if (this->hander_ == 0) { this->hander_ = new MyTimerEventHandler_T(this); ACE_Reactor* r = theApp.reactor(); ACE_Time_Value tv(2,0); r->schedule_timer(this->hander_,0,tv,tv); } }
注册事件成功后,MyTimerEventHandler::handle_timeout()将入约被Reactor框架回调
handle_timeout生成一个字符串,调用主窗口,将字符串显示在列表框中。
int MyTimerEventHandler_T::handle_timeout(const ACE_Time_Value &, const void *) { static int x = 0; char msg[MAX_PATH] = {0}; ACE_OS::sprintf(msg,"On My Timer Event %d",x++); this->mainWnd_->log(msg); return 0; }
当窗口销毁时,我们将事件从反应器中拆除
void CACEwithMFCDlg::OnDestroy() { if (this->hander_) { ACE_Reactor* r = theApp.reactor(); r->cancel_timer(this->hander_); delete this->hander_; this->hander_ = 0; } CDialog::OnDestroy(); // TODO: Add your message handler code here }
5. 运行界面图
6. 下载源代码
请从本站bbs中下载源代码
如需要更多帮助,请致邮件 jiangtao@tao-studio.net.
Stone Jiang
2008-12-16