熟悉.NET的人都知道,  .NET使用委托可以快速实现观察者模式,免去写很多繁杂重复的代码。遗憾的是,C++并没有提供这样的模型,为了达到相似的目的,需要继承一个类并重写virtual方法,这种做法需要写很多代码,效率比较低下。然而,在强大的C++面前,没有什么是不可能的,已经有很多人针对这个问题进行过研究,并且实现了各种委托模型,其中最著名的就是FastDelegate。为了让使用FastDelegate更象.NET,我新添加几个模板,主要如下:

 

首先添加一个两个类用于模拟事件发生源及事件参数类:

// 定义事件发送源(类似于.net的sender)
class IEventSource
   3: {
public:
virtual ~IEventSource (){}
   6: };
   7:  
namespace fastdelegate;
   9:  
// 定义标准的事件参数
class CEventArgs
  12: {
public:
void)
  15:     {
FALSE;
  17:     }
  18:  
  19:     BOOL    bHandled;
  20: };

然后是定义一个事件句柄管理类:

// 定义事件句柄,用于管理事件中加入的委托
class TBase>
class CEventHandlerBase
   4: {
public:
virtual ~CEventHandlerBase ()
   7:     {
int i = _delegates.GetSize () - 1; i >= 0; i --)
   9:         {
delete (TBase*) _delegates[i];
  11:         }
  12:         _delegates.Empty ();
  13:     }
  14:  
return _delegates.GetSize (); }
  16:  
// 添加委托
operator += (TBase& eventDelegate)
  19:     {
new TBase (eventDelegate));
  21:     }
  22:  
// 删除委托
operator -= (TBase& eventDelegate)
  25:     {
int i = _delegates.GetSize () - 1; i >= 0; i --)
  27:         {
if (*((TBase*) _delegates[i]) == eventDelegate)
  29:             {
delete (TBase*) _delegates[i];
  31:                 _delegates.Remove (i);
  32:             }
  33:         }
  34:     }
  35:  
public:
  37:     CStdPtrArray _delegates;
  38: };

最后定义一个宏用于快速创建事件句柄:

// 定义生成事件句柄的类 handleClass 为句柄类名称,eventClass 为参数类名称
#define DEFINE_EVENT_HANDLER(handleClass, eventClass) \
typedef FastDelegate2<IEventSource *, eventClass *> eventClass##Delegate;\
public CEventHandlerBase<eventClass##Delegate>\
   5:     {\
public:\
void Fire (IEventSource* sender, eventClass* e)\
   8:         {\
int i = _delegates.GetSize () - 1; i >= 0; i --)\
  10:             {\
  11:                 (*(eventClass##Delegate*) _delegates[i]) (sender, e);\
  12:             }\
  13:         }\
  14:     }
  15:  
  16: DEFINE_EVENT_HANDLER (CStdEventHandler, CEventArgs);

使用如有两种情况,一是只用CEventArgs参数类型就可以满足要求,二是需扩展自己的参数类型。如果需要扩展参数,代码如下:

public CEventArgs
   2: {
public:
int delta1);
   5:  
int delta;
   7: };
   8:  
// void handler (IEventSource* sender, CMouseEventArgs* e);
  10: DEFINE_EVENT_HANDLER (CMouseEventDelegate, CMouseEventArgs);

应用代码示例如下:

public IEventSource
   2: {
private:
void);
public:
void);
   7:  
void);
   9:  
// 定义鼠标点击事件
  11:     CMouseEventDelegate MouseClick;
  12:  
  13:     ……
protected:
int nCode, WPARAM wParam, LPARAM lParam)
  16:     {
  17:         CGlobalWindowMsgHook* This = instance();
  18:         PMSLLHOOKSTRUCT hookStruct = (PMSLLHOOKSTRUCT)lParam;
  19:         
int msg = wParam;
int x = hookStruct->pt.x;
int y = hookStruct->pt.y;
short)((hookStruct->mouseData >> 16) & 0xffff);
  24:         
if (msg == WM_LBUTTONUP)
  26:         {
// 触发鼠标点击事件
  28:             This->MouseDown.Fire (This, &CMouseEventArgs (Left, 0, x, y, delta));
  29:         }
  30:         ……
  31:     }
  32:     ……
  33: };
  34:  
// 测试类
class CTest
  37: {
public:
  39:     CTest ()
  40:     {
this, &CTest::MouseDownHandler);
  42:     }
  43:     ~CTest ()
  44:     {
this, &CTest::MouseDownHandler);
  46:     }
  47:  
void MouseDownHandler (IEventSource* sender, CMouseEventArgs* e)
  49:     {
));
  51:     }
  52: }

相关文章:

  • 2021-05-31
  • 2022-01-31
  • 2021-08-28
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-12
  • 2021-07-26
  • 2022-12-23
  • 2021-08-05
  • 2022-12-23
  • 2022-02-14
  • 2022-12-23
相关资源
相似解决方案