ListBox选中项取消不了,BCG里的黑科技

本文介绍了一种在BCGControlBar环境下使用CBCGPListBox派生类实现通过鼠标单击空白处来取消ListBox选中项的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ListBox选中项取消不了,BCG里的黑科技

简介

用过MFC CListBox的都知道,列表框项一旦被选中,下一次想点击其空白处来取消该项的选择基本很难做到,因为CListBox会默认为把上一次选中的项作为当前的选项。
这里写图片描述
那么如何通过鼠标单击空白处来取消选择项呢?BCGControlBar给了我们最好的答案。

方法实现

1、首先需要重写继承自CBCGPListBox类,我们命名为CTextListBox

class CTextListBox : public CBCGPListBox
{...}

2、由于CBCGPListBox中的HitTest(…)函数是个保护成员函数,所以我们要在CTextListBox类中添加一个公有成员函数并对HitTest(…)值进行返回,-1表示没选中。

int CTextListBox::HitItemTest(CPoint point)
{
    return HitTest(point);
}

3、之后在对CTexListBox控件(对应的变量名命名为m_SubPro)所在的对话框进行SelectChange消息重写,来实现鼠标单击到某项被选中,单击到空白处被取消。

void CRobotSimSetupDlg::OnLbnSelchangeListSubpro()
{
    CPoint point;
    GetCursorPos(&point);
    m_SubPro.ScreenToClient(&point);

    int iHit = m_SubPro.HitItemTest(point);

    m_SubPro.SetCurSel(iHit);

}

4、这样就实现了我们所要的功能。

<think>好的,我现在需要在MFC取消ListBox选中状态。首先,根据用户提供的参考资料,特别是引用[4],面提到了使用SetItemState来设置列表选中状态。用户的问题是如何取消选中,所以可能需要将特定的状态设置为未选中。 用户提到在ListBox中没有直接的左键单击事件,所以他们自己扩展了CListBox类来处理这些事件。但问题是如何取消选中。引用[4]中的例子是针对ListCtrl的,但可能类似的方法可以应用于ListBox。 首先,我需要确认CListBox是否有类似SetItemState的方法。根据MFC文档,CListBox的SetCurSel方法可以设置当前选中,传入-1可以取消所有选中。例如: m_listbox.SetCurSel(-1); 这个方法可能有效,但需要测试。另外,引用[4]中的代码使用了SetItemState,但那是针对CListCtrl的。CListBox可能没有同样的方法,所以可能需要用其他方式。 如果SetCurSel(-1)不起作用,可能需要遍历所有并逐个取消选中。比如,对于每个,使用SetSel(index, FALSE)来取消选中。但ListBox的多选和单选模式可能不同,需要根据风格来判断。 另外,用户提到扩展了CListBox类来处理左键单击空白处取消选中,这可能涉及到处理鼠标消息,比如WM_LBUTTONDOWN,并检测点击的位置是否在列表之外,然后调用SetCurSel(-1)。 总结可能的解决方法: 1. 使用SetCurSel(-1)取消选中。 2. 遍历所有,使用SetSel(index, FALSE)取消多选状态。 3. 处理左键单击事件,当点击空白处时取消选中。 需要检查这些方法的适用性,并参考提供的引用资料中的示例代码,特别是引用[4]中的SetItemState的使用,但适应于ListBox的情况。</think>在MFC取消列表框控件`ListBox`的选中状态,可以通过以下方法实现: --- ### **方法一:使用`SetCurSel`函数** 对于**单选模式**的`ListBox`,直接调用`SetCurSel(-1)`即可取消所有选中: ```cpp m_listbox.SetCurSel(-1); // 将当前选中设置为-1(即无选中) ``` 这是最简洁的方式,适用于`LBS_SINGLE`(单选)风格的列表框[^4]。 --- ### **方法二:遍历并取消多选** 若列表框为**多选模式**(`LBS_MULTIPLESEL`),需遍历所有取消选中: ```cpp for (int i = 0; i < m_listbox.GetCount(); i++) { m_listbox.SetSel(i, FALSE); // 取消第i选中状态 } ``` 此方法通过`SetSel`逐个取消选中,适用于需要精确控制的情况[^4]。 --- ### **方法三:处理左键单击空白区域** 若需在点击空白区域时取消选中,需自定义`CListBox`子类并处理`WM_LBUTTONDOWN`消息: 1. **扩展`CListBox`类**: ```cpp class CMyListBox : public CListBox { afx_msg void OnLButtonDown(UINT nFlags, CPoint point) { // 检查点击位置是否在之外 BOOL bOutside; ItemFromPoint(point, bOutside); if (bOutside) { SetCurSel(-1); // 取消选中 } CListBox::OnLButtonDown(nFlags, point); } DECLARE_MESSAGE_MAP() }; ``` 2. **替换默认控件变量**: 在对话框类中将`ListBox`控件变量声明为`CMyListBox`类型。 此方法通过检测点击位置实现智能取消选中[^1]。 --- ### **关键注意事** 1. **控件风格**: - 单选模式(`LBS_SINGLE`)直接使用`SetCurSel(-1)`。 - 多选模式(`LBS_MULTIPLESEL`)需遍历或调用`SetSel(-1, FALSE)`取消所有选中[^3]。 2. **动态创建控件**: 若动态创建`ListBox`,需在`Create`函数中指定风格,例如: ```cpp m_listbox.Create(WS_CHILD | WS_VISIBLE | LBS_SINGLE, rect, this, IDC_LIST); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值