我试图禁用用户更改列表控件中复选框状态的能力。我目前正在务实地改变状态。我已经处理了该LVN_ITEMCHANGED
消息,并且由于程序其余部分的布局,尝试更改状态没有选项。我还尝试在用户单击列表控件并简单地重置那里的复选框时进行 HitTest,但这并没有给我我正在寻找的确切结果。
当用户单击复选框本身时,是否发送了特定消息或我可以覆盖的功能?我只想覆盖处理程序或捕获消息,以便它不会去任何地方。
我试图禁用用户更改列表控件中复选框状态的能力。我目前正在务实地改变状态。我已经处理了该LVN_ITEMCHANGED
消息,并且由于程序其余部分的布局,尝试更改状态没有选项。我还尝试在用户单击列表控件并简单地重置那里的复选框时进行 HitTest,但这并没有给我我正在寻找的确切结果。
当用户单击复选框本身时,是否发送了特定消息或我可以覆盖的功能?我只想覆盖处理程序或捕获消息,以便它不会去任何地方。
解决方案:
我最终删除了LVS_EX_CHECKBOXES
标志并创建了自己的实现。这样,只有一种方法可以更改图标。阅读上一个问题的链接给了我一个设置“忙碌”标志的想法,否则我会收到堆栈溢出错误。
// In my dialog class
m_CListCtrl.SetImageList(&m_ImgList, LVSIL_SMALL); // Custom checkboxes (only two images)
// ...
void CMyDialog::OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult)
{
if(busy) { return; }
// ....
}
// When calling the SetCheck function:
busy = TRUE; // Avoid stack overflow errors
m_CListCtrl.SetCheck(index, fCheck);
busy = FALSE;
// I derived a class from CListCtrl and did an override on the get/set check:
class CCustomListCtrl : public CListCtrl
{
BOOL CCustomListCtrl::SetCheck(int nItem, BOOL fCheck)
{
TCHAR szBuf[1024];
DWORD ccBuf(1024);
LVITEM lvi;
lvi.iItem = nItem;
lvi.iSubItem = 0;
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
lvi.pszText = szBuf;
lvi.cchTextMax = ccBuf;
GetItem(&lvi);
lvi.iImage = (int)fCheck;
SetItem(&lvi);
return TRUE;
}
// Just need to determine which image is set in the list control for the item
BOOL CCustomListCtrl::GetCheck(int nItem)
{
LVITEM lvi;
lvi.iItem = nItem;
lvi.iSubItem = 0;
lvi.mask = LVIF_IMAGE;
GetItem(&lvi);
return (BOOL)(lvi.iImage);
}
}
这并不像我希望的那样优雅,但它完美无瑕。