📄 subject_28570.htm
字号:
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:74LS373 回复日期:2003-01-23 10:21:29
<br>内容:ProcessShellCommand(cmdInfo)是做命令行参数解析,程序启动时的命令行一般是FileNew,ProcessShellCommand(cmdInfo)解析FileNew的结果是创建文档,文档创建后要判断框架窗口是否存在,不存在则要LoadFrame创建,LoadFrame先注册了一个回调函数WindowProc(通过AfxRegisterWndClass注册),再建一个WH_CBT的创建钩子_AfxCbtFilterHook(通过AfxHookWindowCreate建),再调用API CreateWindowEx创建窗口,发送WM_CREATE,WM_NCCREATE消息。<BR>_AfxCbtFilterHook我也没高清楚要做什么,估计是做一些过滤掉WM_CREATE,WM_NCCREATE等一些非HCBT_CREATEWND的消息吧。<BR>WindowProc就很清楚了,直接调用OnWndMsg或DefWindowProc。<BR>OnWndMsg中的主体是:<BR>switch (nSig)<BR> {<BR> default:<BR> ASSERT(FALSE);<BR> break;<BR><BR> case AfxSig_bD:<BR> lResult = (this->*mmf.pfn_bD)(CDC::FromHandle((HDC)wParam));<BR> break;<BR>...<BR><BR> case AfxSig_iwWw:<BR> lResult = (this->*mmf.pfn_iwWw)(LOWORD(wParam),<BR> CWnd::FromHandle((HWND)lParam), HIWORD(wParam));<BR> break;<BR><BR> case AfxSig_iww:<BR> lResult = (this->*mmf.pfn_iww)(LOWORD(wParam), HIWORD(wParam));<BR> break;<BR><BR> case AfxSig_iWww: // really AfxSig_iWiw<BR> lResult = (this->*mmf.pfn_iWww)(CWnd::FromHandle((HWND)wParam),<BR> (short)LOWORD(lParam), HIWORD(lParam));<BR> break;<BR><BR> case AfxSig_is:<BR> lResult = (this->*mmf.pfn_is)((LPTSTR)lParam);<BR> break;<BR><BR> case AfxSig_lwl:<BR> lResult = (this->*mmf.pfn_lwl)(wParam, lParam);<BR> break;<BR><BR> case AfxSig_lwwM:<BR> lResult = (this->*mmf.pfn_lwwM)((UINT)LOWORD(wParam),<BR> (UINT)HIWORD(wParam), (CMenu*)CMenu::FromHandle((HMENU)lParam));<BR> break;<BR><BR> case AfxSig_vv:<BR> (this->*mmf.pfn_vv)();<BR> break;<BR><BR> case AfxSig_vw: // AfxSig_vb, AfxSig_vh<BR> (this->*mmf.pfn_vw)(wParam);<BR> break;<BR><BR> case AfxSig_vww:<BR> (this->*mmf.pfn_vww)((UINT)wParam, (UINT)lParam);<BR> break;<BR><BR> case AfxSig_vvii:<BR> (this->*mmf.pfn_vvii)((short)LOWORD(lParam), (short)HIWORD(lParam));<BR> break;<BR><BR> case AfxSig_vwww:<BR> (this->*mmf.pfn_vwww)(wParam, LOWORD(lParam), HIWORD(lParam));<BR> break;<BR><BR> case AfxSig_vwii:<BR> (this->*mmf.pfn_vwii)(wParam, LOWORD(lParam), HIWORD(lParam));<BR> break;<BR><BR> case AfxSig_vwl:<BR> (this->*mmf.pfn_vwl)(wParam, lParam);<BR> break;<BR><BR> case AfxSig_vbWW:<BR> (this->*mmf.pfn_vbWW)(m_hWnd == (HWND)lParam,<BR> CWnd::FromHandle((HWND)lParam),<BR> CWnd::FromHandle((HWND)wParam));<BR> break;<BR><BR> case AfxSig_vD:<BR> (this->*mmf.pfn_vD)(CDC::FromHandle((HDC)wParam));<BR> break;<BR><BR> case AfxSig_vM:<BR> (this->*mmf.pfn_vM)(CMenu::FromHandle((HMENU)wParam));<BR> break;<BR><BR> case AfxSig_vMwb:<BR> (this->*mmf.pfn_vMwb)(CMenu::FromHandle((HMENU)wParam),<BR> LOWORD(lParam), (BOOL)HIWORD(lParam));<BR> break;<BR><BR> case AfxSig_vW:<BR> (this->*mmf.pfn_vW)(CWnd::FromHandle((HWND)wParam));<BR> break;<BR><BR> case AfxSig_vW2:<BR> (this->*mmf.pfn_vW)(CWnd::FromHandle((HWND)lParam));<BR> break;<BR><BR> case AfxSig_vWww:<BR> (this->*mmf.pfn_vWww)(CWnd::FromHandle((HWND)wParam), LOWORD(lParam),<BR> HIWORD(lParam));<BR> break;<BR><BR> case AfxSig_vWp:<BR> {<BR> CPoint point((DWORD)lParam);<BR> (this->*mmf.pfn_vWp)(CWnd::FromHandle((HWND)wParam), point);<BR> }<BR> break;<BR><BR> case AfxSig_vWh:<BR> (this->*mmf.pfn_vWh)(CWnd::FromHandle((HWND)wParam),<BR> (HANDLE)lParam);<BR> break;<BR><BR> case AfxSig_vwW:<BR> (this->*mmf.pfn_vwW)(wParam, CWnd::FromHandle((HWND)lParam));<BR> break;<BR><BR> case AfxSig_vwWb:<BR> (this->*mmf.pfn_vwWb)((UINT)(LOWORD(wParam)),<BR> CWnd::FromHandle((HWND)lParam), (BOOL)HIWORD(wParam));<BR> break;<BR>.......<BR> case AfxSig_vs:<BR> (this->*mmf.pfn_vs)((LPTSTR)lParam);<BR> break;<BR><BR> case AfxSig_vws:<BR> (this->*mmf.pfn_vws)((UINT) wParam, (LPCTSTR)lParam);<BR> break;<BR><BR> case AfxSig_vOWNER:<BR> (this->*mmf.pfn_vOWNER)((int)wParam, (LPTSTR)lParam);<BR> lResult = TRUE;<BR> break;<BR><BR> case AfxSig_iis:<BR> lResult = (this->*mmf.pfn_iis)((int)wParam, (LPTSTR)lParam);<BR> break;<BR><BR> case AfxSig_wp:<BR> {<BR> CPoint point((DWORD)lParam);<BR> lResult = (this->*mmf.pfn_wp)(point);<BR> }<BR> break;<BR><BR> case AfxSig_wv: // AfxSig_bv, AfxSig_wv<BR> lResult = (this->*mmf.pfn_wv)();<BR> break;<BR><BR> case AfxSig_vCALC:<BR> (this->*mmf.pfn_vCALC)((BOOL)wParam, (NCCALCSIZE_PARAMS*)lParam);<BR> break;<BR><BR> case AfxSig_vPOS:<BR> (this->*mmf.pfn_vPOS)((WINDOWPOS*)lParam);<BR> break;<BR><BR> case AfxSig_vwwh:<BR> (this->*mmf.pfn_vwwh)(LOWORD(wParam), HIWORD(wParam), (HANDLE)lParam);<BR> break;<BR><BR> case AfxSig_vwp:<BR> {<BR> CPoint point((DWORD)lParam);<BR> (this->*mmf.pfn_vwp)(wParam, point);<BR> break;<BR> }<BR> case AfxSig_vwSIZING:<BR> (this->*mmf.pfn_vwl)(wParam, lParam);<BR> lResult = TRUE;<BR> break;<BR><BR> case AfxSig_bwsp:<BR> lResult = (this->*mmf.pfn_bwsp)(LOWORD(wParam), (short) HIWORD(wParam),<BR> CPoint(LOWORD(lParam), HIWORD(lParam)));<BR> if (!lResult)<BR> return FALSE;<BR> }<BR>可见其中就是消息处理。WM_CREATE就是AfxSig_is,AfxMsg.h这样定义:<BR>#define ON_WM_CREATE() \<BR> { WM_CREATE, 0, 0, 0, AfxSig_is, \<BR> (AFX_PMSG)(AFX_PMSGW)(int (AFX_MSG_CALL CWnd::*)(LPCREATESTRUCT))&OnCreate },<BR>#define ON_WM_COPYDATA() \<BR> { WM_COPYDATA, 0, 0, 0, AfxSig_bWCDS, \<BR> (AFX_PMSG)(AFX_PMSGW)(BOOL (AFX_MSG_CALL CWnd::*)(CWnd*, COPYDATASTRUCT*))&OnCopyData },<BR>#define ON_WM_DESTROY() \<BR> { WM_DESTROY, 0, 0, 0, AfxSig_vv, \<BR> (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnDestroy },<BR>#define ON_WM_MOVE() \<BR> { WM_MOVE, 0, 0, 0, AfxSig_vvii, \<BR> (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(int, int))&OnMove },<BR>#define ON_WM_SIZE() \<BR> { WM_SIZE, 0, 0, 0, AfxSig_vwii, \<BR> (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, int, int))&OnSize },<BR>......<BR>可见,程序即使没走到Run(),就能通过注册的WindowProc处理消息了(WindowProc应该也算一种钩子吧),也就是说主窗口消息循环已经启动了(通过注册窗口类启动),而Run()并不是启动消息循环,而是将消息翻译派发到各自的窗口而已。<BR><BR>以上自己的理解,不晓得对不对。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-23 11:27:09
<br>内容:_AfxCbtFilterHook是要在窗口创建前一刻改掉wndproc和window class name,这是MFC4新加了,据说是为了支持3d controls!<BR><BR>我当问这个问题是就在想是不是这个HOOK造成的! 一直都还没把HOOK PROCR的代码拿来看! 等我看完了再来回贴吧<BR><BR>BTW<BR><BR>define ON_WM_CREATE() \<BR> { WM_CREATE, 0, 0, 0, AfxSig_is, \<BR> (AFX_PMSG)(AFX_PMSGW)(int (AFX_MSG_CALL CWnd::*)(LPCREATESTRUCT))&OnCreate },<BR>#define ON_WM_COPYDATA() \<BR> { WM_COPYDATA, 0, 0, 0, AfxSig_bWCDS, \<BR> (AFX_PMSG)(AFX_PMSGW)(BOOL (AFX_MSG_CALL CWnd::*)(CWnd*, COPYDATASTRUCT*))&OnCopyData },<BR>#define ON_WM_DESTROY() \<BR> { WM_DESTROY, 0, 0, 0, AfxSig_vv, \<BR> (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnDestroy },<BR>#define ON_WM_MOVE() \<BR> { WM_MOVE, 0, 0, 0, AfxSig_vvii, \<BR> (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(int, int))&OnMove },<BR>#define ON_WM_SIZE() \<BR> { WM_SIZE, 0, 0, 0, AfxSig_vwii, \<BR> (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, int, int))&OnSize },<BR><BR>这些东西就是用来构造MessageMap的一部分<BR><BR>MSG_ENTRIES<BR>----------------------------------------------------------<BR>|msg id |id |id |id |sign |fun |------>每条消息<BR>----------------------------------------------------------<BR>| | | | | | |<BR>----------------------------------------------------------<BR>| | | | | | |<BR>--------------------------------------------------------<BR>| | | | | | |<BR>---------------------------------------------------------<BR>|0 |0 |0 |0 |0 |0 |-------->表示结束<BR>----------------------------------------------------------<BR><BR><BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-23 20:31:13
<br>内容:<BR>我终于搞清楚了!<BR>Run()只是进入消息循环,就是说只是GetMessage->TranslateMessage->DispatchM<BR>essage,说白了,就是不让这个程序到达终点! <BR>而WM_CREATE由系统传到窗口,交给wndproc来处理,而此时的wndproc就是AfxWndProc而他会调用<BR><BR>AfxCallWndProc,就是在这个函数,调用了如下一条语句:pWnd->WindowProc(nMsg, wParam, lParam);,<BR><BR>让WM_CREATE消息进入了那一张巨大的网中去了(Message Maping & Routing)
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-23 20:33:50
<br>内容:谢谢! 结贴
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -