CListCtrl 带复选框的问题
CListCtrl with checkboxes questions
列表控件在资源上被定义为单选。
问题 1
我想在 CListCtrl
第一列的 header 上有一个复选框。 OnInitDialog
我有
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
中添加它,它只会显示 header 的复选框,我绝对不想要这样,因为我希望检查操作和选择操作将用于不同的目的。
问题二
我需要设置一个布尔值并在用户选中或取消选中某个项目时将其标记为已修改。但是我不希望在插入项目时发生此操作,例如在加载表单时填充列表时,但它是在我无意的情况下触发的,因为 InsertItem
在 OnItemChanged
上触发 "a uncheck action" .
它迫使我用 m_is_inserting
成员标志来调节每个插入:
m_is_inserting = true;
m_list.InsertItem(i, m_array[i]->GetName());
m_is_inserting = false;
并对 LVN_ITEMCHANGED
处理程序做出相应反应
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;
}
是否有更好的方法来区分真实用户 check/uncheck 操作与 InsertItem
副作用?
问题 3
是否有更好的符号约定来获取 check/uncheck 状态?幻数 0x1000
和 0x2000
毫无意义!
提前致谢。
首先插入列 headers。然后更改HDF_CHECKBOX
。例如:
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
方法查看项目是否被选中。示例:
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);
}
}
列表控件在资源上被定义为单选。
问题 1
我想在 CListCtrl
第一列的 header 上有一个复选框。 OnInitDialog
我有
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
中添加它,它只会显示 header 的复选框,我绝对不想要这样,因为我希望检查操作和选择操作将用于不同的目的。
问题二
我需要设置一个布尔值并在用户选中或取消选中某个项目时将其标记为已修改。但是我不希望在插入项目时发生此操作,例如在加载表单时填充列表时,但它是在我无意的情况下触发的,因为 InsertItem
在 OnItemChanged
上触发 "a uncheck action" .
它迫使我用 m_is_inserting
成员标志来调节每个插入:
m_is_inserting = true;
m_list.InsertItem(i, m_array[i]->GetName());
m_is_inserting = false;
并对 LVN_ITEMCHANGED
处理程序做出相应反应
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;
}
是否有更好的方法来区分真实用户 check/uncheck 操作与 InsertItem
副作用?
问题 3
是否有更好的符号约定来获取 check/uncheck 状态?幻数 0x1000
和 0x2000
毫无意义!
提前致谢。
首先插入列 headers。然后更改HDF_CHECKBOX
。例如:
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
方法查看项目是否被选中。示例:
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);
}
}