Zeile einer Listbox blau hinterlegen
-
Hallo,
Möchte in meiner ListBox die aktuelle Zeile (Cursorposition) blau hinterlegen.
Muß ich dieses über MouseMove Befehl erledigen oder gibt es eine andere Möglichkeit ?
Habe vergeblich in der Hilfe gesucht.Gruß Siegfried
-
Hallo
ja da brauchst du den OnMouseMove-Event und die Mehtode ItemAtPos()
Wobei ich mich frage, ob das Item dann nur anders dargestellt werden soll oder auch gleich effektiv ausgewählt werden soll (ItemIndex).
Wenn du es nur darstellen willst, brauchst du noch einen Zwischenspeicher für dieses hervorzuhebende Item, und must den OnDrawItem-Event benutzen, um die Hervorhebung durchzuführen. Dazu must du den Style auf OwnerDraw... setzenbis bald
akari
-
Hallo,
Habe es etwas unglücklich beschrieben. Kenne aus anderen Prgramme, das man beim überfahren der Listbox mit der Maus die jeweilige Zeile blau hinterlegt wird.
Deine Infos haben meinen Weg bestätigt. Danke für die schnelle Hilfe.
Gruß Siegfried

-
Hallo,
nutze den Code aus dem C++ Forum.
leider ändern sich nur die Farben be einem " Click " auf die Zeile.
Hatte mir vorgestellt, das die Farbe sich beim Cursor auf die Zeile ändert.void __fastcall TFrameListbox::ListBox1DrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) { int i=0; // if(State.Contains(odSelected)) { ListBox1->Canvas->Brush->Color = LBColors[0]; // Hintergrundfarbe ListBox1->Canvas->Font->Color = LBColors[4]; // Textfarbe } else { ListBox1->Canvas->Brush->Color = LBColors[4]; // Textfarbe ListBox1->Canvas->Font->Color = LBColors[3]; //Hintergrundfarbe } // Hintergrund zeichnen ListBox1->Canvas->FillRect(Rect); // Text zeichnen ListBox1->Canvas->TextRect(Rect, Rect.Left, Rect.Top, ListBox1->Items->Strings[Index]); i = Index; if(State.Contains(odFocused)) { ListBox1->Canvas->DrawFocusRect(Rect); } // Label1->Caption = IntToStr(MousePosIndex); Label2->Caption = IntToStr(i); } //---------------------------------------------------------------------------wer kann mir helfen?
Gruß Siegfried

-
Hallo
ich glaube das beste ist eine Ableitung von TListBox, um den Effekt zu erzeugen.
Zuerst erstellst du eine Klasse dafür, wie hier in diesem Beispiel
http://www.c-plusplus.net/forum/viewtopic-var-t-is-112679-and-start-is-0.html
nur das du statt ComboBox immer ListBox schreibst und die automatisch erstellten Dateien stattdessen anders erweiterst.
Headerdatei ListBoxEx.h :... private: void __fastcall wmMouseMove(TMessage& Msg); void __fastcall cmMouseLeave(TMessage& Msg); int iLastIndex; // interner Sppeicher für das letzte mit der Maus überfahrene Item TOwnerDrawState GetItemState(int CurrIndex); protected: BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_MOUSEMOVE, TMessage, wmMouseMove); MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, cmMouseLeave); END_MESSAGE_MAP(TListBox) virtual void __fastcall DrawItem(int Index, const TRect &Rect, TOwnerDrawState State); public: ...Implementationsdatei ListBoxEx.cpp :
void __fastcall TListBoxEx::DrawItem(int Index, const TRect &Rect, TOwnerDrawState State) { if(State.Contains(odSelected)) { Canvas->Brush->Color = clHighlight; // Hintergrundfarbe Canvas->Font->Color = clHighlightText; // Textfarbe } else { Canvas->Brush->Color = clWindow ; // Textfarbe Canvas->Font->Color = clMenuText ; //Hintergrundfarbe } // Hier wird jetzt das gerade von der Maus überfahrene Item anders gezeichnet if (iLastIndex == Index) { Canvas->Font->Color = clRed; } // Hintergrund zeichnen Canvas->FillRect(Rect); // Text zeichnen Canvas->TextRect(Rect, Rect.Left +2, Rect.Top, Items->Strings[Index]); if(State.Contains(odFocused)) { Canvas->DrawFocusRect(Rect); } } //--------------------------------------------------------------------------- // Ermittelt den OwnerDrawState für ein Item TOwnerDrawState TListBoxEx::GetItemState(int CurrIndex) { TOwnerDrawState State = TOwnerDrawState(); if (ItemIndex == CurrIndex) State << odSelected; return(State); } void __fastcall TListBoxEx::wmMouseMove(TMessage& Msg) { TPoint CursorPoint; // aktueller Punkt des Mauscursors GetCursorPos(&CursorPoint); // Cursor ermitteln CursorPoint = ScreenToClient(CursorPoint); // Cursor auf dieses Control umrechnen int CursorIndex = ItemAtPos(CursorPoint, true); // Item unter Cursor ermitteln // Wenn Item unter Cursor vorhanden, dieses neu zeichnen if (CursorIndex != -1) { TRect Rect = ItemRect(CursorIndex); DrawItem(CursorIndex, Rect, GetItemState(CursorIndex)); } // Wenn vor dem Aufruf ein anderes Item hervorgehoben war, dieses // ermitteln und neu ohne Vorhebung zeichnen if ((iLastIndex != CursorIndex) && (iLastIndex > -1)) { TRect Rect = ItemRect(iLastIndex); int Buffer = iLastIndex; iLastIndex = CursorIndex; DrawItem(Buffer, Rect, GetItemState(Buffer)); } iLastIndex = CursorIndex; // neuen Index übernehmen } //--------------------------------------------------------------------------- void __fastcall TListBoxEx::cmMouseLeave(TMessage& Msg) { if (iLastIndex == -1) return; // Wenn keine Vorhebung, beenden // Item ohne Vorhebung neu zeichnen und Index zurücksetzen TRect Rect = ItemRect(iLastIndex); int Buffer = iLastIndex; iLastIndex = -1; DrawItem(Buffer, Rect, GetItemState(Buffer)); } //--------------------------------------------------------------------------- __fastcall TListBoxEx::TListBoxEx(TComponent* Owner) : TListBox(Owner) { iLastIndex = -1; // Startwert } //---------------------------------------------------------------------------bis bald
akari
-
Hallo,
muß alles ausprobieren.
vorerst vielen Dank
Gruß Siegfried
-
Hallo,
hat funktioniert.
kann man nachträglich den Code abändern und die Komponente updaten ?Gruß Siegfried
-
Hallo
klar.
du öffnest das erstellte Package (Package_ListBoxEx.bpk), änderst den Code und compilierst und installierst das Package neu. Die alte Version wird dann ersetzt.bis bald
akari
-
Hallo,
hat auch funktioniert.
Habe aber noch ein Problem. Habe im OI die Schrift auf Fett eingestellt. Wenn ich mit der Maus über die Zeilen fahre, wandelt sich der Text in normal um.wo muß ich noch eine Änderung durchführen ?
Gruß Siegfried
-
Hallo
einfach die Funktion DrawItem so erweitern
void __fastcall TListBoxEx::DrawItem(int Index, const TRect &Rect, TOwnerDrawState State) { Canvas->Font = Font; // übernimmt den Font des Controls zum Darstellen ...bis bald
akari
-
Hallo,
funktioniert, so wie ich es wollte.
Danke !!!
Gruß Siegfried

-
Hallo @akari
die Komponente funktioniert gut.
Jetzt wollte ich "OnMouseMove" zusätzlich nutzen. Klappt leider nicht.
OnMouseDown und OnMouseUp klappt.brauche Hilfe!
Gruß Siegfried

-
Hallo
liegt daran, das in der abgeleiteten Komponente ja die MouseMove-Botschaft abgefangen wird. Alles was du tun must, ist den OnMouseMove-Event selber auszulösen
void __fastcall TListBoxEx::wmMouseMove(TMessage& Msg) { ... if (OnMouseMove) OnMouseMove(this, TShiftState(), 0, 0); }DIe letzten drei Parameters kannst du auch noch bestimmen, u.a. aus den Message-Parametern.
/Edit : Oder besser der Vorschlag von Jansen.
bis bald
akari
-
In den MessageHandlern fehlt das Dispatch().
Siehe auch den entsprechenden FAQ-Eintrag im Abschnitt "System".
-
Hallo,
Danke an alle für die Hilfe.void __fastcall TListBoxEx::wmMouseMove(TMessage& Msg) { // OnMouseMove Ereignis auswerten if (OnMouseMove) OnMouseMove(this, TShiftState(), 0, 0); // // TPoint CursorPoint; // aktueller Punkt des Mauscursors GetCursorPos(&CursorPoint); // Cursor ermitteln CursorPoint = ScreenToClient(CursorPoint); // Cursor auf dieses Control umrechnen int CursorIndex = ItemAtPos(CursorPoint, true); // Item unter Cursor ermitteln // Wenn Item unter Cursor vorhanden, dieses neu zeichnen if (CursorIndex != -1) { TRect Rect = ItemRect(CursorIndex); DrawItem(CursorIndex, Rect, GetItemState(CursorIndex)); } // Wenn vor dem Aufruf ein anderes Item hervorgehoben war, dieses // ermitteln und neu ohne Vorhebung zeichnen if ((iLastIndex != CursorIndex) && (iLastIndex > -1)) { TRect Rect = ItemRect(iLastIndex); int Buffer = iLastIndex; iLastIndex = CursorIndex; DrawItem(Buffer, Rect, GetItemState(Buffer)); } iLastIndex = CursorIndex; // neuen Index übernehmen } //---------------------------------------------------------------------------Zeile eingefügt, funktioniert! Habe aber noch ein Problem. Wie bekomme ich den "CursorIndex" an die Form gemeldet ?
Bin bei solchen Code überfragt. Kann man mir hier auch helfen ?
Hintergrund ist folgender. Beim überfahren der ListBox ändert sich die Zeilenfarbe. Dies ist alles ok. Nun möchte ich aber beim überfahren der Zeilen auch dessen Inhalt auslesen, ohne einen Maus Click ausführen zu müssen. Wenn dieses nicht der richtige Weg ist, lasst mich es wissen.Gruß Siegfried

-
Hallo
Du machst eine Nur-Lesen Eigenschaft für iLastIndex. Dann kannst du diesen Wert beliebig oft abrufen, und als Index für Items->Strings benutzen.
bis bald
akari
-
Dispatch!
-
Hallo,
nochmals vielen Dank für die Hilfe. Habe eine Möglichkeit gefunden, meine Wünsche zu verwirklichen. Ich gehe davon aus, wenn ihr meine Lösung lest, das ihr die Hände über dem Kopf .....void __fastcall TListBoxEx::wmMouseMove(TMessage& Msg) { // // TPoint CursorPoint; // aktueller Punkt des Mauscursors GetCursorPos(&CursorPoint); // Cursor ermitteln CursorPoint = ScreenToClient(CursorPoint); // Cursor auf dieses Control umrechnen int CursorIndex = ItemAtPos(CursorPoint, true); // Item unter Cursor ermitteln // Wenn Item unter Cursor vorhanden, dieses neu zeichnen if (CursorIndex != -1) { //************************************************************ // OnMouseMove Ereignis auswerten if (OnMouseMove) OnMouseMove(this, TShiftState(), 0, CursorIndex); //************************************************************ TRect Rect = ItemRect(CursorIndex); DrawItem(CursorIndex, Rect, GetItemState(CursorIndex)); } // Wenn vor dem Aufruf ein anderes Item hervorgehoben war, dieses // ermitteln und neu ohne Vorhebung zeichnen if ((iLastIndex != CursorIndex) && (iLastIndex > -1)) { TRect Rect = ItemRect(iLastIndex); int Buffer = iLastIndex; iLastIndex = CursorIndex; DrawItem(Buffer, Rect, GetItemState(Buffer)); } iLastIndex = CursorIndex; // neuen Index übernehmen } //---------------------------------------------------------------------------Wenn auch meine Möglichkeit getrickst ist, hat es mir den Erfolg gebracht.
Über "Dispatch" können wir uns später unterhalten. Ich arbeite mit C++ seit etwa 6 Monate, komme aus der untersten Ebene über VB6 zu C++. Also muß ich sehr gut zuhören, was man mir vorschlägt. Es kann nur besser werden.
bis bald
Siegfried
