MFC ListView Control: How CListCtrl notifies "checkbox status changed"?
Q: How CListCtrl having LVS_REPORT and LVS_EX_CHECKBOXES styles notifies "checkbox status changed" (e.g. when a user has clicked in a checkbox)?
http://codexpert.ro/forum/download/file.php?id=265
A: When an item status has been changed the listview control send LVN_ITEMCHANGED notification to its parent window. This includes the change of checkbox state, but unfortunately this is not (yet) documented.
However, this is possible by testing the bit 12 and 13 from uNewState member of NMLISTVIEW structure sent with LVN_ITEMCHANGED.
Example
Code:
// MyDialog.h
class CMyDialog : public CDialog
{
// ...
afx_msg void OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult);
}
Code:
// MyDialog.cpp
// ...
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CMyDialog::OnLvnItemchangedList)
END_MESSAGE_MAP()
// ...
// ...
void CMyDialog::OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
if(pNMLV->uChanged & LVIF_STATE) // item state has been changed
{
switch(pNMLV->uNewState & 0x3000)
{
case 0x2000: // new state: checked
TRACE1("\n Item %d has been checked", pNMLV->iItem);
break;
case 0x1000: // new state: unchecked
TRACE1("\n Item %d has been unchecked", pNMLV->iItem);
break;
}
}
*pResult = 0;
}
Example
Code:
// Similar to previous example but a little bit better written;
// the "magic" constants are replaced with LVIS_STATEIMAGEMASK and
// INDEXTOSTATEIMAGEMASK macros defined in commctrl.h.
// Credits: VictorN
void C_TestCheckDlg::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
if(pNMLV->uChanged & LVIF_STATE) // item state has been changed
{
switch(pNMLV->uNewState & LVIS_STATEIMAGEMASK)
{
case INDEXTOSTATEIMAGEMASK(BST_CHECKED + 1): // new state: checked
TRACE1("\n Item %d has been checked", pNMLV->iItem);
break;
case INDEXTOSTATEIMAGEMASK(BST_UNCHECKED + 1): // new state: unchecked
TRACE1("\n Item %d has been unchecked", pNMLV->iItem);
break;
}
}
*pResult = 0;
}
See also How CCheckListBox notifies "checkbox status changed"?