Für die globale Variable bekommst'e erstmal den Popo verhauen.
Wieso hörst du nicht auf den Compiler?
z.B. [dcc32 Hinweis] H2164 Variable 'i' wurde deklariert, aber in 'TForm1.FormCreate' nicht verwendet
Warum einmal OnMessage über TApplicationEvents auf der Form,
aber dann abweichend OnIdle über das globale Application?
Wenn, dann am Besten beides einheitlich über TApplicationEvents.
Delphi-Quellcode:
public
ActiveLB: TListBox;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
if ListBox1.Handle = msg.hwnd then ActiveLB := ListBox1 else
if ListBox2.Handle = msg.hwnd then ActiveLB := ListBox2 else
if ListBox3.Handle = msg.hwnd then ActiveLB := ListBox3;
end;
procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
begin
if Assigned(ActiveLB) then begin
if ActiveLB <> ListBox1 then ListBox1.TopIndex := ActiveLB.TopIndex;
if ActiveLB <> ListBox2 then ListBox2.TopIndex := ActiveLB.TopIndex;
if ActiveLB <> ListBox3 then ListBox3.TopIndex := ActiveLB.TopIndex;
ActiveLB := nil; // einmal abgearbeitet, dann abschalten, sonst triggert sich das auf ewig immer wieder selbst.
// in LB1 scrollen löst Scrollen in LB2 und LB3 aus, was wiederum Messages in diesen auslöst usw.
// Du hast echt Glück, dass im Setter von TopIndex ein "if GetTopIndex <> Value then" steht und es schnell endet
//
// PS: also können die "if ActiveLB <> ListBox1 then" weg (ähnlich dem nachfolgenden Beispiel)
end;
end;
oder einfach alles direkt und umgehend
Delphi-Quellcode:
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
C: TWinControl;
//L: TListBox absolute C;
begin
C := FindControl(msg.hwnd);
if (C is TListBox) and C.Focused then begin // bzw. falls weitere ListBoxen :: if C.Focused and ((C = ListBox1) or (C = ListBox2) or (C = ListBox3)) then
//if (ListBox1 <> L) and (ListBox1.TopIndex <> L.TopIndex) then ListBox1.TopIndex := L.TopIndex;
//if (ListBox2 <> L) and (ListBox2.TopIndex <> L.TopIndex) then ListBox2.TopIndex := L.TopIndex;
//if (ListBox3 <> L) and (ListBox3.TopIndex <> L.TopIndex) then ListBox3.TopIndex := L.TopIndex;
// jupp, die Prüfungen weg, siehe Setter von TopIndex
ListBox1.TopIndex := TListBox(C).TopIndex;
ListBox2.TopIndex := TListBox(C).TopIndex;
ListBox3.TopIndex := TListBox(C).TopIndex;
end;
end;
oder am Besten garnicht ganz global, sondern direkt nur in den ListBoxen, also anstatt OnMessage
Delphi-Quellcode:
type
TListBox =
class(
Vcl.StdCtrls.TListBox)
protected
// im StandardHandler
// WM_VSCROLL
// CN_VSCROLL
procedure WndProc(
var Message: TMessage);
override;
// oder gezielt die gewünschte(n) Message(s) und Notification(s)
procedure WMVScroll(
var Message: TWMVScroll);
message WM_VSCROLL;
// oder CN_VSCROLL
end;
TForm1 =
class(TForm)
ListBox1: TListBox;
ListBox2: TListBox;