This article tries to briefly introduce the integration of ACE and MFC to reply to questions from netizens.
1. Compile the MFC version of ACE.
The version downloaded from the doc ace website does not provide the version compiled from the MFC. The following describes how to generate an MFC version using the MPC tool.
Take vc9 (Visual Studio 2008) as an Example
Config. h
//-*-C ++ -*-# Ifndef 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"#IfDefined (ace_doesnt_instantiate_nonstatic_object_manager) # UNDEF ace_doesnt_instantiate_nonstatic_object_manager # endif/* Ace_config_h */
Cd % ace_root % Cd acemwc. pl-type vc9-value_template"Deployments = 'mfc release' 'mfc debug'"-Features MFC = 1-name_modifier"* _ Mfc_vc9"Ace. MWC
We can get ace_mfc_vc9.sln
Open and compile with Visual Studio 2008. We can get acemfcd. Lib, acemfcd. Lib
2. Write ace Initialization
MFCProgramThe entry is not the main function, so you need to manually initialize (init) and fini operations
Generally, it can be called in MFC App: initinstance () and app: exitinstance () respectively.
In this exampleCodeReusable. An initialized class can be written globally or as a member of the app to ensure that the life cycle of an ace is longer than that of an app class.
The Code aceinitor. h/CPP is as follows:
/* File: aceinitor. hauthor: Stone Jiang
Blog: http://www.tao-studio.net/blog */
# Ifndef aceinitor_h __# define aceinitor_h __// Class aceinitorClassAceinitor_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");}
Here, the anti-aceinitor class instance g_aceinit is used as a global function before theapp to ensure that its life cycle is longer than theapp.
The Code is as follows (acewithmfc. cpp LN 38)
3. Write the thread that runs the reactor event loop 3.1 write the thread code
We have multiple ways to open a thread. In this example, we use the method of deriving subclass from ace_task_base to create a thread.
Class Name: acereactorthread_t (the class name is represented by classname_t in the coding style on this site. It is used by many companies. We will not discuss the encoding style here. In short, the Hungary style of MFC has many disadvantages)
/* File: acereactorthread. hauthor: Stone Jiang
Blog: http://www.tao-studio.net/blog */
# 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 start and end threads
APP: initinstance ()
This-> Acethread _ =NewAcereactorthread_t ();This-> Acethread _-> open ();
APP: exintinstance ()
This-> Acethread _-> stop (); acethread _-> wait ();DeleteAcethread _; acethread _ = 0;
4. Write ace events and register the events in reactor 4.1.
This example is an example of a timer event (this is a simple event)
/* File: mytimereventhandler. h Author: Stone Jiang
Blog: http://www.tao-studio.net/blog */
# Ifndef mytimereventhand_h __# define mytimereventhand_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 // Mytimereventhand_h __
To communicate events with the main window, the class mytimereventhandler and cacewithmfcdlg
Mutual dependency. Here, the relationship between mytimereventhandler and cacewithmfcdlg is aggregation.
4.2 register the event to the reactor
When responding to the button event, MFC creates the event and registers it to the reactor.
VoidCacewithmfcdlg: onbnclickedbuttontimer (){// Todo: add your control notification handler code hereIf(This-> Hander _ = 0 ){This-> Hander _ =NewMytimereventhandler_t (This); Ace_reactor * r = theapp. Reactor (); ace_time_value TV (2, 0); R-> schedule_timer (This-> Hander _, 0, TV, TV );}}
After the event is successfully registered, mytimereventhandler: handle_timeout () is called back by the reactor framework.
Handle_timeout generates a string, calls the main window, and displays the string in the list box.
IntMytimereventhandler_t: handle_timeout (ConstAce_time_value &,Const Void*){Static IntX = 0;CharMSG [max_path] = {0}; ace_ OS: sprintf (MSG ,"On my timer event % d", X ++ );This-> Mainwnd _-> log (MSG );Return0 ;}
When the window is destroyed, we remove the event from the reactor.
VoidCacewithmfcdlg: 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. Running Interface
6. Download Source code
Download source code from BBS on this site
Http://www.tao-studio.net/bbs
If you need more help, please contact your jiangtao@tao-studio.net.
Stone Jiang