CListCtrl und LVN_ITEMCHANGED wiedermal
-
Hi,
ich brauche Hilfe...
folgendes Szenario:
ich habe eine Liste, bei der man nur einen Eintrag auswählen kann.
Wenn man jetzt Werte ändert (sind dann aber noch nicht (in DB) gespeichert) und anschließend einen anderen Eintrag auswählen möchte, dann soll eine Abfrage erscheinen (soll gespeichert werden...?).
Daraufhin soll sich der Anwender entscheiden.
So ist das ja kein Thema.Habe das so realisiert:
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_MITARBEITER, OnSelChangedMitarbeiter) // ... void CVCMitarbeiterDlg::OnSelChangedMitarbeiter(NMHDR *pNMHDR, LRESULT *pResult) { pResult = 0; // falls manuell eintrag selektiert wird... if (m_bIgnoreNotify == true) return; NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if ((pNMListView->uChanged & LVIF_STATE) != LVIF_STATE) return; // state has not changed // Has the selected state changed? if (!(pNMListView->uNewState & LVIS_SELECTED) || (pNMListView->uOldState & LVIS_SELECTED)) return; // selected state has not changed // anderer eintrag? if (pNMListView->iItem != m_iCurPos) { if (IsDirty()) // verändert? { switch (MessageBox("Die Daten wurden verändert.\r\nSollen die Änderungen gespeichert werden?", "Sicherheitsabfrage", MB_YESNO | MB_ICONQUESTION)) { case IDYES: if (!Save()) { m_bIgnoreNotify = true; m_ctlListMA.SetItemState(m_iCurPos, LVIS_SELECTED, LVIS_SELECTED); m_bIgnoreNotify = false; return; } break; case IDNO: m_bDirty = false; break; } } //... m_iCurPos = pNMListView->iItem; } }
Warum läuft der immer noch 2x durch diese Routine (ergo: die Abfrage zum Speichern erscheint auch 2x)?!?
Kann mir das bitte jemand erklären?Danke im voraus
-
Ergänzung:
Das 2. Mal wird erst aufgerufen, wenn ich die Maus wieder bewege.
Ich habe aber weder irgendein maus-event noch LVS_EX_TRACKSELECT in der listctrl definiert...
-
Habe das ganze mal mit einem einfachen Dialogfeldbasierendem Projekt geprüft.
Einfach die Schrift "Hier kommt der Text..." entfernt und eine Liste eingefügt.
Typ: Bericht
Attribute: Einzelauswahl und Auswahl immer anzeigen.
Event: LVN_ITEMCHANGEDDas ist dann der Inhalt der Methode:
// MessageMap ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, OnItemchangedList1) // OnInitDialog... CListCtrl* pCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); pCtrl->InsertColumn(0, "Test1", NULL, 100); pCtrl->InsertColumn(1, "Test2", NULL, 100); pCtrl->InsertColumn(2, "Test3", NULL, 100); pCtrl->InsertColumn(3, "Test4", NULL, 100); for (int i=0; i<10; i++) { CString strText; strText.Format("textnr. %d", i); int iPos = pCtrl->InsertItem(pCtrl->GetItemCount(), strText); pCtrl->SetItemText(iPos, 1, "bla blubb"); } pCtrl->SetExtendedStyle(pCtrl->GetExtendedStyle() | LVS_EX_FULLROWSELECT); // Nachrichtenbehandlung... void CListeDlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if ((pNMListView->uChanged & LVIF_STATE) != LVIF_STATE) return; // state has not changed // Has the selected state changed? if (!(pNMListView->uNewState & LVIS_SELECTED) || (pNMListView->uOldState & LVIS_SELECTED)) return; // selected state has not changed CListCtrl* pCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); if (pNMListView->iItem == 3) { MessageBox("jetzt"); pCtrl->SetItemState(5, LVIS_SELECTED, LVIS_SELECTED); pCtrl->SetItemState(5, LVIS_SELECTED, LVIS_SELECTED); pCtrl->SetItemState(5, LVIS_FOCUSED, LVIS_FOCUSED); } *pResult = 0; }
Gleicher Effekt!
Wenn ich mit den Pfeiltasten hoch und runter gehe, dann funzt es wunderbar...
Aber mit der Maus wird es erst 1x aufgerufen und wenn ich dann die Maus bewege, wird das 2.x dieses Event aufgerufen.
Solange man die Maus nicht bewegt, werden die "speziellen" Tasten [Esc], [Tab], [Alt]+[F4] ignoriert!!!Warum?!?
Ich raff nix mehr...
-
Entschuldigt bitte, dass ich nerve...
Aber hat wirklich keiner eine Idee?
Oder habt ich mich unverständlich ausgedrückt?Das ist doch eigentlich nicht allzu selten, diese Situation...
Schönes Wochenende noch...
-
Hi,
ich kenne das Problem von TreeCtrls. Da ist es auch so, wenn ich mich recht erinnere...
Aber du wirst damit leben müssen, dass die Message eben zweimal kommt. Da kannst vermutlich nix dran drehen. Aber du kannst dir doch in deinem Handler eine kleine "Intelligäns" einbauen, damit die Message nur einmal ausgewertet wird. Das ist doch kein Problem, oder?
Grüße, Volle.
-
Vielleicht hätte es damit funktioniert:
void CListeDlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) { ... *pResult = 0; }
Damit wird die Message als behandelt gesetzt und im "Message-Tree" nicht mehr weiter behandelt. Weiß aber nicht, ob es das Problem gelöst hätte.
Naja, hätte ja gern früher geholfen, war damals aber noch in der Grundschule ^^. Ich hoffe irgendwer hat das selbe Problem nochmal und kanns ausprobieren:) ..
-
oh, ich seh grad, dass es eh drin ist.. sry