模仿MFC消息驱动机制

36 篇文章 0 订阅
27 篇文章 0 订阅

模仿MFC消息驱动机制


欢迎向我索要模仿MFC消息驱动的实例源码,希望能与更多的人讨论。

邮箱:wjh_2010@163.com

 

       在微软推出的MFC架构中,其消息驱动机制是其精髓,使用简单,效率高,而且思路清晰。如果能够模拟MFC的消息驱动机制,并添加一些自己的消息映射(例如消息可以用字符串表示),那么在程序的移植上就会有非常大的帮助。

 

1. MFC 消息的基本使用规则

 

A. 定义自己的类,派生于CWnd

B. 在类的内部声明DECLARE_MESSAGE_MAP()

C. 定义消息映射表:

BEGIN_MESSAGE_MAP(CChildViewCWnd)

ON_WM_PAINT()

END_MESSAGE_MAP()

 

      分析这三个宏的定义,即可发现其消息映射表的实现规则(宏的定义请直接参考VS的工程)

 

一个类的消息映射表的框图如下:

 

       由于DECLARE_MESSAGE_MAP()声明的函数为虚函数,所以基类获得的消息映射表是最上层的映射表。在消息派发的时候,就可以先在子类的消息映射表中查找,查找不到再交给其基类处理,这样一直往底层派发。

 

2. 实现MFC消息架构的基本原理

       在C/C++中,基本上好的程序架构都离不开回调函数。MFC的消息架构也是如此,不过在C++中有虚函数的概念。因为回调函数能够解决模块间的耦合问题。

       在MFC中定义消息映射的宏很多,例如ON_MESSAGE。每个消息映射都有一个类的成员函数,这函数就是回调函数。底层调用这些回调函数的时候能够实现像用对象调用这些函数一样,在函数中直接使用this指针。

       MFC中,不同的消息映射,其实现的回调函数参数不一样。

实现MFC的消息架构需要实现的基本点如下:

A. 回调函数调用类的成员函数,函数内部使用this指针;

B. 根据不同的消息类型,给回调函数传入不同的参数;

C. 对象的注册与注销,可能在消息函数中释放对象;

D. 消息队列的处理与派发消息过程;

E. 消息函数的重入问题;

 

       对于AB两点,在MFC的消息架构中可以看到其源码,可以参考消息映射宏的实现与CWnd::OnWndMsg函数的实现。

       对于问题C,可以在基类的构造函数中实现注册,在析构函数中实现注销,对于对象的释放做出规定。

       对于问题D,在消息队列中获得的消息,首先需要找到目标对象,然后再目标对象中查找对应的消息映射表,调用相应的回调函数。

       在CWnd::OnWndMsg中如下语句说明了如何查找消息映射表。

for (/* pMessageMap already init'ed */pMessageMap->pfnGetBaseMap != NULL;

pMessageMap = (*pMessageMap->pfnGetBaseMap)())

 

3. 模拟MFC消息驱动机制

      在MFC的消息机制中,一般在窗口类中实现消息的收发。自定义的类若不是派生于CWnd,则无法实现消息映射。并且发送消息必须有hwnd句柄(类对象直接调用send等函数则省略了该参数)。并且其消息映射只能使用整型数字,无法使用字符串来标志消息类型。

      我们希望模拟MFC的消息机制,并扩展MFC的消息机制,实现如下功能:

A.定义整型的消息映射表

B.定义字符型的消息映射表

C.可以广播消息

D.可以通过对象名,而不单使用对象关联句柄发送消息。

 

定义带消息驱动的类:

class CCmdParser : public CMsgBase

 

CCmdParser:类为自定义类,派生于CMsgBase即可实现消息映射。

CMsgBase:是所有消息类的基类,其构造函数和析构函数会实现对象的注册与注销。

 

如果CCmdParser 需要实现自己的消息映射表,则在类中声明

//声明消息映射表

DECLARE_MFH_MESSAGE_MAP()

然后在类的实现中声明映射表:

//消息映射表

BEGIN_MFH_MESSAGE_MAP(CCmdParser,CMsgBase)

MFH_COMMAND("SLOGIN",&CCmdParser::DealLoginCommand)

MFH_COMMAND("SStartFileTransmit",&CCmdParser::DealLoginCommand)

MFH_BOARDCAST(MSG_CHECK_USER,&CCmdParser::DealCheckUser)

MFH_MESSAGE(MSG_START_SERVER,&CCmdParser::StartServer)

END_MFH_MESSAGE_MAP()

 

主程序的使用如下:

int _tmain(int argc_TCHARargv[])

{

CCmdParser parser;

 

parser.PostUserMessage(MSG_START_SERVER,NULL,NULL);

 

return CMsgBase::Exec();

}

 

       在模拟消息机制中主要需要实现sendMessage,PostMessage类似的函数和消息循环Exec()函数。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值