Für diesen Fall würde ich dir
PascalScript von RemObjects empfehlen. Das kannst du auf der Seite kostenlos herunterladen und anschließend installieren. Ich schreibe mal schnell eine Kurzanleitung, wie du das dann für deinen Fall nutzen kannst.
Wir brauchen für unsere Form einen TButton, ein TEdit, ein TLabel und die TPSScript-Komponente, die nun oben in der Komponentenleiste zu finden sein sollte. Doppelklick auf den Button und folgenden Source übernehmen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TForm1.Button1Click(Sender: TObject); var Messages: String; X: Integer; begin PSScript1.Script.Text := 'var ' + 'X: Double; ' + 'begin ' + 'X := ' + Edit1.Text + '; ' + 'GetResult(X); ' + 'end. ';
if not (PSScript1.Compile) then begin for X := 0 to PSScript1.CompilerMessageCount - 1 do Messages := Messages + PSScript1.CompilerMessages[X].MessageToString + #13#10;
Label1.Caption := 'Fehler bei der Eingabe: ' + #13#10 + Messages; end; end; |
Was wurde hier gemacht? Zuerst wurde ein Script an PascalScript übergeben. Dieses Script besteht aus einer Variable X, dann der Rechnung, die in Edit1 steht und einem Funktionsaufruf von GetResult, bei dem X übergeben wird. Diese Funktion müssen wir gleich noch schreiben. Dann wird das Script durchen den Compiler von PascalScript gejagt. Sollten hierbei Fehler auftreten (Compile gibt False zurück), also falls der User eine ungültige Rechnung eingegeben hat, so werden die Fehler im Label1 angezeigt.
Nun wechseln wir wieder zu unserer Form, wählen die PSScript-Komponente aus, gehen im Objektinspektor auf Ereignisse und doppelklicken in das leere weiße Feld rechts von OnCompile. Der Quelltext springt nach vorne und wir nehmen folgenden Source:
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TForm1.PSScript1Compile(Sender: TPSScript); begin Sender.AddMethod(Self, @TForm1.GetResult, 'procedure GetResult(Val: Double);'); end; |
Wir sagen PascalScript dadurch, dass es eine Funktion GetResult gibt (bzw. gleich geben wird), diese ist eine Methode von unserer Form1. Erst jetzt ist es möglich, dass wir im oberen Stück Source, welches wir PascalScript übergeben, auf diese Funktion zugreifen. Fehlt uns also noch diese eine Funktion.
Wir scrollen nach ganz oben, wo wir folgenden Block finden und wie hier ersetzen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; Edit1: TEdit; PSScript1: TPSScript; procedure Button1Click(Sender: TObject); procedure PSScript1Compile(Sender: TPSScript); private procedure GetResult(Val: Double); public end; |
Die Funktion GetResult kann problemlos als privat deklariert werden, PascalScript findet sie trotzdem - sofern wir sie auch geschrieben haben und das kommt jetzt. Ein wenig weiter nach unten scrollen, bis wir
{$R *.dfm} finden. Dort brauchen wir dieses Stück Quelltext:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| {$R *.dfm}
procedure TForm1.GetResult(Val: Double); begin Label1.Caption := FloatToStr(Val); end; |
Nun sollte auch klar werden, was diese Funktion macht: Sie gibt das Ergebnis der Berechnung im Label1 aus, wie das auch sein sollte.
Damit sind wir auch schon fertig. Gibt der Anwender nun in das Edit zum Beispiel
sqrt(15*2) - Pi ein, so gibt unser Programm im Label 2,33563... aus. Das Programm funktioniert also wie gewünscht.
Einige Hinweise:
- Momentan können böse Anwender auch Script im Edit eingeben, der dann womöglich ausgeführt wird. Strichpunkte können so ein Indiz sein und sollten mit StringReplace entfernt werden.
- Will man eigene Funktionsnamen, wie z.B. WURZEL statts sqrt verwenden, so muss der Text im Edit vorher mit StringReplace entsprechend ersetzt werden.
- Das Tutorial wurde gerade eben geschrieben, ich habe auch gerade eben zum ersten Mal PascalScript verwendet, es kann also durchaus sein, dass es noch einfachere Varianten oder Dinge zum Beachten gibt. Aber für den Anfang sollte das reichen.
Grüße
GTA-Place
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)