WINX的消息分派机制(续2)

我们继续Inside WINX's Message Dispatch。现在开始我们进入了最为关键的部分——WINX是怎么进行消息分派的。

从原理上来讲,WINX的消息分派函数(DispatchMessage)其实与上一篇:《WINX的消息分派机制(续)》中的并无多大的不同,只不过更加智能而已。其中最为关键的是,WINX引入了一种技巧,它可以在编译期判断一个函数是否被重载。简单来说,WINX的消息分派伪代码如下:

template  < class  T >
class  WindowMessage
{
 ...

 BOOL DispatchMessage(
   HWND hWnd, UINT message,
   WPARAM wParam , LPARAM lParam, LRESULT
&  lResult)
 {
  T
*  pThis  =  static_cast < T *> ( this );
  
if  (派生类重载了OnPaint  &&  message  ==  WM_PAINT)
    pThis
-> OnPaint(hWnd);
  
else   if  (派生类重载了OnKeyDown  &&  message  ==  WM_KEYDOWN)
    pThis
-> OnKeyDown(hWnd, wParam, lParam);
  
else   if  (...)
    ...
  
else
    
return  FALSE;
  
return  TRUE;
 }
};

简单看一个实际的例子,这样做的好处就很明了了。设想WindowMessage的派生类只重载了OnPaint,那么WindowMessage类看起来是这样的:

template  < class  T >
class  WindowMessage
{
 ...

 BOOL DispatchMessage(
   HWND hWnd, UINT message,
   WPARAM wParam , LPARAM lParam, LRESULT
&  lResult)
 {
  T
*  pThis  =  static_cast < T *> ( this );
  
if  ( true   &&  message  ==  WM_PAINT)
    pThis
-> OnPaint(hWnd);
  
else   if  ( false   &&  message  ==  WM_KEYDOWN)
    pThis
-> OnKeyDown(hWnd, wParam, lParam);
  
else   if  (...)
    ...
  
else
    
return  FALSE;
  
return  TRUE;
 }
};

并最终被编译器优化为:

template  < class  T >
class  WindowMessage
{
 ...

 BOOL DispatchMessage(
   HWND hWnd, UINT message,
   WPARAM wParam , LPARAM lParam, LRESULT
&  lResult)
 {
  T
*  pThis  =  static_cast < T *> ( this );
  
if  (message  ==  WM_PAINT)
    pThis
-> OnPaint(hWnd);
  
else
    
return  FALSE;
  
return  TRUE;
 }
};

特别地,如果WindowMessage派生类没有响应任何消息,则优化后DispatchMessage为一个空函数,如下:

template  < class  T >
class  WindowMessage
{
 ...

 BOOL DispatchMessage(
   HWND hWnd, UINT message,
   WPARAM wParam , LPARAM lParam, LRESULT
&  lResult)
 {
  
return  FALSE;
 }
};

这就是WINX的消息分派机制为何比MFC、WTL以及其他任何界面库高效(无论是编译后的代码尺寸上,还是执行效率上)的原因。

好了,现在该是解释WINX如何做到这一点——检测派生类是否重载某个函数的时候了。我们假设,基类(名为Base)中有一个成员函数Func(假设有两个参数),现在有另一个成员函数Caller希望根据派生类是否重载Func来做事情。如下:

template  < class  T >
class  Base
{
 RetType Func(ArgType1 arg1, ArgType2 arg2) { ... }
 
void  Caller() {
  
if  (派生类重载了Func) { ... }
  
else  { ... }
 }
};

一个办法是,略微修改一下基类中的Func原型,加上一个无用参数int unused:

 RetType Func(ArgType1 arg1, ArgType2 arg2,  int  unused  =   0 );

或者直接改为可变参数:

 RetType Func(ArgType1 arg1, ArgType2 arg2, ...);

当然,派生类重载Func原型还是需要按我们预期的:

 RetType Func(ArgType1 arg1, ArgType2 arg2);

如此,判断“派生类是否重载了Func”就变成了判断函数原型是否为

 RetType Func(ArgType1 arg1, ArgType2 arg2);

而这正是编译器的拿手好戏。

最后提醒一下,阅读WINX源代码时,你可以发现这个技巧有不少变种(消息分派的实现就与此有细节上的不同),但是其中的道理是完全一致的。

下一篇:WINX的消息分派机制(终结篇)

 

补充:

详细代码请参考WINX库。你也可以通过以下链接在线查看:

WINX的消息分派机制源代码

 




基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值