web-dev-qa-db-ja.com

CListCtrl選択の変更を検出する方法?

ユーザーがCListCtrlで行を選択したときにコードを実行したい(レポートビュー、他の表示モードは気にしない)。

このイベントをキャッチするにはどうすればよいですか?マップできるメッセージや「OnSelectionChanged」などのメソッドはありますか?

29
rec

また試してください:

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...
    }
}
39
djeidot

何が起こっているかに基づいて、いくつかの通知があります。

アイテムを選択していて、まだ何も選択されていない場合、1つのLVIF_STATE変更通知(uNewState&LVIS_SELECTED)を受け取ります。新しく選択したアイテムは次の場所にあります。

pNMListView->iItem

新しいオブジェクトを選択する前にアイテムを選択すると、次の3つの状態変化が発生します。

最初に、フォーカスのある前のアイテムがフォーカスを失っていることが通知されます。

pNMListView->uOldState & LVIS_FOCUSED

次に、古いアイテムが選択解除されていることが通知されます。

pNMListView->uOldState & LVIS_SELECTED

最後に、新しいアイテムの選択状態を取得します。

pNMListView->uNewState & LVIS_SELECTED

(もう一度、新しく選択されたアイテムのiItemを見てください)

したがって、私たちが遭遇した落とし穴は、アイテムの選択を解除すると2つの通知が発生するため、繰り返しの多い、場合によっては有害な処理を行うことでした。結局のところ、この処理は2番目のメッセージ(pNMListView->uOldState & LVIS_SELECTED)、フォーカス喪失通知後の同じ処理のスキップ。

11
Mark Colbath

djeidotはまさにその通りです。

ListViewは複数選択をサポートしているため(これは無効にできます)、OnSelectionChanged()がないことを追加したいだけです。したがって、単一選択リストビューでは、2つのイベントが送信されます。古いアイテムが選択されていないことと、新しいアイテムが選択されていることです。

4
Serge Wautier

私のVisual Studio 2010では、ビジュアルエディターは次のようにダイアログヘッダーファイルでコールバックを宣言します。

afx_msg void OnLbnSelchangeListOnvif();

そしてソースファイルで:

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

void CDialogOnvif::OnLbnSelchangeListOnvif()
{
    // do stuff...
}
0
Zac