Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TListBox und dessen Einträge


Torsten - Do 24.10.02 16:46
Titel: TListBox und dessen Einträge
Moinsen Leute!

Sitze schon seit ein paar Stunden an einem dämlichen Problem.
Ich umschreibe es mal kurz.

In einem Beispielprogramm will ich Ereignisse wie etwas OnMouseMove, OnClick für mehrere Komponenten (TForm, TButton, ...) abfangen.

Die Anzahl der Ereignisse soll später in TListBox dargestellt werden.

Ist ja ansich kein Problem, doch die Einträge sollen nicht fortlaufend eingefügt werden. Das ist nicht gerade gut für die Übersicht.

Es ist also eine konstante Anzahl der Einträge, bei denen sich nur die Einträge selbst ändern.
Zum Beispiel:

Eintrag 1: 10x FormMouseMove
Eintrag 2: 29x ButtonClick

Da die Anzahl der Ereignisse, die ich abfange endlich ist, wird also die Liste nicht sehr lang.

Mein Problem ist nun, wie ich die Einträge der Liste selbst verändere, ohne bestehende Einträge zu überschreiben.
Bewege ich besipielsweie die Maus, so wird ja nur der Zähler für das Ereignis OnMouseMove erhöht und somit auch der entsprechende Eintrag in der ListBox verändert.
Alle anderen bereits eingetroffenen Ereignisse sollen aber dennoch in der ListBox bestehen bleiben.

Etwas Code habe ich mir dazu schon überlegt:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
...

{$J+}    // ermöglicht typisierte Konstanten (können wie Variablen genutzt werden)
         // ansonsten liessen sich die Variablen schlecht initialisieren
         
procedure getEvents(id: Integer; count: Integer);
begin
 Form4.ListBox1.Clear;
 case id of
        1: Form4.ListBox1.Items.Append(IntToStr(count) + ': FormMouseMove');
        2: Form4.ListBox1.Items.Append(IntToStr(count) + ': FormMouseDown');


  end;

end;


procedure TForm4.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const i: Integer = 0;
begin
 inc(i);
 getEvents(1,i);
end;

rocedure TForm4.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
const i: Integer = 0;
begin
 inc(i);
 getEvents(2,i);

end;
...


Das ist nur ein Beispiel für zwei Ereignisse.
Jedoch werden beide nicht gleichzeitig in der ListBox dargestellt.

Hätte jemand einen guten Hinweis für mich?

Fragende Grüße

Torsten


aogwaba - Do 24.10.02 19:37

Hi!

TStringList.append, hängt den String am Ende der Listbox an,
was du benötigst ist TListBox.items[i] zum Zugriff auf die einzelnen Items.
Vielleich solltest du die Bezeichnungen wie '': FormMouseDown' in
einer extra TStringList speichern und erst in der Procedure mit 'count' zusammenfügen.

Aber, wäre bei dem Problem ein TListView nicht abgebrachter?

cu
waba


Torsten - Do 24.10.02 20:25

Moinsen!

OK, Append war auch nur ein Ansatz, leider ein erfolgloser, von mir.
Mit Items habe ich das auch schon probiert, jedoch nix Vernünftiges gebacken bekommen.

TListBox muss es sein. Kann ich leider nicht vermeiden.

Grüße

Torsten


aogwaba - Do 24.10.02 20:45

Hi!

Na dann mach's doch so, deklariere ne TStringList :

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var myList:TStringList;

im constructor dann:
myList:=TStringList.create;
myList.add(': FormMouseMove');
...
procedure getEvents(id: Integer; count: Integer);
begin
  Form4.ListBox1.Clear;
  if id >=myList.count then exit;
  Form4.ListBox1.Items[1]:=IntToStr(count) + myList.items[1];
end;

ID beginnt bei 0 !!!

und im destructor dann:

Quelltext
1:
myList.free;                    


cu
waba

(24.10.02 22:59 Tino) Code-Tags hinzugefügt.


Torsten - Do 24.10.02 22:57

Moinsen!

Besten Dank für den Tipp.
Hatte es aber schon anders probiert. Und zwar so.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
...

procedure getEvents(id: Integer; count: Integer);
begin
 case id of
        0: Form4.ListBox1.Items[id]:=IntToStr(count) + 'x FormMouseMove';
        1: Form4.ListBox1.Items[id]:=IntToStr(count) + 'x FormMouseDown';
        2: Form4.ListBox1.Items[id]:=IntToStr(count) + 'x FormMouseUp';
        3: Form4.ListBox1.Items[id]:=IntToStr(count) + 'x FormClick';
        4: Form4.ListBox1.Items[id]:=IntToStr(count) + 'x ButtonMouseMove';
 end;
end;


procedure TForm4.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const i: Integer = 0;
begin
 inc(i);
 getEvents(0,i);
end;

procedure TForm4.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
const i: Integer = 0;
begin
 inc(i);
 getEvents(1,i);
end;

procedure TForm4.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
const i: Integer = 0;
begin
 inc(i);
 getEvents(2,i);
end;

procedure TForm4.FormClick(Sender: TObject);
const i: Integer = 0;
begin
 inc(i);
 getEvents(3,i);
end;

procedure TForm4.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const   i: Integer = 0;
begin
 inc(i);
 getEvents(4,i);
end;

...


Doch da ist ein kleines Problem.
Tritt beispielsweise Event4 vor Event2 auf, so gibt es eine Exception. Die Zeile konnte nicht eingefügt werden.
Ist ja auch logisch, da es keine Vorgänger-Zeile gibt. Daher auch der Fehler.
Werden die Events so ausgelöst, wie es in der case-Anweisung steht, dann funktioniert es wunderbar.

Wie kann man das clever umgehen? Mittlerweile sehe ich den Code nicht mehr. Der Tag war lang genug.

Fragende Grüße

Torsten


aogwaba - Do 24.10.02 23:15

Hi!
Die Listbox wird zum Programmstart leer sein.
Solltest im constructor folgendes einfügen:

for i:=0 to 4 do getEvents(i,0) ;

cu
waba


Torsten - Do 24.10.02 23:27

Moinsen!

Göttlich. Das war es.
Besten Dank dafür. Funktioniert astrein.

Dankende Grüße

Torsten


Torsten - Fr 25.10.02 18:52

Moinsen!

Ääähm, mal so am Rande.
Wie kann man einer ListBox eine horizontale Laufleiste verpassen?

Grüße

Torsten


aogwaba - Fr 25.10.02 19:08

Hi!

aus der OH:

Mit ScrollWidth können Sie die logische Breite des Listenfeldes abrufen oder einstellen. Ist ScrollWidth größer als die Breite des Client-Bereichs des Listenfeldes, erhält das Listenfeld eine horizontale Bildlaufleiste. Ist ScrollWidth dagegen kleiner oder gleich ClientWidth, wird die Bildlaufleiste nicht angezeigt.

cu
waba
[/quote]


Torsten - Fr 25.10.02 19:12

Moinsen!

Danke für die Antwort.
Habe soeben auch eine andere Möglichkeit gefunden.

Grüße

Torsten