You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CListCtrl子类中接收LVN_MARQUEEBEGIN通知消息?

为什么CListCtrlEx收不到LVN_MARQUEEBEGIN通知?

你遇到的问题主要由三个原因导致:

  • 通知接收对象错误:LVN_MARQUEEBEGIN默认发送给ListView控件的父窗口,而非控件自身的OnNotify方法,所以直接在CListCtrlEx::OnNotify中无法捕获该通知。
  • 结构体类型错误:LVN_MARQUEEBEGIN对应的参数结构体是NMHDR,而非NMLISTVIEW,强制转换后无法正确获取通知代码,甚至可能引发内存访问问题。
  • 控件样式限制:如果ListView设置了LVS_SINGLESEL单选样式,拖选功能会被禁用,自然不会触发该通知。

解决方案

方案1:在父窗口中处理通知

在ListView所属的父窗口(如对话框、视图类)中添加消息映射和处理函数:

  1. 在父窗口的头文件中声明处理函数:
afx_msg void OnListMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult);
  1. 在父窗口的消息映射中添加:
BEGIN_MESSAGE_MAP(CYourParentClass, CParentBaseClass)
    // 替换IDC_YOUR_LISTCTRL为你的ListView控件ID
    ON_NOTIFY(LVN_MARQUEEBEGIN, IDC_YOUR_LISTCTRL, &CYourParentClass::OnListMarqueeBegin)
END_MESSAGE_MAP()
  1. 实现处理函数:
void CYourParentClass::OnListMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult)
{
    // 在这里编写拖选开始的处理逻辑
    *pResult = 0;
}

方案2:在CListCtrlEx内部通过消息反射处理

如果希望直接在控件类内部处理,使用MFC的消息反射机制:

  1. 在CListCtrlEx的头文件中添加函数声明:
afx_msg void OnMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult);
  1. 在CListCtrlEx的消息映射中添加反射宏:
BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
    ON_NOTIFY_REFLECT(LVN_MARQUEEBEGIN, &CListCtrlEx::OnMarqueeBegin)
END_MESSAGE_MAP()
  1. 实现处理函数:
void CListCtrlEx::OnMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult)
{
    // 在这里编写拖选开始的处理逻辑
    *pResult = 0;
}

额外注意事项

  • 检查并移除LVS_SINGLESEL样式(如果存在):
// 移除单选样式,启用多选拖选
SetStyle(GetStyle() & ~LVS_SINGLESEL);
  • 若需要更灵活的多选支持,可添加扩展样式:
SetExtendedStyle(GetExtendedStyle() | LVS_EX_MULTISELECT);

内容的提问来源于stack exchange,提问作者Li Lin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:00:34