您的位置:首页 > 其它

091022(星期四)TreeCtrl的控件通知消息1 OnNotify

2009-10-22 21:34 288 查看

1022

回到SearchTool,双击IDC_TREE_SMBLIST,到调用生成的函数,栈图如下:

CDlgSmbList::OnDblclkTreeSmblist(tagNMHDR * 0x0013f2b0, long * 0x0013f014) line 449
_AfxDispatchCmdMsg(CCmdTarget * 0x0013fd50 {CDlgSmbList hWnd=0x00010878}, unsigned int 1025, int 65533, void (void)* 0x004012d0 CDlgSmbList::OnDblclkTreeSmblist(struct tagNMHDR *,long *), void * 0x0013ef2c, unsigned int 38, AFX_CMDHANDLERINFO * 0x00000000) line 118
CCmdTarget::OnCmdMsg(unsigned int 1025, int 65533, void * 0x0013ef2c, AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes
CDialog::OnCmdMsg(unsigned int 1025, int 5177341, void * 0x0013ef2c, AFX_CMDHANDLERINFO * 0x00000000) line 97 + 24 bytes
CWnd::OnNotify(unsigned int 1025, long 1307312, long * 0x0013f014) line 2125
CWnd::OnWndMsg(unsigned int 78, unsigned int 1025, long 1307312, long * 0x0013f058) CWnd::WindowProc(unsigned int 78, unsigned int 1025, long 1307312) line 1596 + 30 bytes
AfxCallWndProc() line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00010878, unsigned int 78, unsigned int 1025, long 1307312) line 379
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d1b89b()
USER32! 77d1b903()
COMCTL32! 5d176751()
COMCTL32! 5d1c993c()
COMCTL32! 5d189bc6()
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d1c63f()
USER32! 77d1f65d()
CWnd::DefWindowProcA(unsigned int 515, unsigned int 1, long 3014737) line 1011 + 32 bytes
CWnd::WindowProc(unsigned int 515, unsigned int 1, long 3014737) line 1597 + 26 bytes
AfxCallWndProc(CWnd * 0x0013fe2c {CTreeCtrl hWnd=0x0001087a}, HWND__ * 0x0001087a, unsigned int 515, unsigned int 1, long 3014737) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x0001087a, unsigned int 515, unsigned int 1, long 3014737) line 379
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d189cd()
USER32! 77d18a10()
USER32! 77d2d99d()
USER32! 77d3c69b()
CWnd::IsDialogMessageA(tagMSG * 0x0064be8c {msg=0x00000203 wp=0x00000001 lp=0x002e0051}) line 182
CWnd::PreTranslateInput(tagMSG * 0x0064be8c {msg=0x00000203 wp=0x00000001 lp=0x002e0051}) line 3435
CDialog::PreTranslateMessage(tagMSG * 0x0064be8c {msg=0x00000203 wp=0x00000001 lp=0x002e0051}) line 92
CWnd::WalkPreTranslateTree(HWND__ * 0x000c0376, tagMSG * 0x0064be8c {msg=0x00000203 wp=0x00000001 lp=0x002e0051}) line 2678 + 18 bytes
CWinThread::PreTranslateMessage(tagMSG * 0x0064be8c {msg=0x00000203 wp=0x00000001 lp=0x002e0051}) line 672 + 18 bytes
CWinThread::PumpMessage() line 848 + 30 bytes
CWnd::RunModalLoop(unsigned long 4) line 3489 + 19 bytes
CDialog::DoModal() line 539 + 12 bytes
CIntelligentFtpApp::InitInstance() line 65 + 11 bytes
AfxWinMain() line 39 + 11 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f26, int 1) line 30
WinMainCRTStartup() line 198 + 54 bytes
KERNEL32! 7c816fd7()

这个栈图大有学问,MFC对话框消息处理的很多策略都浓缩在这里面,一点一点来熟悉。
首先关注OnNotiy函数,如果要去掉“展开/合起”TreeItem的功能,就要控制这块的功能代码不被调用。
1, OnNotiy函数被调用的上下文:在OnWndMsg中调用,10月17号的描述。
OnWndMsg()
该函数的功能首先按字节对消息进行排序,对于WM_COMMAND消息,调用OnCommand()消息响应函数,对于WM_NOTIFY消息调用OnNotify()消息响应函数。OnWndMsg()函数搜 索类的消息映像,以找到一个能处理任何窗口消息的处理函数。如果OnWndMsg()函数不能找到这样的处理函数的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数。

2,OnNotify源码
BOOL CWnd::OnNotify(WPARAM, LPARAM lParam, LRESULT* pResult)
{
NMHDR* pNMHDR = (NMHDR*)lParam;
HWND hWndCtrl = pNMHDR->hwndFrom;
// get the child ID from the window itself
UINT nID = _AfxGetDlgCtrlID(hWndCtrl);
int nCode = pNMHDR->code;
if (_afxThreadState->m_hLockoutNotifyWindow == m_hWnd)
return TRUE; // locked out - ignore control notification
// reflect notification to child window control
if (ReflectLastMsg(hWndCtrl, pResult))
return TRUE; // eaten by child
AFX_NOTIFY notify;
notify.pResult = pResult;
notify.pNMHDR = pNMHDR;
return OnCmdMsg(nID, MAKELONG(nCode, WM_NOTIFY), ¬ify, NULL);
}

3,msdn描述
The framework calls this member function to inform the parent window of a control that an event has occurred in the control通知控件的父亲窗口:这个控件上发生了一个事件 or that the control requires some kind of information.
virtual BOOL OnNotify(
WPARAM wParam,
LPARAM lParam,
LRESULT* pResult
);
Parameters
wParam
Identifies the control that sends the message if the message is from a control. Otherwise, wParam is 0.
lParam
Pointer to a notification message (NMHDR) structure that contains the notification code and additional information. For some notification messages, this parameter points to a larger structure that has the NMHDR structure as its first member.
pResult
Pointer to an LRESULT variable in which to store the result code if the message is handled.
Return Value
An application returns nonzero if it processes this message; otherwise 0.

Remarks
OnNotify processes the message map for control notification.处理控件的通知消息。
Override this member function in your derived class to handle the WM_NOTIFY message. An override will not process the message map unless the base class OnNotify is called重要!!如果要处理自己的逻辑,可以override OnNotify函数,如果是在默认基础上的增量,可以先显式调用CWnd::OnNotify函数。
For more information on the WM_NOTIFY message, see Technical Note 61 (TN061), ON_NOTIFY and WM_NOTIFY messages. You may also be interested the related topics described in Control Topics, and TN062, Message Reflection for Windows Controls.更详尽的信息可以继续在msdn中获取。

4、ReflectLastMsg默认展开/合起 Item
BOOL PASCAL CWnd::ReflectLastMsg(HWND hWndChild, LRESULT* pResult)
{
// get the map, and if no map, then this message does not need reflection
CHandleMap* pMap = afxMapHWND();
if (pMap == NULL)
return FALSE;

// check if in permanent map, if it is reflect it (could be OLE control)
CWnd* pWnd = (CWnd*)pMap->LookupPermanent(hWndChild);
ASSERT(pWnd == NULL || pWnd->m_hWnd == hWndChild);
if (pWnd == NULL)
{
#ifndef _AFX_NO_OCC_SUPPORT
// check if the window is an OLE control
CWnd* pWndParent = (CWnd*)pMap->LookupPermanent(::GetParent(hWndChild));
if (pWndParent != NULL && pWndParent->m_pCtrlCont != NULL)
{
// If a matching control site exists, it's an OLE control
COleControlSite* pSite = (COleControlSite*)pWndParent->
m_pCtrlCont->m_siteMap.GetValueAt(hWndChild);
if (pSite != NULL)
{
CWnd wndTemp(hWndChild);
wndTemp.m_pCtrlSite = pSite;
LRESULT lResult = wndTemp.SendChildNotifyLastMsg(pResult);
wndTemp.m_hWnd = NULL;
return lResult;
}
}
#endif //!_AFX_NO_OCC_SUPPORT
return FALSE;
}

// only OLE controls and permanent windows will get reflected msgs
ASSERT(pWnd != NULL);
return pWnd->SendChildNotifyLastMsg(pResult);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: