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

如何在WTL中获取子CListViewCtrl获得焦点的通知?

解决WTL中检测CListViewCtrl焦点状态的方法

首先纠正一个误区:LBN_SETFOCUS是**列表框(CListBox)**的通知消息,不适用于列表视图控件(CListViewCtrl)。列表视图的焦点变更通知是通过WM_NOTIFY消息发送的NM_SETFOCUS和NM_KILLFOCUS通知码,无需子类化控件或发送自定义消息,直接在父窗口中处理即可。

实现步骤

  1. 在父窗口的消息映射中添加NM_SETFOCUS和NM_KILLFOCUS的处理函数:
BEGIN_MSG_MAP(CYourParentWindow)
    // 保留原有其他消息映射
    NOTIFY_CODE_HANDLER(NM_SETFOCUS, OnListViewSetFocus)
    NOTIFY_CODE_HANDLER(NM_KILLFOCUS, OnListViewKillFocus)
END_MSG_MAP()
  1. 实现焦点变更的处理逻辑,通过pnmh->idFrom判断是哪个列表视图控件:
LRESULT OnListViewSetFocus(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    if (pnmh->idFrom == IDC_LIST_A) // 替换为你的列表A控件ID
    {
        // 处理列表A获得焦点的逻辑,比如标记当前激活列表为A
    }
    else if (pnmh->idFrom == IDC_LIST_B) // 替换为你的列表B控件ID
    {
        // 处理列表B获得焦点的逻辑,比如标记当前激活列表为B
    }
    return 0;
}

LRESULT OnListViewKillFocus(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    if (pnmh->idFrom == IDC_LIST_A)
    {
        // 可选:处理列表A失去焦点的逻辑
    }
    else if (pnmh->idFrom == IDC_LIST_B)
    {
        // 可选:处理列表B失去焦点的逻辑
    }
    return 0;
}

针对点击已选中项的场景

当你点击列表A中已选中的项时,虽然不会触发LVN_ITEMCHANGED,但列表A会重新获得焦点,此时NM_SETFOCUS通知会被触发,你可以通过这个通知来感知当前激活的列表是A,完美覆盖你提到的场景。

额外小技巧

如果只是在某个时刻需要判断当前哪个列表有焦点,也可以直接调用::GetFocus(),然后对比控件的HWND:

HWND hFocusWnd = ::GetFocus();
if (hFocusWnd == m_listA.m_hWnd)
{
    // 列表A处于激活状态
}
else if (hFocusWnd == m_listB.m_hWnd)
{
    // 列表B处于激活状态
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:09:58