本文主要是介绍关于TreeView控件-改进版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【原文写于2005年3月12日15:36星期六,注】
关于TreeView控件-改进版
上一篇的《关于TreeView控件》中存在许多问题。其中最突出的是由于在CMyTreeCtrl中不能捕获WM_LBUTTONUP而导致
改进版解决了这个问题。其主要思想是不再直接捕获鼠标事件,而是捕获控件notify
WM_NOTIFY是控件发给父窗口的“通知”消息,利用Windows的“消息反射(Message Reflection)”机制,能够将WM_NOTIFY返回给自己,同时决定该WM_NOTIFY是否再发给父窗口
具体实现:
代码 |
.h afx_msg BOOL OnClick(NMHDR* pNMHDR, LRESULT* pResult); .cpp ON_NOTIFY_REFLECT_EX(NM_CLICK, OnClick) BOOL CMyTreeCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here CPoint pt(::GetMessagePos()) ; ::MapWindowPoints(HWND_DESKTOP, GetSafeHwnd(), &pt, 1); TVHITTESTINFO tvHitInfo = { pt.x, pt.y } ; HitTest(&tvHitInfo) ; if (tvHitInfo.flags & TVHT_ONITEMSTATEICON) GetParent()->PostMessage(UM_CHECKSTATECHANGE, WPARAM(GetDlgCtrlID()), LPARAM(tvHitInfo.hItem)) ; *pResult = 0; return FALSE ; } |
OnClick负责处理TreeView控件消息NM_CLICK
最后return FALSE表示NM_CLICK依然发给父窗口
其它细节请参考上一篇的 《关于TreeView控件》
改进后,CMyTreeCtrl不再出现原来处理WM_LBUTTONDOWN导致的问题,父窗口处理UM_CHECKSTATECHANGE时也不必再采用相反的逻辑
改进后,与MSDN的做法一样,需要GetMessagePos()和MapWindowPoints(),但是我觉得,MSDN的做法,对话框(或父窗口)与TreeView控件间耦合太紧。如果上述的CMyTreeCtrl再完善一下封装,能实现一个真正的支持“CheckNotify”的TreeView控件
这篇关于关于TreeView控件-改进版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!