Für RichEdits habe ich es folgendermaßen umgesetzt:
(
https://youtu.be/qH-kT2I5q6g)
Das kannst Du so natürlich nicht 1:1 übernehmen (da ich von einem anderen Datenbestand ausgehe und Listboxen vielleicht nicht genau so funktionieren) aber evtl. hilft es als Ideenpool...
(Die Panels sind ausgestanzt und bilden die Rahmen um die aktuellen Zeilen links und rechts.)
Delphi-Quellcode:
case (ControlledSite) of
csLeft:
begin
TLO := RichEdit1O.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
ALO := RichEdit1O.ActiveLineNo;
PanelLeftFrame.Top := (((ALO - TLO) * 14) + 4);
lTag := (TLO);
if Assigned(BlocksCtrl) then
begin
D := MaxInt;
for I := 0 to BlocksCtrl.LineNumberListRight.Count - 1 do
begin
D_ := Abs(ALO - (BlocksCtrl.LineNumberListRight[I].LineNumber));
if (D_ < D) then
begin
ALR := I;
D := D_;
if (D = 0) then
begin
TLR := RichEdit1R.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
TLC := (I - (ALO - TLO));
if (TLC < 0) then
begin
TLC := 0;
end;
RichEdit1R.Perform(EM_LINESCROLL, 0, TLC - TLR);
TLR := RichEdit1R.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
rTag := TLR;
PanelRightFrame.Top := (((ALR - TLR) * 14) + 4);
PanelRightFrame.Visible := True;
if (RichEdit1R.CaretPos.Y <> ALR) then
RichEdit1R.CaretPos := TPoint.Create(0, ALR);
Break;
end;
end;
end;
if (D <> 0) then
begin
PanelRightFrame.Visible := False;
rTag := -1;
end;
if (ALO <= BlocksCtrl.LineNumberListLeft.Count - 1) then
BlocksCtrl.currentBlockNumber := BlocksCtrl.LineNumberListLeft[ALO].BlockNumber;
end;
end;
...