Hallo Forum,
ich wollte Euch auf dem laufenden halten. Die ganze Diskussion Zeiger, 32-Bit und 64-Bit scheint mir recht müßig zu sein. Punkt ist auf einem System gehen Teile von Pascalscript die auf anderen nicht funktionieren. Wer eine Anwendung mit Pascalscript ausstattet und auf unterschiedlichen Plattformen arbeiten will muss hier sehr aufpassen. Meine Vorgehensweise war jetzt die Schnittmenge von mir verfügbaren Systemen zu bilden, d.h. das System mit dem geringeren Befehlsumfang so zu erweitern, dass es überall läuft. Die beiden Plattformen, die ich dabei ausprobiert habe sind WinXP 32-Bit und linux 64-Bit, dabei ist linux das Host-System mit einem WinXP in der VirtualBox. WinXP hat sich als das System mit dem geringeren Befehlsumfang (in Bezug auf Pascalscript) erwiesen. Also fehlende Befehle in WinXP einbauen und danach unter Linux testen ob der Code kompatibel ist. Folgende Punkte habe ich bisher herausgefunden:
- 1. Funktionen (in Lazarus implementiert und in PascalScript freigegeben) sind mit Vorsicht zu genießen. Es empfiehlt sich statt dessen Prozeduren mit var-Parametern zu verwenden wenn man Rückgabewerte im Script braucht.
2. TForm ist dem Script zwar bekannt, aber nicht alles funktioniert (bisher weiß ich das Width, Height, Parent, BringToFront, Free, Font, Create und CreateNew nicht funktionieren)
3. Der Konstructor der Komponenten scheint nicht zu funktionieren (bisher gefunden bei TLabel, TEdit, TButton und TGroupBox)
4. Events von visuellen Komponenten können nur über Umwege abgefangen werden (siehe vorherige Beiträge).
Aber nochmals ich finde PascalScript nicht schlecht(Schleifen, Bedingungen, Variablen, Unterprogramme wollte ich nicht neu erfinden), aber es fehlt eine gescheite Doku, mit Hinweisen zu den Stolpersteinen.
Ich poste hier die Erweiterungen im Quell-Code der unter den beiden Plattformen (WinXP 32-Bit und linux 64-Bit) getestet ist.
Lazarus-Code:
Code: Alles auswählen
procedure Teditor.CreateForm(var AName: string; var AForm: TForm);
begin
while (slNamedForms.IndexOf(AName)<>-1) do
AName := AName +'1';
AForm := TForm.Create(self);
AForm.Name := AName;
slNamedForms.AddObject(AName,AForm);
end;
procedure Teditor.SetFormSize(AForm: TForm; AWidth, AHeight: integer);
begin
if AWidth <> -1 then
AForm.Width := AWidth;
if AHeight <> -1 then
AForm.Height := AHeight;
end;
procedure Teditor.FreeForm(AForm: TForm);
Var
i : integer;
begin
if slNamedForms.IndexOfObject(AForm) <> -1 then
begin
for i := 0 to AForm.ComponentCount - 1 do
AForm.Components[i].Free;
slNamedForms.Delete(slNamedForms.IndexOfObject(AForm));
AForm.Free;
end;
end;
procedure Teditor.GetFormFont(AForm: TForm; var FFont: TFont);
begin
FFont := AForm.Font;
end;
procedure Teditor.MakeFrontMost(AForm: TForm);
begin
// AForm.BringToFront;
SetForegroundWindow(AForm.Handle);
end;
procedure Teditor.CreateGroupBox(AOwner: TWinControl; var AGroupBox: TGroupBox);
begin
AGroupBox := TGroupBox.Create(AOwner);
AGroupBox.Parent := AOwner;
end;
procedure Teditor.CreateLabel(AOwner: TWinControl; var ALabel: TLabel);
begin
ALabel := TLabel.Create(AOwner);
ALabel.Parent := AOwner;
end;
procedure Teditor.CreateButton(AOwner: TWinControl; var AButton: TButton);
begin
AButton := TButton.Create(AOwner);
AButton.Parent := AOwner;
end;
procedure Teditor.CreateEdit(AOwner: TWinControl; var AEdit: TEdit);
begin
AEdit := TEdit.Create(AOwner);
AEdit.Parent := AOwner;
end;
procedure TEditor.SetOnClick(ACtrl : TControl);
begin
ACtrl.OnClick:=@ClickEvent;
end;
procedure Teditor.ClickEvent(Sender: TObject);
begin
// ShowMessage('Gedrückt: '+TComponent(Sender).Name);
ClickSender:=TComponent(Sender).Name;
end;
procedure Teditor.GetClickSender(var s : string);
begin
s := ClickSender;
end;
procedure Teditor.ResetClickSender;
begin
ClickSender := '';
end;
procedure Teditor.ceCompile(Sender: TPSScript);
Var
i : integer;
begin
for i := 0 to slNamedForms.Count - 1 do
begin
TForm(slNamedForms.Objects[i]).Free;
end;
slNamedForms.Clear;
Sender.AddMethod(Self, @TEditor.Writeln, 'procedure writeln(s: string)');
Sender.AddMethod(Self, @TEditor.Readln, 'procedure readln(var s: string)');
Sender.AddRegisteredVariable('Self', 'TForm');
Sender.AddRegisteredVariable('Application', 'TApplication');
Sender.AddMethod(Self, @TEditor.CreateForm, 'procedure CreateForm(var AName: string; var AForm: TForm)');
Sender.AddMethod(Self, @TEditor.SetFormSize, 'procedure SetFormSize(AForm: TForm; AWidth, AHeight: integer)');
Sender.AddMethod(Self, @TEditor.FreeForm, 'procedure FreeForm(AForm: TForm)');
Sender.AddMethod(Self, @TEditor.GetFormFont, 'procedure GetFormFont(AForm: TForm; var FFont: TFont)');
Sender.AddMethod(Self, @TEditor.MakeFrontMost, 'procedure MakeFrontMost(AForm: TForm)');
Sender.AddMethod(Self, @TEditor.CreateGroupBox, 'procedure CreateGroupBox(AOwner: TWinControl; var AGroupBox: TGroupBox)');
Sender.AddMethod(Self, @TEditor.CreateLabel, 'procedure CreateLabel(AOwner: TWinControl; var ALabel: TLabel)');
Sender.AddMethod(Self, @TEditor.CreateButton, 'procedure CreateButton(AOwner: TWinControl; var AButton: TButton)');
Sender.AddMethod(Self, @TEditor.CreateEdit, 'procedure CreateEdit(AOwner: TWinControl; var AEdit: TEdit)');
Sender.AddMethod(Self, @TEditor.SetOnClick, 'procedure SetOnClick(ACtrl : TControl)');
Sender.AddMethod(Self, @TEditor.GetClickSender, 'procedure GetClickSender(var s: string)');
Sender.AddMethod(Self, @TEditor.ResetClickSender, 'procedure ResetClickSender');
end;
Pascal-Script-Code:
Code: Alles auswählen
Program test;
Var
s : string;
F : TForm;
L : TLabel;
B : TButton;
E : TEdit;
Vis : Boolean;
dwawF : TForm;
dwawB : TButton;
GB: TGroupBox;
FF : TFont;
procedure dwawShow(AFCap, ABCap, ABName: string);
var
dwawS : string;
begin
dwawS := 'dwawForm';
CreateForm(dwawS,dwawF); // Erzeugen des Formulars
dwawF.Caption := AFCap;
SetFormSize(dwawF,170,40);
dwawF.Position := poMainFormCenter;
CreateButton(TWinControl(dwawF),dwawB);
dwawB.Name := ABName;
dwawB.Caption := ABCap;
dwawB.Top:= 10;
dwawB.Left := 10;
dwawB.Width := 150;
SetOnClick(TControl(dwawB)); // Einrichten des "Click"-Events für den Button
dwawF.Show;
MakeFrontMost(dwawF);
end;
procedure dwawRemove;
begin
dwawF.Hide;
dwawB.Free;
FreeForm(dwawF);
end;
procedure CloseF; // Schließt das Formular wieder
begin
s := E.Text;
F.Close;
end;
begin
s:= 'MyForm';
CreateForm(s,F); // Erzeugen des Formulars
GetFormFont(F,FF); // Formular-Font ermitteln
FF.Size := 13; // Globale Änderung der Font.Size
F.Caption := s;
CreateGroupBox(TWinControl(F),GB); // Erzeugen einer GroupBox im Formular
GB.Caption := 'Alles meins';
GB.Height := 200;
CreateLabel(TWinControl(GB),L); // Erzeugen eines Labels in der Groupbox
L.Caption := 'Hallo';
L.Left := 10;
L.Top := 10;
CreateButton(TWinControl(GB),B); // Erzeugen eines Buttons in der GroupBox
B.Name := 'ButMe'; // Der Name ist für das Abfangen des "Click"-Events wichtig.
B.Caption := 'Push Me';
B.Top := 40;
B.Left := 10;
CreateEdit(TWinControl(GB),E); // Erzeugen eines Editier-Feldes in der GroupBox
E.Top := 70;
E.Left := 10;
E.Text := 'empty';
SetOnClick(TControl(B)); // Einrichten des "Click"-Events für den Button
Vis := True; // Flag für die Sichtbarkeit des Formulars
F.Show;
while Vis do // Programm-Schleife solange Vis gesetzt ist.
begin
GetClickSender(s); // Namen eines möglichen Click-Senders ermitteln.
if s <> '' then
begin
case s of
'ButMe': begin
CloseF; // Wenn der Click-Sender "ButMe" ist Formular schließen
dwawShow('Hallo', 'BumbMe', 'Bumper');
end;
'Bumper': begin
Vis := False;
dwawRemove;
end;
end;
ResetClickSender; // Zurücksetzen des ClickSenders
end;
Application.HandleMessage; // Abarbeiten anderer Events
end;
end.