MFC相关技术说明:<可参阅MSDN MFC TNO 5>
MFC 中通过通过不同于SDK的switch的方法来处理WINDOWS消息,
由消息映射表(Message Map)和虚函数多态来处理指定的窗体消息
1 声明一个消息映射表(Message Map)
在能处理消息的类中中添加宏
DECLARE_MESSAGE_MAP()
注 深入浅出MFC中有更详尽系统的概述 这里只介绍几个宏定义
这个宏实现了3个功能:
1 私有数据成员声明 AFX_MESSAGEMAP_ENTRY _messageEntries;数组
2 保护数据成员声明 AFX_MESSAGE_MAP _messageMap指向_messageEntrie数组
3声明并定义虚保护成员函数 GetMessageMap()用于得到 _messageMap的地址
宏的实现及相关的成员变量
注意 具有消息处理得类必须从CCmdTarget派生而来
CCmdTarget派生的类至少可以处理WM_COMMAND消息而只有消息的派发可以参看
CMDTARG.CPP中的函数实现 AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg()派发消息的函数)
类具有处理窗体的消息必须要从CWnd类中派生
以下是CWnd及其派生类处理并派发消息的成员函数
CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
2实现一个消息映射表
在类的实现文件中添加消息映射表
表头宏 BEGIN_MESSAGE_MAP(CMyClass, CBaseClass)
表未宏 END_MESSAGE_MAP()
在表中添加相关的宏可以实现过滤 拦截处理消息 否则消息会顺着消息映射表在类的派生结构中流向基类
2.1处理标准WINDOW消息宏
(AfxMsg_.h的头文件中找到相关宏定义)
在消息映射表中添加 ON_WM_xxx(xxx为消息名称)
ie:
如在一个窗体中处理WM_PAINT消息
BEGIN_MESSAGE_MAP(CMyWnd, CBaseWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
还需添加一个对应的处理WM_PAINT的成员函数在CMyWnd中
标准Windows消息处理ON_WM_XXX对应的成员函数类型可以在
注意:该功能可以通过class winzard来完成
2.2处理COMMAND消息的消息映射表宏
(AfxMsg_.h的头文件中找到相关宏定义)
COMMAND消息一般是由菜单命令和加速健按下产生的
2.2.1 ON_COMMAND
ON_COMMAND(CMD_ID OnCmdFunc)
afx_msg void OnCmdFunc();
注意:可以由class winzard完成
2.2.2 ON_COMMAND_UI
ON_COMMAND_UI (CMD_ID, OnUpdateCmdUIFunc)
afx_msg void OnUpdateCmdUIFunc(CCmdUI* pCmdUI);
注意:可以由class winzard完成
2.2.3 ON_COMMAND_RANGE
ON_COMMAND_RANGE(START_ID, END_ID, OnCmdRangeFunc)
afx_msg void OnCmdRangeFunc (int ID)
注意:不可以由class winzard完成
2.2.4 ON_COMMAND_UI_RANGE
ON_COMMAND_UI_RANGE (START_ID, END_ID, OnUpdateCmdUIFunc)
afx_msg void OnUpdateCmdUIFunc(CCmdUI* pCmdUI);
注意:不可以由class winzard完成
2.2.5 ON_COMMAND_EX
ON_COMMAND_EX (ID, OnCmd)
BOOL OnCmd()返回TURE表示消息得到处理, 否则消息会在消息路由中继续流动
类似于异常的再次抛出
注意:不可以由class winzard完成
2.3 处理用户自定义消息
ON_MESSAGE(WM_USERDEFINED, OnMsg)
HRESULT OnMsg(WPARAM , LPARAM);
用户定义的消息的值可以定义WM_USER - 0x7fff之间
2.4 处理注册消息(系统级)
::RegisterWindowMessage()
通过这个API可以在系统中注册一个消息并保证在系统内部是唯一的
处理这样的消息的宏
ON_REGISTERED_MESSAGE(WM_REGISTERED_MSG, OnMsg)
afx_msg HRESULT OnMsg(WPARAM, LPARAM);
2.5 处理控件消息
控件发送给父窗体的通知消息父窗体可以在这时改变一些空间的状态或做出响应 WM_NOTIFY的消息
ON_NOTIFY( wNotifyCode, id, memberFxn )
afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );
ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )
可以用于处理一些标准的空间通知消息
当要处理用户自己定义的控件消息时必须用宏
ON_CONTROL(wNotifyCode, id, memberFxn)
ON_CONTROL_RANGE( wNotifyCode, id1, id2, memberFxn )
3相关宏的定义
/////////////////////////////////////////////////////////////////////////////
// Window message map handling
struct AFX_MSGMAP_ENTRY; // declared below after CWnd
struct AFX_MSGMAP
{
#ifdef _AFXDLL
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
#else
const AFX_MSGMAP* pBaseMap;
#endif
const AFX_MSGMAP_ENTRY* lpEntries;
};
#ifdef _AFXDLL
#define DECLARE_MESSAGE_MAP() /
private: /
static const AFX_MSGMAP_ENTRY _messageEntries[]; /
protected: /
static AFX_DATA const AFX_MSGMAP messageMap; /
static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); /
virtual const AFX_MSGMAP* GetMessageMap() const; /
#else
#define DECLARE_MESSAGE_MAP() /
private: /
static const AFX_MSGMAP_ENTRY _messageEntries[]; /
protected: /
static AFX_DATA const AFX_MSGMAP messageMap; /
virtual const AFX_MSGMAP* GetMessageMap() const; /
#endif
#ifdef _AFXDLL
#define BEGIN_MESSAGE_MAP(theClass, baseClass) /
const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() /
{ return &baseClass::messageMap; } /
const AFX_MSGMAP* theClass::GetMessageMap() const /
{ return &theClass::messageMap; } /
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = /
{ &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; /
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = /
{ /
#else
#define BEGIN_MESSAGE_MAP(theClass, baseClass) /
const AFX_MSGMAP* theClass::GetMessageMap() const /
{ return &theClass::messageMap; } /
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = /
{ &baseClass::messageMap, &theClass::_messageEntries[0] }; /
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = /
{ /
#endif
#define END_MESSAGE_MAP() /
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } /
}; /