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

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中调用,1017号的描述。

OnWndMsg()       

该函数的功能首先按字节对消息进行排序,对于WM_COMMAND消息,调用OnCommand()消息响应函数,对于WM_NOTIFY消息调用OnNotify()消息响应函数。OnWndMsg()函数搜                    索类的消息映像,以找到一个能处理任何窗口消息的处理函数。如果OnWndMsg()函数不能找到这样的处理函数的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数。

 

2OnNotify源码

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), &notify, NULL);

}

 

3msdn描述

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中获取。

 

4ReflectLastMsg默认展开/合起 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);

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值