C++⾃定义ClistCtrl控件响应数据项的点击事件消息反射的原
理
ON_NOTIFY不反射消息.如果⾃⼰处理不了,就传给上级窗⼝,如果再处理不了,在往上传.实在处理不了,由框架默认处理.
ON_NOTIFY_REFLECT 反射消息.把消息传给上级窗⼝处理,如果上级都处理不了,再反射回来,⾃⼰处理.
这就是MFC强⼤的消息反射机制.如果上级窗⼝处理,则⼦窗⼝不处理;
为了项⽬的需要,往往需要编写⾃定义控件。当然,很多时候都是在现有控件的基础上进⾏扩展,在C++中可以⽤继承来解决。
那么,在MFC列表控件CListCtrl中,如何响应项(Item)的点击事件呢?
⾸先,在⾃定义控件类的头⽂件MyListCtrl.h中定义消息:祈使句的用法
protected:
/
/ ⽣成的消息映射函数
DECLARE_MESSAGE_MAP()
public:
hohoafx_msg void OnLvnClickListItem(NMHDR *pNMHDR, LRESULT *pResult);
其次,需要在源⽂件MyListCtrl.cpp中使⽤ ON_NOTIFY_REFLECT 声明响应消息:
BEGIN_MESSAGE_MAP(PicListCtrl, CListCtrl)
//}}AFX_MSG_MAP
ON_NOTIFY_REFLECT(NM_CLICK, OnLvnClickListItem)
END_MESSAGE_MAP()
有点头晕,先看看MSDN中是怎么定义的吧。
Map entry Function prototype
ON_CONTROL_REFLECT( wNotifyCode, memberFxn )afx_msg void memberFxn ( );
原来,是处理控件的点击事件(NM_CLICK),OnLvnClickListItem为响应的函数。
这种事件的响应当然包括控件中没有任何数据项的情况。
但我们只需要在控件中有数据项并且点击到项的时候才处理这些事件,那么就需要在MyListCtrl.cpp中判断⼀下了:
void MyListCtrl::OnLvnClickListItem(NMHDR *pNMHDR, LRESULT *pResult)
770是什么意思{
//强制转换
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
//判断点击的项个数
if(nItem>=0 && nItem<m_List.GetItemCount())
{
.............
//判断双击位置是否在有数据的列表项上⾯
}
//TODO: 在这⼉就可以放置项点击的处理代码了
}
ok,,⼤概就是这个思路了。
消息处理函数中的if语句很重要,⽤于判断双击位置是否在有数据的列表项上⾯。因为NM_DBLCLK消息是CListCtrl控件(整体)消息,只要是在CListCtrl控件范围之内执⾏此事件就会产⽣该消息,⽽不⼀定要在有数据的列表项上⾯。
放飞中国梦CListCtrl控件主要事件及LVN_ITEMCHANGED消息和⿏标双击列表项事件的处理
amelia earhartLVN_BEGINDRAG ⿏标左键正在被触发以便进⾏拖放操作(当⿏标左键开始拖拽列表视图控件中的项⽬时产⽣)
LVN_BEGINRDRAG ⿏标右键正在被触发以便进⾏拖放操作(当⿏标右键开始拖拽列表视图控件中的项⽬时产⽣)
LVN_BEGINLABELEDIT 开始编辑项的⽂本
LVN_COLUMNCLICK 单击列(当⿏标单击列表视图控件列标题时产⽣)
NM_CLICK 当⿏标单击列表视图控件时产⽣
LVN_COLUMNCLICK 单击列
LVN_DELETEALLITEMS 删除所有项
LVN_DELETEITEM 删除某个项
归去来兮翻译
NM_DBLCLK 当⿏标双击列表视图控件时产⽣
LVN_ENDLABELEDIT 结束对项⽂本的编辑
LVN_GETDISPINFO 请求需要显⽰的信息
LVN_GETINFOTIP 请求显⽰在⼯具提⽰窗⼝内的附加的⽂本信息
LVN_HOTTRACK ⿏标滑过某个项
LVN_INSERTITEM 当向列表视图控件插⼊项⽬时产⽣
lVN_ITEMACTIVATE 激活某个项
LVN_ITEMCHANGED 某个项已经发⽣变化
LVN_ITEMCHANGING 某个项⽬正在发⽣变化
LVN_ITEMCHANGING 某个项⽬正在发⽣变化
NM_KILLFOCUS 当视表列图控件失去焦点时产⽣
LVN_KEYDOWN 某个键被按下
LVN_MARQUEEBEGIN 开始某个边框选择
NM_OUTOFMEMORY 当内存溢出时产⽣
LVN_ODCACHEHINT 虚拟列表控件的显⽰区域的内容发⽣了变化
LVN_ODSTATECHANGED 虚拟列表的控件的某个项或某个范围内的项已经发⽣变化LVN_ODFINDITEM 需要拥有者查找⼀个特定的回调项
NM_RCLICK 当⿏标右键单击列表视图控件时产⽣
NM_RDBLCLK 当⿏标右键双击列表视图控件时产⽣
NM_SETFOCUS 当列表视图控件获得焦点时产⽣
LVN_SETDISPINFO ⽗窗⼝必须更新控件为项所维护的信息
注解:
早教英文儿歌
HDN:Header Notify
LVN:ListView control Notify
NM:Notify Message
TVN:TreeView control Notify
LVN_ITEMCHANGED消息的处理
消息处理函数:
void C***Dlg::OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult)
{
karate>语法结构NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if(pNMListView->uChanged==LVIF_STATE)
{
if(pNMListView->uNewState & LVIS_SELECTED)
{
//处理内容
int nItem=pNMListView->iItem;
CString value[6];
for(int i=0;i<6;i++)
{
value[i]=m_List.GetItemText(nItem,i);
}
}
}
*pResult = 0;
}
消息处理函数中的两个if条件句⼀定要有,否则可能出现多次进⼊处理内容的问题。
金山翻译在线