posts - 1, comments - 3, trackbacks - 0, articles - 0

2010年4月11日

最近在做个小例子,在对话框中放了一个CListCtrl,为CListCtrl增加了双击消息的处理,也在对话框中增加了这个CListCtrl的双击消息处理,这时问题出现了,我发现每次在对话框和CListCtrl中只有一个能收到鼠标的双击消息,而且CListCtrl优先。如果既想让CListCtrl来处理它的内部事务,也想通知到对话框,“CListCtrl有双击消息了!”,怎么办呢?
先看VS2008中自动生成的对话框的双击消息:
1 ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CTemp07Dlg::OnNMDblclkList1)
2 
3 void CTemp07Dlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
4 {
5     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<NMITEMACTIVATE>(pNMHDR);
6     AfxMessageBox(_T("CTemp07Dlg::OnNMDblclkList1"));
7     *pResult = 0;
8 }

还有CLList继承于CListCtrl中的双击消息:
1 ON_NOTIFY_REFLECT(NM_DBLCLK, &CLList::OnNMDblclk)
2 
3 void CLList::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
4 {
5     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<NMITEMACTIVATE>(pNMHDR);
6     AfxMessageBox(_T("CLList::OnNMDblclk"));
7     *pResult = 0;
8 }

我的目的就是,先弹出一个“CLList::OnNMDblclk”的对话框,再弹出一个“CTemp07Dlg::OnNMDblclkList1”的对话框,这样的要求很过分吗?
于是,打开网页搜索,搜索了一圈,终于发现一个有用的信息:
对于一个控件来说,比如一个listctrl,当DBCLICK发生时,如果有WM_DBCLICK处理程序,则该函数处理,其他包括 NM_**,NM_**_REFLECT都没有机会处理,如果没有WM_DBCLICK,则REFLECT处理,若没有REFLECT映射,则NM_才有机会处理。其中,REFLECT有包括REFLECT_EX,它可以通过返回值决定是否给NM_处理机会。

原来,ON_NOTIFY_REFLECT这个宏太自私,不懂得分享!好了,在你后面加个_EX,再把函数CLList::OnNMDblclk改一下,变成这样:
1 ON_NOTIFY_REFLECT_EX(NM_DBLCLK, &CLList::OnNMDblclk)
2 
3 BOOL CLList::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
4 {
5     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<NMITEMACTIVATE>(pNMHDR);
6     AfxMessageBox(_T("CLList::OnNMDblclk"));
7     // TRUE表示不让上级处理了,FALSE给别人处理的机会
8     return FALSE;
9 }

好了,好东西就是这样分享的嘛

posted @ 2010-04-11 16:31 vk 阅读(2957) | 评论 (3)编辑 收藏