Ich würde zunächst ein temporäre Liste (LButtons: TList) mit allen Buttons mit füllen. Diese Liste würde ich sortieren und zwar mit einer Vergleichsfunktionen die dafür sorgt, dass die Buttons entsprechend der (gedachten) Zeile und Spalte bewertet werden. Ein Button ist dann in einer anderen Zeile, wenn seine Y-Position mindestens um die Höhe des Buttons von dem anderen Button abweicht.
Delphi-Quellcode:
function BtnCompare(P1, P2: Pointer): Integer;
var
btn1, btn2: TBitButton;
begin
btn1 := TObject(P1) as TBitButton;
btn2 := TObject(P2) as TBitButton;
if btn1.Top>btn2.Top+btn2.Height
then // btn1 ist tiefer als btn2
Result := 1
else
if btn1.Top+btn1.Height<btn2.Top
then // btn1 ist höher als btn2
Result := -1
else // die beiden Knöpfe sind in der gleichen Zeile
Result := btn2.Left-btn1.Left;
end;
Nachdem ich nun ein Liste habe, in der die Buttons in der Lese-Reihenfolgen geordnet sind, brauche ich nur noch durch die Liste zu gehen und alle Taborder-Werte gleich dem Index zu setzen.
Delphi-Quellcode:
for i:=0 to LButtons.Count-1 do
TBitButton(LButtons[i]).TabOrder := i;
Danach kann die temporäre Liste wieder frei geben werden.