CListCtrl与复选框问题 [英] CListCtrl with checkboxes questions
问题描述
列表控件被定义为资源上的单选".
The List Control is defined as Single Selection on the resources.
问题1
我想在我的CListCtrl
第一列的标题上有一个复选框.在OnInitDialog
我有
I want to have a checkbox on the header of first column of my CListCtrl
. On the OnInitDialog
I have
m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
CString s;
s.LoadString(IDS_COLUMN1);
#ifndef HDS_CHECKBOXES
// Copied from Microsoft SDKs\Windows\v7.0A\Include\CommCtrl.h
#define HDS_CHECKBOXES 0x0400
#endif
CHeaderCtrl& header = *m_list.GetHeaderCtrl();
header.ModifyStyle(0, HDS_CHECKBOXES);
#ifndef HDF_CHECKBOX
// Copied from Microsoft SDKs\Windows\v7.0A\Include\CommCtrl.h
#define HDF_CHECKBOX 0x0040
#endif
LVCOLUMN lc = { 0 };
lc.mask = LVCF_FMT |LVCF_WIDTH |LVCF_TEXT | LVCF_SUBITEM;
lc.fmt |= HDF_CHECKBOX;
lc.cx = 96;
lc.pszText = (TCHAR*) (LPCTSTR)s;
m_list.InsertColumn(0, &lc);
仅当我添加扩展的|LVS_EX_AUTOCHECKSELECT
时,它才会显示标题的复选框,我绝对不希望这样做,因为我希望将检查动作和选择动作用于不同的目的.
It only presents the header's checkbox if I add in the extended |LVS_EX_AUTOCHECKSELECT
, which I definitely not want because I desire that checking action and selection action will be used for different purposes.
问题2
当用户选中或取消选中某项时,我需要设置一个布尔值并将其标记为已修改.但是我不希望在插入项目时(例如,在窗体加载时填充列表时)执行此操作,但是由于InsertItem
在OnItemChanged
上触发了取消选中的操作",因此我无意中触发了该操作.
I need to set a boolean and mark thing as modified when user checks or unchecks an item. But I don't want this action to occur when inserting items, for example when filling the list at form loading, but it is triggered without my intention, as InsertItem
triggers "a uncheck action" on OnItemChanged
.
我不得不用m_is_inserting
成员标志来对每个插入进行条件处理:
It obliged me to condition every insert with a m_is_inserting
member flag:
m_is_inserting = true;
m_list.InsertItem(i, m_array[i]->GetName());
m_is_inserting = false;
并在LVN_ITEMCHANGED
处理程序上做出相应反应
and react accordingly on the LVN_ITEMCHANGED
handler
void CMyDialog::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if (pNMListView->uChanged & LVIF_STATE)
{
if (pNMListView->uNewState & LVIS_SELECTED)
OnSelect();
else
{
if (pNMListView->iItem != -1)
{
if ((pNMListView->uNewState & LVIS_STATEIMAGEMASK) == 0x1000)
{
if (!m_is_inserting)
{
m_array[pNMListView->iItem]->m_active = false;
SetModified();
}
}
else if ((pNMListView->uNewState & LVIS_STATEIMAGEMASK) == 0x2000)
{
if (!m_is_inserting)
{
m_array[pNMListView->iItem]->m_active = true;
SetModified();
}
}
}
}
}
*pResult = 0;
}
是否有更好的方法将真实的用户检查/取消检查操作与InsertItem
副作用区分开来?
Is there a better way to distinguish a real user check/uncheck action from a InsertItem
side effect?
问题3
是否有更好的符号约定来获取检查/取消检查状态?魔术数字0x1000
和0x2000
毫无意义!
Is there a better symbolic convention for getting the check/uncheck state? Magic numbers 0x1000
and 0x2000
are pretty meaningless!
谢谢.
推荐答案
首先插入列标题.然后更改HDF_CHECKBOX
.例如:
Insert the column headers first. Then change the HDF_CHECKBOX
. For example:
m_list.SetExtendedStyle(LVS_EX_CHECKBOXES| LVS_EX_FULLROWSELECT);
CHeaderCtrl &header = *m_list.GetHeaderCtrl();
header.ModifyStyle(0, HDS_CHECKBOXES);
m_list.InsertColumn(0, L"Column0", 0, 120, 0);
m_list.InsertColumn(1, L"Column1", 0, 80, 1);
m_list.InsertColumn(2, L"Column2", 0, 80, 2);
HDITEM hdi = { 0 };
hdi.mask = HDI_FORMAT;
header.GetItem(0, &hdi);
hdi.fmt |= HDF_CHECKBOX;
header.SetItem(0, &hdi);
m_list.InsertItem(m_list.GetItemCount(), L"C0", 0);
m_list.InsertItem(m_list.GetItemCount(), L"C1", 0);
m_list.SetCheck(0, 1);
m_list.SetCheck(1, 1);
在处理通知时,可以使用GetCheck
方法查看是否选中了该项目.示例:
When handling the notification you can use the GetCheck
method to see if item is checked or not. Example:
if(pNMListView->uChanged & LVIF_STATE)
{
if(pNMListView->uNewState & LVIS_SELECTED)
{
...
}
else if(pNMListView->uNewState & LVIS_STATEIMAGEMASK && pNMListView->iItem >= 0)
{
if(m_list.GetCheck(pNMListView->iItem))
TRACE("%d checked\n", pNMListView->iItem);
}
}
这篇关于CListCtrl与复选框问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!