详细解析支持主项可编辑的列表视图控件的代码

书籍:《Visual C++ 2017从入门到精通》的2.3.8 Win32控件编程

环境:visual studio 2022

内容:【例2.28】支持主项可编辑的列表视图控件

说明:以下内容大部分来自腾讯元宝。

创建列表视图

详细解析​双击某行返回行内容的列表视图控件​代码-CSDN博客https://blog.csdn.net/qq_20725221/article/details/146205016?spm=1001.2014.3001.5502

列表视图控件的标签编辑处理

/*  该代码实现了列表视图控件的标签编辑功能,通过捕获 LVN_BEGINLABEEDIT 和 LVN_ENDLABEEDIT 事件,
    结合全局变量 gbPreeEscKey 判断用户操作类型,最终更新或恢复列表项内容。
    处理列表视图控件(hListView)的标签编辑事件​(WM_NOTIFY),具体包括:
        ​开始编辑标签时​(LVN_BEGINLABELEDIT):保存原始文本内容。
        ​结束编辑标签时​(LVN_ENDLABEEDIT):根据用户操作(回车确认 / ESC取消)更新或恢复项文本*/
case WM_NOTIFY:
    /* 关键点:
        wParam 为通知标识符(此处假设10000是自定义通知码,通常由控件父窗口设置)。
        lParam 包含事件详细信息(LPNMHDR 结构指针)。*/
    if (10000 == wParam)
    {

        /*处理 LVN_BEGINLABELEDIT 事件
            ​功能:
            当用户点击列表项标签进入编辑模式时,保存当前文本到 strRaw,用于后续可能的取消操作恢复。
            ​关键函数:
            ListView_GetEditControl:获取正在编辑的标签控件的句柄。
            GetWindowText:复制编辑框内容到缓冲区。*/
        if (((LPNMHDR)lParam)->code == LVN_BEGINLABELEDIT)
        {
            hEdit = ListView_GetEditControl(hListView);     // 获取当前编辑的控件句柄
            GetWindowText(hEdit, strRaw, sizeof(strRaw));   // 保存原始文本到strRaw
        }

        /*处理 LVN_ENDLABEEDIT 事件
            ​核心逻辑:
            ​获取聚焦项索引:
            LVM_GETNEXTITEM 用于查找当前选中的项(LVNI_FOCUSED 标志)。
            若返回 - 1,表示无有效项,直接退出。
            ​更新或恢复文本:
            ​正常提交​(用户按回车):从编辑框读取新文本到 buf,调用 LVM_SETITEMTEXT 更新列表项。
            ​取消编辑​(用户按ESC):使用 strRaw 中的原始文本恢复,并重置 gbPreeEscKey。
            ​全局变量 gbPreeEscKey:
            用于标记用户是否按下ESC键(需在其他代码段中设置,例如键盘事件处理)。*/
        if (((LPNMHDR)lParam)->code == LVN_ENDLABELEDIT)
        {
            int iIndex = 0;
            TCHAR buf[255] = _T("");
            iIndex = SendMessage(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);     // 获取聚焦项索引

            if (-1 == iIndex)
            {
                break;              // 无有效项则退出
            }

            item.iSubItem = 0;      // 主项(非子项)

            if (!gbPreeEscKey)      // 用户未按ESC(正常提交)
            {
                item.pszText = buf;
                GetWindowText(hEdit, buf, sizeof(buf));         // 获取用户输入的新文本 
                SendMessage(hListView, LVM_SETITEMTEXT, (WPARAM)iIndex, (LPARAM)&item);     // 更新项文本
            }
            else                    // 用户按ESC(取消编辑)
            {
                item.pszText = strRaw;          // 使用原始文本恢复
                SendMessage(hListView, LVM_SETITEMTEXT, (WPARAM)iIndex, (LPARAM)&item);
                gbPreeEscKey = false;           // 重置标志
            }
        }
    }
    break;

主函数检测ESC按键

/*加速键处理
    关键点:
    TranslateAccelerator 检查消息 msg 是否匹配加速键表 hAccelTable 中的条目。
    ​返回值逻辑:
    ​** true:加速键已处理,消息被消耗,​不再分派** 。
    ​** false * *:无匹配加速键,继续执行后续代码。
    ​作用:确保快捷键(如 Ctrl + S)优先于普通按键处理。*/
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
    /*捕获 WM_KEYDOWN 事件
        功能:
        当用户按下 ​ESC键 且无加速键匹配时,设置全局变量 gbPreeEscKey 为 true。
        ​典型用途:标记用户意图取消操作(如关闭对话框、终止编辑)。*/
    if (msg.message == WM_KEYDOWN)
    {
        if (VK_ESCAPE == msg.wParam)
        {
            gbPreeEscKey = true;
        }
    }
    //翻译并分派消息,确保普通按键事件正常响应。
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

相关内容

详细解析 ListView_GetEditControl()-CSDN博客https://blog.csdn.net/qq_20725221/article/details/146228863?spm=1001.2014.3001.5502LVN_BEGINLABELEDIT和LVN_ENDLABELEDIT会在什么时候被触发?-CSDN博客https://blog.csdn.net/qq_20725221/article/details/146229127?spm=1001.2014.3001.5502详细解析GetWindowText()-CSDN博客https://blog.csdn.net/qq_20725221/article/details/146229364?sharetype=blogdetail&sharerId=146229364&sharerefer=PC&sharesource=qq_20725221&spm=1011.2480.3001.8118WM_NOTIFY 详解-CSDN博客https://blog.csdn.net/qq_20725221/article/details/146229622?sharetype=blogdetail&sharerId=146229622&sharerefer=PC&sharesource=qq_20725221&spm=1011.2480.3001.8118

你可能感兴趣的:(windows)