首页 精选版块

移动开发

iOS Android Qt WP

云计算

IaaS Pass/SaaS 分布式计算/Hadoop

Java技术

Java SE Java Web 开发 Java EE Java其他相关

.NET技术

.NET Framework C# .NET分析与设计 ASP .NET VB .NET

Web开发

PHP JavaScript ASP HTML(CSS) HTML5 Apache

开发语言/框架

Delphi VC/MFC VB C/C++ C++ Builder 其他开发语言

数据库开发

MS-SQL Server Oracle PowerBuilder Informatica 其他数据库开发

硬件/嵌入式开发

嵌入开发(WinCE) 驱动开发/核心开发 硬件设计 单片机/工控汇编语言 VxWorks开发

Linux/Unix社区

系统维护与使用区 应用程序开发区 内核源代码研究区 驱动程序开发区 CPU和硬件区

论坛帮助论坛牛人 论坛地图专家问答

<< >>

CSDN > CSDN论坛 > VC/MFC > 基础类

返回列表

管理菜单

置顶

推荐

锁定

移动

编辑

删除

帖子加分

帖子高亮

结帖

发帖

回复

关注

sunceenjoy

关于MFC的(AFX_PMSG)(AFX_PMSGW)转换的请教 [问题点数：10分，结帖人sunceenjoy]

快速回复只显示楼主关注帖子

不显示删除回复

显示所有回复

显示星级回复

显示得分回复

只显示楼主
收藏

取消关注

关注

sunceenjoy

sunceenjoy

本版等级：

本版专家分：97

结帖率：100%

楼主发表于： 2009-06-18 10:46:14

在MFC里面
typedef void (AFX_MSG_CALL CWnd::*AFX_PMSGW)(void);
typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);

#define ON_WM_LBUTTONDOWN() \
{ WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp, \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > ( &ThisClass :: OnLButtonDown)) },

OnLButtonDown是成员函数指针，有2个参数，先是转换成了 void (AFX_MSG_CALL CWnd::*)(UINT, CPoint),这不难理解.
但之后又转成了(AFX_PMSG)(AFX_PMSGW) 这里这2个都是无参数的转换，难道就真的这样转了吗，那参数怎么调用？？

更多分享到：

对我有用[0] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理
回复次数：8

取消关注

关注

jian_tian_yang

jian_tian_yang

本版等级：

本版专家分：2609

结帖率：100%

#1 得分：1 回复于： 2009-06-18 12:32:33

帮楼主顶一下

对我有用[0] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理

取消关注

关注

sunceenjoy

sunceenjoy

本版等级：

本版专家分：97

结帖率：100%

#2 得分：0 回复于： 2009-06-19 09:24:59

有人知道吗？？

对我有用[1] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理

取消关注

关注

PRCLionel

PRCLionel

本版等级：

本版专家分：912

结帖率：100%

#3 得分：9 回复于： 2009-06-19 09:47:06

楼主这个问题问的很有水平，原因是这样的。
MFC在处理消息的时候，是用一个大数组将消息与消息响应函数对应起来的

BEGIN_MESSAGE_MAP(CTestCastingDlg, CDialog)

//{{AFX_MSG_MAP(CTestCastingDlg)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

数组中每一个元素都是一个AFX_MSGMAP_ENTRY类型的结构，这一点我们可以从BEGIN_MESSAGE_MAP宏定义看出

#define BEGIN_MESSAGE_MAP(theClass, baseClass) \

......

AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \

{ \

其中AFX_MSGMAP_ENTRY结构体的定义如下

typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);

struct AFX_MSGMAP_ENTRY

{

UINT nMessage;   // windows message

UINT nCode;      // control code or WM_NOTIFY code

UINT nID;        // control ID (or 0 for windows messages)

UINT nLastID;    // used for entries specifying a range of control id's

UINT nSig;       // signature type (action) or pointer to message #

AFX_PMSG pfn;    // routine to call (or special value)

};

正是由于这个结构体中最后一个成员类型是AFX_PMSG，所以所有消息处理函数不管是有没有参数的，参数是什么类型的，最终都要转换为AFX_PMSG才能保存到结构体中。

这样问题就出来了，既然AFX_PMSG函数指针时没有参数的，那对于ON_WM_LBUTTONDOWN这种有参数的函数参数怎么办呢？转换完参数怎么传递呢？

这正是上述结构体中nSig成员发挥其作用的时刻。MFC把所有可能的消息处理函数按照参数及返回值的不同，定义了好多常量，例如ON_WM_LBUTTONDOWN，其中nSig = AfxSig_vwp，意思是该函数返回值是void，第一个参数是WPARAM，第二个参数是CPoint。

#define ON_WM_LBUTTONDOWN() \

{ WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp, \

(AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))&OnLButtonDown },

这样在OnWndMsg进行消息转发的时候，就可以调用正确的消息处理函数了。

case AfxSig_vwp:

{

CPoint point((DWORD)lParam);

(this->*mmf.pfn_vwp)(wParam, point);

break;

}

简单的说，就是ON_WM_LBUTTONDOWN()宏会将一个有特定参数的函数转换成AFX_PMSG，并且将这个有特定参数函数的唯一标示AfxSig_vwp也保存起来，等使用的时候，通过该表示，将AFX_PMSG类型的函数指针还原成真正的函数，然后再调用。

对我有用[1] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理

取消关注

关注

VisualEleven

VisualEleven

本版等级：

本版专家分：353929

结帖率：100%

名人2013年 荣获名人称号

探花2011年 总版技术专家分年内排行榜第三
2010年 总版技术专家分年内排行榜第三

进士2012年 总版技术专家分年内排行榜第五

更多勋章

#4 得分：0 回复于： 2009-06-19 09:53:33

MFC深入浅出可以回答你的问题

对我有用[0] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理

取消关注

关注

youzhipeng

youzhipeng

本版等级：

本版专家分：69

结帖率：73.33%

#5 得分：0 回复于： 2009-06-19 10:18:01

Up! MFC非同小可。

对我有用[0] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理

取消关注

关注

sunceenjoy

sunceenjoy

本版等级：

本版专家分：97

结帖率：100%

#6 得分：0 回复于： 2009-06-19 16:50:19

3楼的解释 真是 醍醐灌顶 ，让我彻底明白了：先是转过来，方便存储，然后用的时候再转回去

才学mfc,多谢你，PRCLionel

对我有用[0] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理

取消关注

关注

wwwhhb4001

wwwhhb4001

本版等级：

本版专家分：133

结帖率：100%

#7 得分：0 回复于： 2009-06-19 16:54:03

问的牛，答的更牛

对我有用[0] 丢个板砖[0] 引用 | 举报 |
编辑 删除
管理

取消关注

关注

mylanyuer

mylanyuer

本版等级：

本版专家分：618

结帖率：100%

#8 得分：0 回复于： 2011-05-03 08:51:29

该回复于2011-05-03 09:36:50被版主删除

编辑 删除
管理

返回列表

管理菜单

置顶

推荐

锁定

移动

编辑

删除

帖子加分

帖子高亮

结帖

发帖

回复

关注

博客专家带你学swift

晒图谱，涨知识，得好礼

Swift 问题与解答

视频直播技术免费课

本帖子已过去太久远了，不再提供回复功能。

关闭