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

在CDialogEx对话框中获取CListCtrl双击位置的异常问题

问题原因与解决办法

核心问题

你错误地将NM_DBLCLK通知的lParam强制转换为NMMOUSE结构了。在MFC中,CListCtrl发送的NM_DBLCLK通知对应的参数结构是**NMITEMACTIVATE**,而非NMMOUSE。强制类型转换导致坐标字段被错误解析,出现x值为0的异常。

解决步骤

  1. 替换结构类型:将NMMOUSE替换为NMITEMACTIVATE来解析lParam
  2. 获取行号的两种方式:
    • 直接从NMITEMACTIVATE的iItem成员获取双击的行号(推荐,更直接)
    • 如果需要用坐标做进一步判断,使用NMITEMACTIVATE中的ptAction字段作为双击坐标

修正后的代码示例

BOOL MyDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT *pResult)
{
    NMITEMACTIVATE* pActivate = reinterpret_cast<NMITEMACTIVATE*>(lParam);
    if (pActivate->hdr.idFrom == IDC_MYLIST && pActivate->hdr.code == NM_DBLCLK)
    {
        // 方式1:直接获取双击行号
        int iLine = pActivate->iItem;
        if (iLine != -1) // 确保点击在有效行上
        {
            // 处理双击逻辑
        }

        // 方式2:用坐标做HitTest(如果需要更精确的位置判断)
        CPoint cp(pActivate->ptAction);
        LVHITTESTINFO hitInfo;
        hitInfo.pt = cp;
        myListCtrl.ScreenToClient(&hitInfo.pt); // 转换为控件客户区坐标
        int hitLine = myListCtrl.HitTest(&hitInfo);
        if (hitLine != -1)
        {
            // 处理逻辑
        }

        *pResult = 0;
        return TRUE;
    }

    return CDialogEx::OnNotify(wParam, lParam, pResult);
}

补充说明

  • NMITEMACTIVATE的iItem会直接返回被双击的列表项索引,无需额外坐标转换,效率更高
  • 如果使用HitTest,记得将屏幕坐标转换为控件的客户区坐标,避免位置判断错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:30:10