如何强制clistctrl总是选择一个项目
How to force a CListCtrl to always have one item selected?
我希望一个clistctrl总是拥有选定的项目,例如收集按钮的集合。
我使用了样式:LVS_SHOWSELALWAYS|LVS_SINGLESEL
我一直在为此寻找一种样式,但找不到它。
处理wm_lbuttondown。在ClistCtrl衍生的类中,添加
mylistctrl.cpp:
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
void CMyListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
UINT uHitFlags;
int nItem = HitTest(point, &uHitFlags);
if (uHitFlags & LVHT_NOWHERE)
{
// eat the message by just returning
return;
}
CListCtrl::OnLButtonDown(nFlags, point);
}
这将防止鼠标点击进入控制并食用消息。您仍然可以通过编程方式删除选择,但是用户将无法单击项目下方的空白区域中的任何地方以删除选择。
我认为对此没有内置支持。
从一开始就选择选择的一部分很容易:只需在填充列表之后选择一个项目:
// Populate the list
// ...
c_MyList.SetItemState(nItem, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
另一部分是在用户单击所有项目外的所有项目时阻止所有项目的取消选择,这更棘手。您可以轻松地检测列表是否取消了项目,而不是为什么该项目丢失所选状态的原因。IE。您无法判断它是取消选择的选择,以选择另一个项目或将所有未选择的项目留下。原因是控件首先发送"项目X已被取消选择"通知,然后"选择了项目Y"通知。如果未选择项目,则获得第一个,但没有选择。
我想到的一个想法是捕获NM_CLICK通知并防止控件取消选择该项目。问题是 在所有选择/取消通知之后发送nm_click。
因此,这是我想到的小黑客:当项目失去所选状态时,存储其项目索引。然后在NM_Click通知中,如果激活的项目为-1,请再次选择最后未选择的项目:
void CMyDialog::OnLvnItemchangedListaEjesPane(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
if (pNMLV->uChanged & LVIF_STATE)
{
UINT oldSelectionState = (pNMLV->uOldState & LVIS_SELECTED);
UINT newSelectionState = (pNMLV->uNewState & LVIS_SELECTED);
if ( oldSelectionState == LVIS_SELECTED && newSelectionState == 0 )
{ // Deselect item
m_LastDeselectedItem = pNMLV->iItem;
}
// ...
}
*pResult = 0;
}
void CMyDialog::OnNMClickListaEjesPane(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
if (pNMItemActivate->iItem == -1)
{
c_ListaEjes.SetItemState(m_LastDeselectedItem, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
}
*pResult = 0;
}
它可能不完全适合您的需求,因为它实际上取消了该项目,然后再次选择它。
可能有更好的解决方案,涉及创建自己的clistctrl子类并拦截点击,检查它们是否要强制无效选择并防止它,但是您必须决定是否值得付出麻烦。
当您设计clistCtrl时,可以在对话框编辑器中完成此操作,在属性中设置"始终显示选择"answers"单个选择"选项。如果您想通过代码执行此操作,那么您有正确的方法,但可以使用错误的位置。首先将OnInitdialog覆盖,并在其中调用Cdialog :: Oninitdialog,然后在此之后设置新样式(使用modifyStyle)。问题是基类正在覆盖您的样式变化。除此之外,可能是一些事情,MFC并不以其直觉而闻名!
我解决了此问题,如下所示:
- 我添加对话框的新变量nate lastItem
-
处理lvn_itemchanging消息并添加此行:
lastItem = pNMLV->iItem;
-
处理NM_CLICK,NM_DBLCLK,NM_RCLICK和NM_RDBLCLK消息,并将这些行添加到所有消息中:
CListCtrl * listCtrl = (CListCtrl *)FromHandle(pNMHDR->hwndFrom); if (pNMItemActivate->iItem == -1) listCtrl->SetItemState(m_lastItem, LVIS_SELECTED, LVIS_SELECTED);
- 运行同一解决方案的另一个项目的项目
- 从链接列表c++中删除一个项目
- 仅从无序集合中删除一个项目
- 是否可以将 EXE 文件作为 lib 文件链接到另一个项目?
- 如何使用另一个项目命名空间?
- 如何在不创建新配置的情况下对两个不同解决方案使用的一个项目使用不同的 #defines
- 数组中无法解释的最后一个项目
- 单元测试类无法在我要测试的同一解决方案中的另一个项目中找到类
- 有没有更好的方法来检测向量中一个项目的多次出现?
- 是否有其他方法将.dll文件从一个项目复制到我的启动项目中的可执行文件旁边
- 如果我尝试将对话框从一个项目移动到另一个项目,我是否需要从 rc 文件中复制 DESIGNINFO、对话框信息和AFX_
- OpenCV:文件存储操作员">>"在一个项目中工作,但不在另一个项目中工作(在同一类上)
- 如何将另一个项目中用 C 编写的源代码包含在我自己的项目中,C++在 Visual Studio 中
- 什么 STL 算法可以确定容器中的一个项目是否满足谓词?
- 将过滤器中的所有.cpp和.h移动到另一个项目并更正其文件夹位置
- 在另一个项目中包括继承的类时,抽象类的链接器错误
- 创建在另一个项目中定义的类对象
- 我正在尝试在Eclipse中构建一个C 项目,但是即使在使用MINGW路径设置路径变量之后,也会获得构建错误
- 在包含相同项目的向量中删除一个项目
- 将多个原型文件包含在一个项目中会导致protobuf_AssignDescriptorsOnce()已经有一个主体