Hi,
ich möchte aus Spaß einen kleinen Terminal programmieren der auf Canvas basiert. Damit man am Ende auch noch alle Befehle im Griff hat und sich da nichts dumm zusammensuchen muss, ergab sich folgendes System:
Delphi-Quellcode:
type
TDynIntArray = Array of Integer;
TDynChrArray = Array of Char;
TScreen = record
X, Y : TDynIntArray;
Text : TDynChrArray;
end;
TfrmMain = class(TForm)
...
private
{ Private-Deklarationen }
Befehle : Array of TScreen;
pX : Integer;
public
{ Public-Deklarationen }
end;
Jeder Befehl enthält einen record namens Screen. In Screen wird jedes zum Befehl gehörige Zeichen inklusive X- und Y-Position gespeichert. Dieses System muss genauso sein, damit der Terminal automatische Zeilenumbrüche (Vermeiden von Schreiben über den Rand hinaus) beherrscht. Im folgenden Codeabschnitt werden X, Y und aktuelles Zeichen des Screens des aktuellen Befehls befüllt:
Delphi-Quellcode:
procedure TfrmMain.FormKeyPress(Sender: TObject; var Key: Char);
begin
with Befehle[High(Befehle)] do
begin
SetLength(X, Length(X)+1);
X[High(X)] := pX; // eintragen des aktuellen X-Wertes
inc(pX); // erhöhen des X-Wertes für das nächste Mal
SetLength(Y, Length(Y)+1);
if X[High(X)]*7 >= ClientWidth-4 then // Alle Textzeichen sind 7 Pixel breit. Wenn der aktuelle X-Wert >= der Zeichenflächenbreite ist, muss umgebrochen werden
begin
Y[High(Y)] := Y[High(Y)-1]+1; // der letzte Y-Wert wird aufgegriffen und um 1 erhöht
X[High(X)] := 0; // da der aktuelle X-Wert außerhalb des Fensters liegt, muss er noch auf 0 verschoben werden, damit er in der nächsten Zeile am Zeilenanfang steht
SetLength(Text, Length(Text)+1);
Text[High(Text)] := Key; // das aktuelle Zeichen hinzufügen
pX := 1; // da das Zeichen bei X=0 schon belegt ist, geht es bei X=1 weiter
end else
begin
Y[High(Y)] := Y[High(Y)-1]; // wenn es nicht nötig ist, umzubrechen, wird der letzte Y-Wert genommen
SetLength(Text, Length(Text)+1);
Text[High(Text)] := Key; // das aktuelle Zeichen hinzufügen
end;
end;
Repaint; // neu zeichnen um den Text auf die Zeichenfläche zu bringen
end;
Der Code funktioniert. Aber was passiert, wenn man das Fenster vergrößert ? Neben dem Text entsteht ein Freiraum. Was passiert, wenn man das Fenster verkleinert ? Ein Teil des Textes ist nicht mehr sichtbar. Ich muss nun die X- und Y-Werte anpassen. Man könnte die X-Werte in ein temporäres 1D-Array packen und dort weiterverarbeiten. Aber wie verarbeitet man es weiter ? Abgesehen davon muss das zugehörige Y-Array auch noch angepasst werden. Habt ihr eine Idee, wie man die Fensterskalierung gut lösen könnte ?
Delphi-Quellcode:
procedure TfrmMain.FormResize(Sender: TObject);
var Alt, DifW, i : Integer; // Alt=Alte Fensterbreite; DifW=Differenz zwischen neuer und alter Breite
tmp : TDynIntArray;
begin
Alt := Width;
Width := Round((Alt div 7)*7)+1;
DifW := (Alt - Width) div 7;
for i := 0 to High(Befehle) do
begin
tmp := Befehle[i].X;
end;
SetLength(tmp, 0);
Repaint;
end;