DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
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 } /
    }; /
posted on   DoubleLi  阅读(759)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2012-04-27 js jsui框架收集整理
2012-04-27 再谈 document.documentElement 与 document.body 的 scrollWidth、offsetWidth、clientWidth
2012-04-27 offsetTop、offsetLeft、offsetWidth、offsetHeight原理使用介绍
2012-04-27 offsetLeft,Left,clientLeft的区别
2012-04-27 style.left,offsetLeft相对于容器的位置控制
2012-04-27 scrollTop、scrollLeft、scrollWidth、scrollHeight原理使用介绍
点击右上角即可分享
微信分享提示