ユーザーがCListCtrlで行を選択したときにコードを実行したい(レポートビュー、他の表示モードは気にしない)。
このイベントをキャッチするにはどうすればよいですか?マップできるメッセージや「OnSelectionChanged」などのメソッドはありますか?
また試してください:
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つの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)
、フォーカス喪失通知後の同じ処理のスキップ。
djeidotはまさにその通りです。
ListViewは複数選択をサポートしているため(これは無効にできます)、OnSelectionChanged()がないことを追加したいだけです。したがって、単一選択リストビューでは、2つのイベントが送信されます。古いアイテムが選択されていないことと、新しいアイテムが選択されていることです。
私の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...
}