PDA

View Full Version : creating on click at runtime



StevenV
05-09-2014, 04:11 PM
i'm trying to make an onclick event for a dynamical form. But it won't work, it alsways gives an error 'identifier not found'
i've searched around on different places and i used their help but nothing seemed to help me out

here is the script:

unit unit22;

{$mode objfpc}{$H+}

interface


uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

{ TForm2 }

TForm2 = class(TForm)
Procedure Nieuw(Sender: TObject);
private
{ private declarations }

public
{ public declarations }


end;
var
Form2: TForm2;
Label2: Tlabel;
Button2: Tbutton;
Labels: Array of TLabel;
Buttons: Array of Tbutton;
i: integer;
AantalStammen: integer;
Stammen: Array of String;

Procedure Test2;



implementation

Procedure TForm2.Nieuw(Sender: TObject);
begin
showmessage('nieuwe stam');
end;

Procedure Test2;
begin

SetLength(Labels, AantalStammen-1);
SetLength(Buttons, 3);
if AantalStammen>1 then
for i:= 0 to AantalStammen-1 do
begin
Labels[i]:=TLabel.Create(Label2);
try
with Labels[i] do
begin
Parent:=Form2;
Left:=50;
Top:=10+25*(i);
Labels[i].Caption:= Stammen[i] ;
end;
except
Labels[i].Free;
end;
end;

Form2.height:=AantalStammen*25+75;
for i:= 0 to 2 do
begin
Buttons[i]:=Tbutton.Create(Button2);
try
with Buttons[i] do
begin
Buttons[i].Parent:=Form2;
Buttons[i].width:=100;
Buttons[i].height:=25;
Buttons[i].Left:=25+(125*i);
Buttons[i].Top:=Form2.height-50;

end;
except
Buttons[i].Free;
end;
end;
Buttons[0].Caption:= 'Nieuw';
Buttons[1].Caption:= 'Wijzigen';
Buttons[2].Caption:= 'Sluiten';
Buttons[0].OnClick:= Nieuw;

Form2.width:=3*125+25;
Form2.show;
end;


{$R *.lfm}

end.

Brandon
05-09-2014, 07:55 PM
You didn't call TForm2.Create?

StevenV
05-09-2014, 08:23 PM
This is my main script, through which i call Tform2 with a button:

unit unit21;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, unit22;

type

{ TForm1 }

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;

var
Form1: TForm1;
UserFile : TextFile;
FileName, TFile : String;


implementation

{$R *.lfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
i: integer;
Begin
i:=0;
GetDir(0,Filename);
Filename:= Filename+'\Stammen.txt';
AssignFile(UserFile,Filename);
If not fileexists(Filename) then
Rewrite(UserFile);
Reset(UserFile);
Repeat
setlength(stammen,i+1);
Readln(UserFile,TFile);
stammen[i]:= Tfile;
i:= i +1;
Until Eof(UserFile);
AantalStammen:=i;
//showmessage('stammen:'+inttostr(AantalStammen));
Test2;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin

end;

end.

StevenV
05-09-2014, 08:26 PM
I've added Tform.create but didn't help

unit unit22;

{$mode objfpc}{$H+}

interface


uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

{ TForm2 }

TForm2 = class(TForm)
//Procedure Nieuw(Sender: TObject);
private
{ private declarations }

public
{ public declarations }

end;


var
Form2: TForm2;
Label2: Tlabel;
Button2: Tbutton;
Labels: Array of TLabel;
Buttons: Array of Tbutton;
i: integer;
AantalStammen: integer;
Stammen: Array of String;

Procedure Test2;



implementation

Procedure Nieuw(Sender: TObject);
begin
showmessage('nieuwe stam');
end;

Procedure Test2;
begin
Form2:= TForm2.create(nil);
SetLength(Labels, AantalStammen-1);
SetLength(Buttons, 3);
if AantalStammen>1 then
for i:= 0 to AantalStammen-1 do
begin
Labels[i]:=TLabel.Create(Label2);
try
with Labels[i] do
begin
Parent:=Form2;
Left:=50;
Top:=10+25*(i);
Labels[i].Caption:= Stammen[i] ;
end;
except
Labels[i].Free;
end;
end;

Form2.height:=AantalStammen*25+75;
for i:= 0 to 2 do
begin
Buttons[i]:=Tbutton.Create(Button2);
try
with Buttons[i] do
begin
Buttons[i].Parent:=Form2;
Buttons[i].width:=100;
Buttons[i].height:=25;
Buttons[i].Left:=25+(125*i);
Buttons[i].Top:=Form2.height-50;

end;
except
Buttons[i].Free;
end;
end;
Buttons[0].Caption:= 'Nieuw';
Buttons[1].Caption:= 'Wijzigen';
Buttons[2].Caption:= 'Sluiten';
Buttons[0].OnClick:= Nieuw;

Form2.width:=3*125+25;
Form2.show;
end;


{$R *.lfm}

end.

StevenV
05-14-2014, 12:33 PM
This has been solved using a pointer

type
TMethodPointer = packed record
pMethod: Pointer;
pObject: TObject;
end;

var
methodPointer: TMethodPointer;

in the code right before the event i place this (and make your onclick procedure):
methodPointer.pMethod := @Onclickprocedure;
methodPointer.pObject := nil;
Buttons[0].OnClick:= TNotifyEvent(methodPointer);

StevenV
05-14-2014, 12:38 PM
during the process of my program i will encounter several problems and now i have encountered this on:

during the creation of the program i will need to alter the main form.
My main form excists out of multiple buttons. But during the process i might add a few nieuw ones.
I would like to be able to changes the mainform at runtime.
If you start a new application then the mainform already has been made. But i would like to add buttons manually to the form.
But if i try this code then the mainform does not show the created components.
I have done some research. Their is stated that it's not possible to change the main form.
It should be created using Form1 := TForm1.Create(nil) instead of application.create(Tform1,form1) i've tried but it does not work. An other way is to hide the main form and use the 2nd as false mainform, but i haven't found a good explanation on how to do so

This would be the code :

begin
NrOfButtons:= 4;
setlength(buttons,NrOfButtons+1);

for i:= 1 to NrOfButtons do
begin
Buttons[i]:=Tbutton.Create(Button2);
try
with Buttons[i] do
begin
Buttons[i].Parent:=Form1;
Buttons[i].width:=100;
Buttons[i].height:=25;
Buttons[i].Top:= 25 + Buttons[i-1].Top+Buttons[i-1].height+15;
end;
except
Buttons[i].Free;
end;
end;
Buttons[1].Caption:='Gehouden Stammen';
Buttons[4].OnClick:= TNotifyEvent(methodPointer);
methodPointer.pMethod := @GehoudenStammen;
methodPointer.pObject := nil;
Buttons[2].Caption:='Nieuwe data';
Buttons[3].Caption:='Print';
Buttons[4].Caption:='Close';
Buttons[4].OnClick:= TNotifyEvent(methodPointer);
methodPointer.pMethod := @Close;
methodPointer.pObject := nil;
Form1.height:=25 + Buttons[length(buttons)].Top+Buttons[length(buttons)].height+15
end.