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

子类化TListView:CNNotify中编辑取消时pszText值判断异常问题

解决TListView子类化中编辑取消时pszText判断无效的问题

问题背景

子类化TListView时,在CNNotify()事件中处理LVN_ENDLABELEDIT通知,预期编辑取消时plvdi->item.pszText应为NULL,但多次尝试判断均无效,其余功能正常。

代码问题分析

原代码存在以下关键错误:

  • 未过滤通知类型:所有WM_NOTIFY通知都被处理,错误访问非LVN_ENDLABELEDIT通知的结构数据。
  • 父类调用顺序错误:先调用TListView::Dispatch(&Message),导致父类提前修改了plvdi中的数据,无法正确获取取消编辑时的pszText值。
  • Result值设置错误:将Message.Result与LVN_ENDLABELEDIT(通知码)进行位或操作,不符合该通知的返回值规则。
  • 有效性检查缺失:未验证列表项的有效性,可能导致空指针访问。

修复后的代码

.cpp文件中修改CNNotify函数

void __fastcall TCustomListView1::CNNotify(Winapi::Messages::TWMNotify &Message)
{
    // 仅处理LVN_ENDLABELEDIT通知
    if (Message.NMHdr->code == LVN_ENDLABELEDIT)
    {
        NMLVDISPINFO* plvdi = reinterpret_cast<NMLVDISPINFO*>(Message.NMHdr);
        
        // 编辑取消时pszText为NULL,同时确保操作的是有效列表项
        if (plvdi->item.pszText == NULL && plvdi->item.iItem != -1)
        {
            TListItem* targetItem = Items->Item[plvdi->item.iItem];
            if (FOnEditCancel && targetItem != nullptr)
            {
                cancel = true;
                FOnEditCancel(this, targetItem, cancel);
                cancel = false;
            }
        }
    }

    // 最后调用父类处理其他通知逻辑
    TListView::Dispatch(&Message);
}

修复说明

  • 过滤通知类型:仅在收到LVN_ENDLABELEDIT时处理编辑结束逻辑,避免无效结构访问。
  • 调整父类调用顺序:先处理自定义逻辑,再调用父类Dispatch,确保能获取原始的通知数据。
  • 增加有效性验证:通过plvdi->item.iItem != -1确认列表项有效,避免空指针错误。
  • 移除错误的Result设置:原代码中Message.Result |= LVN_ENDLABELEDIT是错误用法,若需阻止控件默认处理编辑结果,可设置Message.Result = TRUE(非0值),否则由父类处理即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:25:27