2009-09-22 10 views
27

Tôi muốn thực thi một số mã khi người dùng chọn một hàng trong một CListCtrl (chế độ xem báo cáo, tôi không quan tâm đến các chế độ xem khác).Làm cách nào để phát hiện thay đổi lựa chọn CListCtrl?

Làm cách nào để bắt sự kiện này? là có một số tin nhắn tôi có thể bản đồ hoặc một phương pháp như "OnSelectionChanged" hoặc một cái gì đó như thế?

Trả lời

38

Cũng thử:

BEGIN_MESSAGE_MAP(cDlgRun, CDialog) 
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, OnItemchangedList2) 
END_MESSAGE_MAP() 

/* ... */ 

void cDlgRun::OnItemchangedList2(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 

    if ((pNMListView->uChanged & LVIF_STATE) 
     && (pNMListView->uNewState & LVIS_SELECTED)) 
    { 
     // do stuff... 
    } 
} 
+1

này sẽ không bắt một sự thay đổi khi bạn chọn ba phần tử với shift, nhưng sau đó chọn bất kỳ phần tử nào trong số chúng (mà bỏ chọn hai phần tử còn lại, nhưng giữ cho phần tử này được chọn). Bất kỳ giải pháp nào cho điều đó ngoại trừ việc giữ một danh sách các mục đã chọn? –

+0

Tôi không thể kiểm tra nó ngay bây giờ nhưng tôi nghĩ rằng bạn sẽ cần phải bắt deselection cũng như lựa chọn: để bắt deselection chỉ sử dụng 'if ((pNMListView-> uChanged & LVIF_STATE) && (pNMListView-> uOldState & LVNI_SELECTED) &&! (PNMListView -> uNewState & LVNI_SELECTED)) ' – djeidot

+2

@djeidot: Cảm ơn rất nhiều, nó đã giúp ích rất nhiều. Khi được nhúng trong lớp Điều khiển riêng của mình, điều này có thể được giảm xuống ON_NOTIFY_REFLECT (LVN_ITEMCHANGED, & OnItemSelected) – mox

4

djeidot là phải vào.

Tôi chỉ muốn thêm rằng không có OnSelectionChanged() vì ListView hỗ trợ đa lựa chọn (mặc dù điều này có thể bị tắt). Do đó, một listview chọn một lựa chọn sẽ gửi cho bạn hai sự kiện: mục cũ chưa được chọn VÀ mục mới được chọn.

9

Có một vài thông báo dựa trên những gì đang xảy ra.

Nếu bạn đang chọn một mục và không có mục nào được chọn, bạn sẽ nhận được một thông báo thay đổi LVIF_STATE: uNewState & LVIS_SELECTED. Mục mới được lựa chọn sẽ được tìm thấy tại địa chỉ:

pNMListView->iItem 

Nếu một mục được chọn trước khi bạn chọn một đối tượng mới, bạn sẽ nhận được ba thay đổi trạng thái:

Trước tiên, bạn sẽ được thông báo rằng mục trước trong tập trung được mất tập trung:

pNMListView->uOldState & LVIS_FOCUSED 

Sau đó, bạn sẽ được thông báo rằng mục cũ đang được được chọn:

pNMListView->uOldState & LVIS_SELECTED 

Cuối cùng, bạn sẽ nhận được mới nhà nước lựa chọn mục:

pNMListView->uNewState & LVIS_SELECTED 

(một lần nữa nhìn vào iItem cho mặt hàng mới được chọn)

Vì vậy, các cạm bẫy chúng tôi chạy qua là, bởi vì kết quả mục deselection trong hai thông báo , chúng tôi đã làm rất nhiều công đoạn lặp đi lặp lại, đôi khi gây bất lợi. Những gì chúng tôi đã kết thúc chỉ làm việc xử lý này cho thư thứ 2 (pNMListView->uOldState & LVIS_SELECTED) và bỏ qua quá trình xử lý tương tự sau khi mất thông báo tiêu điểm.

-1

Mở Visual Studio của tôi năm 2010, soạn thảo trực quan tuyên bố một callback trong file header thoại như thế này:

afx_msg void OnLbnSelchangeListOnvif(); 

và trong file nguồn:

BEGIN_MESSAGE_MAP(CDialogOnvif, CDialog) 
    ON_LBN_SELCHANGE(IDC_LIST_ONVIF, &CDialogOnvif::OnLbnSelchangeListOnvif) 
END_MESSAGE_MAP() 

void CDialogOnvif::OnLbnSelchangeListOnvif() 
{ 
    // do stuff... 
} 
+2

Điều đó sẽ chỉ làm việc cho Danh sách hộp (CListBox), không CListCtrl. –