VC初学,关于WM_XXX消息映射的疑问
在学习<深入浅出MFC>的消息映射
书中说得到一个非WM_COMMAND(就是系统消息)消息就直接向基类传递,并比较消息映射表.如果和消息处理函数匹配就进行处理.
我的问题是,消息映射表并不是单一继承下来的而是有4个分支的.MFC如何知道该从CMYAPP CMYVIEW CMYFRAMWND CMYDOCUMENT中的特定一个开始这个匹配过程的?
而且,它能保证选定了一条线路后就一定能找到那个处理函数吗?因为书上的意思好象就是一定可以找到的.
简单地说,我不知道系统捕获一个此类消息后如何确定在消息映射表匹配路线的起点.一旦选定,为什么在这条路线上一定能匹配到它所要的消息处理函数呢?
而且一个WM_COMMAND消息的匹配起点如何确定我也很困惑,只知道所有的支路它都比较了一次.
希望大家帮我解惑
也不知自己表达地是否清楚.
先谢谢大家啦!!!!
问题点数:100、回复次数:2Top
1 楼smilingdeng(笑笑的邓冲)回复于 2003-02-03 18:46:30 得分 15
太难回答你了,我当时看到这里的时候也看了N遍才看懂。你再好好把《深入浅出MFC》这本收关于消息映射这一章好好的看一次。你只要理解一点消息是由WINDOWS管理与产生的只要注重你产生消息的着力点就行了,若要想再知详情我建议你去看看《WINDOWS核心编程》这本书,最后一章专门讲这个问题的。Top
2 楼deerchao(不跨浏览器/不符合标准不考虑)回复于 2003-02-03 19:58:26 得分 85
<<以下所说简体第二版>>
\\\MFC程序基本上运行在CWinThread::Run()里,在那里当GetkMessage()取得了消息了以后,调用::DispatchMessage()(293页),
\\\把消息发给AfxWndProc(),后者调用AfxCallWndProc()(421页),
\\\在这里,MFC跟据消息中的HWND,找出负责处理此消息的窗口(也就是说,所有消息的处理----无论是否WM_COMMAND消息----涉及的第一个类,肯定是CWnd类或其派生类),并调用此窗口对应的CWnd(或其派生类)对象的CWnd::WindProc(),(至此,处理消息的窗口已经确定,以后各函数间传递的消息参数中就不再有HWND),CWnd::WndProc()调用CWnd::OnWndMsg()(422页);
\\\\\\\\\\\在这里,如果不是WM_COMMAND消息(下面称一般的消息)的话,就定义一个pMessageMap = GetMessageMap()(这是一个virtual method,返回当前对象----就是前边的由HWND确定的对象,现在运行在它的WndProc里----的MessageMap pointer(处理消息的源头就此找到),然后从这里出发,向基类查找Message Handler,如果找到了,就调用对应的函数,如果没找到,将会什么也不发生(至少我的理解是这样:-).(可以看到,一般的消息是没有机会流窜到CWinApp,CDocument类中(因为CWnd类或其派生类不是从这些类派生的,消息沿直线上溯是到不了那里的)(423-434页)。
\\\\\\\\\\\如果是WM_COMMAND消息,CWnd::OnWndMsg()调用OnCommand();不同对象的OnCommand()最后又调用了CWnd::OnCommand();它接着调用当前对象的OnCmdMsg();(426-427页)
\\\\\\\\\\\\\\\\\\\\如果当前对象是CView类的,那么CView::OnCmdMsg()先查找自己的MessageMap(这里就是这种情况下的匹配起点),
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\如找到。。。
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\如找不到,则调用其对应的CDocument对象的OnCmdMsg()让它找文档类的MessageMap
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\如找到。。。
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\如找不到,则返回到\\\\\\\\\\\\\\\\\\\\\\\\\\\\\CView::OnCmdMsg(),后者也只得返回。(428页)
\\\\\\\\\\\\\\\\\\\\如果当前对象是CFrameWnd,那么CFrameWnd::OnCmdMsg()先调用当前的CView对象的OnCmdMsg()(过程如上所述),
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\如果CView及CDoc均未处理此消息,则\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\CFrameWnd::OnCmdMsg()查找自己的MessageMap,
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\若还是找不到就调用CWinApp的OnCmdMsg()。(427-429页)
大哥,多给几分吧,费了好半天工夫!Top




