在 MFC 中使用 CListCtrl 的 LVS_EX_CHECKBOXES 風格時,每行首列會顯示 CheckBox。本文介紹如何捕獲用戶點擊 CheckBox 時的狀態變更事件。
列表控件沒有專門的「CheckBox 點擊」通知消息,需通過 NM_CLICK 消息配合 HitTest 判斷點擊位置是否落在狀態圖標(CheckBox)上。
// 對話框類頭文件聲明
afx_msg void OnClickStateList(NMHDR* pNMHDR, LRESULT* pResult);
// 消息映射
ON_NOTIFY(NM_CLICK, IDC_LIST_CTRL, &CStatusBarDlg::OnClickStateList)
// 處理函數
void CStatusBarDlg::OnClickStateList(NMHDR* pNMHDR, LRESULT* pResult) {
DWORD dwPos = GetMessagePos();
CPoint point(LOWORD(dwPos), HIWORD(dwPos));
m_StatusList.ScreenToClient(&point);
LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;
UINT nFlag;
int nItem = m_StatusList.HitTest(point, &nFlag);
// 關鍵判斷:是否點在狀態圖標(CheckBox)上
if (nFlag == LVHT_ONITEMSTATEICON) {
TRACE(_T("CheckBox clicked, Item=%d\n"), nItem);
// 此處可獲取當前勾選狀態:m_StatusList.GetCheck(nItem)
// 執行業務邏輯...
}
*pResult = 0;
}
GetMessagePos() 獲取點擊時的屏幕坐標ScreenToClient() 轉為控件客戶區坐標HitTest() 返回項索引與標志位 nFlagLVHT_ONITEMSTATEICON 表示點擊了狀態圖標(即 CheckBox)BOOL checked = m_StatusList.GetCheck(nItem); // 獲取
m_StatusList.SetCheck(nItem, TRUE); // 設置
此方法適用於 Report/List 等視圖模式,是 MFC 處理列表 CheckBox 交互的標準做法。