基于消息队列的面向对象程序开发框架设计
引言:
面向对象 + 消息队列 的开发模式在vc6.0时代就已经被发现,并且被用在了mfc的开发框架上,并且给当时的软件开发带来了极大的便利。但是由于微软将 mfc 框架封装的太深,所以很少人知道mfc框架的结构是如何设计的,大部分人只知道其是消息队列机制,而且只停留在如何使用上面,本文的提出时为了向大家描述mfc的结构和他的消息机制,并用一个简化版的模型向大家演示。
成员结构 图
成员讲解:
Msg结构体:
描述:用于保存一个消息的结构体
成员:
Mwnd:对象ID
key:事件类型
wParam:参数
lParam:参数
CObject类:
描述:是一个用于自身事件管理的类,在这里我们只给出他关于事件的对象,所有需要使用消息机制的类都需要继承这个类。
成员:
m_EventList::保存注册事件和相应的回调函数的链表。
m_MHND:用于标识对象的一个标志,到时在调用GetObject(MWND) 时就靠这个成员返回对象的指针。
方法:
RegisterEvent(key, pFuncCall):注册事件和相应的回调函数。
UnRegisterEvent(key):取消事件。
OnMessage(key, wParam, lParam):处理外界发来的事件,根据事件调用相应的回调函数。
GetMWND():返回 m_MHND。
CObjMng类:
描述:对象管理类,保存了一个对象链表。在每个Cobject创建时在他的构造函数里会调用RegisterObj()注册自己,在析构时调用UnRegisterObj()删除自己。而这些对象主要提供给 公共的 GetObject() 方法使用(这个方法我们将在等下对他进行描述)。
成员:
M_ObjectList:对象链表,保存所有创建的Cobject对象。
方法:
GetObject(mWnd):同过一个对象的句柄获取这个对象的指针。
RegisterObj(mWnd, pObj):注册这个对象。
UnRegisterObj(mWnd):删除这个对象
公共方法:
RegisterObject(mWnd, pObj):注册CObject对象。主要是在Cobject在构造函数时调用,将自己注册进CObjMng中。
GetObject(mWnd):根据mWnd获取对象的指针,程序中使用使用在 SendMessage() 和 CappMng.GetMessage() 中,通过他获取Cobject的指针,再调用OnMessage,处理事件。
DeleteObj(mWnd):删除Cobject对象,主要是在Cobject析构是把自己在CObjMng的对象链表中删除。
SendMessage(mWnd, key, wParam, lParam):发送消息,不进入消息队,列立即执行。
PostMessage(mWnd, key, wParam, lParam):发送消息,将消息队列。
CWinObject:
描述:窗口基类,定义了窗口的虚方法。由于其成员不会影响理解程序结构,所以就不一一讲解了。
CWndMng:
描述:程序窗口管理类,负责窗口的调度,如显示show(), 鼠标是作用在哪个窗体上OnMouse(),窗体切换OnWndSwitch(),窗体绘制OnPaint()。
成员:
m_WndList:保存所有窗体的对象,CwndObject将在构造函数时注册自己,在析构函数时删除自己,可以使用SendMessage()向CWndMng发消息来处理。
方法:
Create():创建。
Exit():退出。
OnWndSwitch(wParam, lParam):窗体切换。
OnMouse(wParam, lParam):主要是用来判断鼠标当时是点了哪个窗体。
OnPaint(wParam, lParam):窗体重绘。
CCmmResMng:
描述:公共资源管理类,负责公共资源的创建和销毁。由于其成员不会影响理解程序结构,所以就不一一讲解了。
CAppMng:
描述:程序的核心类,负责消息的调度。所有的消息都是进入这个类的消息队列m_MsgQueue,然后再进行分发。
成员:
m_MsgQueue:消息队列,保存所有PostMessage ()发过来的消息。
m_WndMng:CWndMng的对象,在外界发来的关于窗体的消息,都先将发给这个对象,在由这个对象发给对应的窗体。
m_CmmResMng:CCmmResMng的对象,在外界发来关于公共资源的消息是都先发给他,在由这个对象发给指定的资源对象。
m_SngCount:信号量,用来控制GetMessage(),当无消息时,GetMessage()将被挂起,直到有消息道理,由PostMessage()使m_SngCount受信,GetMessage()才继续执行。
方法:
GetMessage():从消息队列获取一个消息,并进行分发执行。
PostMessage(mWnd, key, wParam, lParam):向消息队列填入一个消息。
Create():创建。
Exit():退出
消息流走向:
当程序启动时,首先创建了,CObjMng对象和CAppMng对象,并调用了他们的Create()方法,这时消息队列开始启动。当有继承与CObject的对象被创建时他将被注册进CObjMng对象链表中。
当有消息时,首先调用PostMessage()将消息放入CAppMng的消息队列中,然后由GetMessage()函数获取(顺便说下程序将启用一个独立的线程循环调用GetMessage()方法),并使用mWnd通过GetObject()函数获取对象指针,通过对象指针调用OnMessage()方法进行处理事件。整个程序就是这么无限循环下去,直到有人发了 Exit 事件,程序关闭消息队列,并退出。