Solved

Creating Dynamic GUI at runtime.

Posted on 2004-04-26
7
637 Views
Last Modified: 2010-04-05
OKay, in ma previous question, i learned how to read a custom script and execute it. (thx mokule).
My aim was to create Dynamic GUI at runtime. Like i press a button, it creates another button with name/caption etc.. and other controls/components.

i used the following code (mokule)
///TemplateForm: Array[1..300] of Tform2;
                                               //ignore the data n todata//
procedure TForm1.CollectGUIData(data,todata:string);
var
  str, PageName: string;
  bRead: boolean;
  f: TextFile;
  List:TStringList;
  i,TemplateID:integer;
begin
bRead := False;  // flag for reading
AssignFile(F,data);
Reset(F);
while not Eof(F) do
  begin
  Readln(F,str);
  if bRead then
    begin
    if Pos('@endnewpage',str) > 0 then // end of block found
      begin
      break;
      end
    else
      memo1.Lines.Add(str);
      TemplateForm[TemplateID]:= Tform2.Create(nil);
      for  i:=  0 to  memo1.Lines.Count -1 do begin
      if Pos('Label',memo1.Lines.Strings[i]) > 0 then
    Createlbl(11,13,'Caption','MyLabel1', TemplateForm[TemplateID]);
     
      end;


     TemplateForm[TemplateID].BorderStyle:=bsSizeable;
     TemplateForm[TemplateID].Align:= alNone;
     TemplateForm[TemplateID].Show;

    end
  else if Pos('@newpage',str) > 0 then // start of block found
    begin
// add counter here for not reading the first block but any other
    PageName:= split(str,'=',2);
    TemplateID:= strtoint(split(str,'=',3));
    bRead := True;
    end;
  end;
CloseFile(F);
end;
////////////////the txt file script
@newpage=My New Page Title=1
 Label 11 16 Caption MyName
 Label 12 22 MyCaption MyName2
@endnewpage=1
///////////////////////////////
the above code isolates the lines between @newpage and @endnewpage into a memo. and it reads all the lines beginning with Label.
Since 2 labels are in the script. it creats a form with 2 labels at their specified cordinates - Top/Left.

now the problem is here...
With every new control a new form is created. Like in One form Label of name = MyName is created and in another form Label with MyName and MyName2 is created.
To sum it up.. the no of controls is equal to the no. of forms created.  I want only one form with those 2 controls.

i found that when i simply create  a form with 3 controls. it works fine .. but when i read it from memo, like in the above code and use For := 0 to memo.lines.count - 1 it creates many forms.

sum help here is appreciated. I wouldnt mind any one putting up there createlbl(); code
0
Comment
Question by:sesycelina
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 17

Assisted Solution

by:mokule
mokule earned 20 total points
ID: 10916492
This should be not in loop reading file, but after reading (after CloseFile fx)

      TemplateForm[TemplateID]:= Tform2.Create(nil);
      for  i:=  0 to  memo1.Lines.Count -1 do begin
      if Pos('Label',memo1.Lines.Strings[i]) > 0 then
    Createlbl(11,13,'Caption','MyLabel1', TemplateForm[TemplateID]);
     
      end;


     TemplateForm[TemplateID].BorderStyle:=bsSizeable;
     TemplateForm[TemplateID].Align:= alNone;
     TemplateForm[TemplateID].Show;

0
 
LVL 3

Accepted Solution

by:
Kunfufaresi earned 30 total points
ID: 10916528
Hello,

I once created something like that in a file named form.dat you can paste this
E ; Name:          ; 120 ; 30 ;  30 ; 200
E ; Surname:       ; 120 ; 30 ;  70 ; 200
C ; City / State:  ; 120 ; 30 ; 110 ; 200 ; Istanbul,Ankara,Izmir,Edirne
X ; Do you agree?: ; 120 ; 30 ; 150 ; 200
 
and the formcreate is

procedure TForm1.FormCreate(Sender: TObject);
var
 t:TextFile;
 s:String;
 xEdit : TEdit;
 xLabel : TLabel;
 xButton : TButton;
 xCheckBox : TCheckBox;
 xComboBox : TComboBox;
 ts,ts2 : TStringList;

begin
 appdir:=extractfiledir(application.exename)+'\';

 if fileexists(appdir+'form.dat') then
 begin
  AssignFile(t,appdir+'form.dat');
  reset(t);
  ts := TStringList.Create;
  repeat
   readln(t,s);
   ts.clear;
   split(s,';',ts);

   if trim(ts[0])='E' then
   begin
    xLabel := TLabel.Create(form1);
    xLabel.Left        := strtoint(trim(ts[3]));
    xLabel.Top         := strtoint(trim(ts[4]));
    xLabel.AutoSize    := TRUE;
    xLabel.Height      := 21;
    xLabel.parent      := Form1;
    xLabel.Visible     := TRUE;
//   xLabel.Name        := s;
    xLabel.Caption     := trim(ts[1]);


    xEdit := TEdit.Create(form1);
    xEdit.Left        := xLabel.Left+ strtoint(trim(ts[2])) + 5;
    xEdit.Top         := xLabel.Top - 3;
    xEdit.Width       := strtoint(trim(ts[5]));
    xEdit.Height      := 21;
    xEdit.parent      := form1;
    xEdit.Visible     := TRUE;
//   xEdit.OnMouseDown := xMouseDown;
//   xEdit.OnMouseMove := xMouseMove;
//   xEdit.OnMouseUp   := xMouseUp;
//   xEdit.ReadOnly    := TRUE;
    xEdit.Enabled     := TRUE;
//   xEdit.Name        := s;
//   xEdit.Text        := s;
//   xEdit.Enabled     := FALSE;
   end;

   if trim(ts[0])='X' then
   begin
    xLabel := TLabel.Create(form1);
    xLabel.Left        := strtoint(trim(ts[3]));
    xLabel.Top         := strtoint(trim(ts[4]));
    xLabel.AutoSize    := TRUE;
    xLabel.Height      := 21;
    xLabel.parent      := Form1;
    xLabel.Visible     := TRUE;
//   xLabel.Name        := s;
    xLabel.Caption     := trim(ts[1]);


    xCheckBox := TCheckBox.Create(form1);
    xCheckBox.Left        := xLabel.Left+ strtoint(trim(ts[2])) + 5;
    xCheckBox.Top         := xLabel.Top - 3;
    xCheckBox.Width       := strtoint(trim(ts[5]));
    xCheckBox.Height      := 21;
    xCheckBox.parent      := form1;
    xCheckBox.Visible     := TRUE;
//   xCheckBox.OnMouseDown := xMouseDown;
//   xCheckBox.OnMouseMove := xMouseMove;
//   xCheckBox.OnMouseUp   := xMouseUp;
//   xCheckBox.ReadOnly    := TRUE;
    xCheckBox.Enabled     := TRUE;
//   xCheckBox.Name        := s;
//   xCheckBox.Text        := s;
//   xCheckBox.Enabled     := FALSE;
   end;

   if trim(ts[0])='C' then
   begin
    xLabel := TLabel.Create(form1);
    xLabel.Left        := strtoint(trim(ts[3]));
    xLabel.Top         := strtoint(trim(ts[4]));
    xLabel.AutoSize    := TRUE;
    xLabel.Height      := 21;
    xLabel.parent      := Form1;
    xLabel.Visible     := TRUE;
//   xLabel.Name        := s;
    xLabel.Caption     := trim(ts[1]);


    xComboBox := TComboBox.Create(form1);
    xComboBox.Left        := xLabel.Left+ strtoint(trim(ts[2])) + 5;
    xComboBox.Top         := xLabel.Top - 3;
    xComboBox.Width       := strtoint(trim(ts[5]));
    xComboBox.Height      := 21;
    xComboBox.parent      := form1;
    xComboBox.Visible     := TRUE;
    Split(trim(ts[6]),',',xComboBox.Items);
    xComboBox.Text := 'Please Select';
   
//   xComboBox.OnMouseDown := xMouseDown;
//   xComboBox.OnMouseMove := xMouseMove;
//   xComboBox.OnMouseUp   := xMouseUp;
//   xComboBox.ReadOnly    := TRUE;
    xComboBox.Enabled     := TRUE;
//   xComboBox.Name        := s;
//   xComboBox.Text        := s;
//   xComboBox.Enabled     := FALSE;
   end;

  until eof(t);
  closefile(t);
 end;
end;

All apeare on the same form because of

TComboBox.Create(form1);

Kunfu Faresi
0
 
LVL 3

Expert Comment

by:Kunfufaresi
ID: 10916547
ok and you would need split

procedure Split(aValue : string; aDelimiter : Char; Result : TStrings);
var
  X : Integer;
  S : string;
begin
  if Result = nil then Result := TStringList.Create;
  Result.Clear;
  S := '';
  for X:=1 to Length(aValue) do begin
    if aValue[X] <> aDelimiter then
      S:=S + aValue[X]
    else begin
      Result.Add(S);
      S := '';
    end;
  end;
  if S <> '' then Result.Add(S);
end;

Kunfu Faresi
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:sesycelina
ID: 10916726
hey thx. i got it now. Kunfu Faresi, i had most of that figured out. It was pretty foolish of me to place the code in da loop. mokula thx again...

Last question concerning this.
my TemplateForm is
TemplateForm : Array[0..300] of Tform2;

and i retrived the Template[ID] from the txt file.
How will i be able to figure out that Template[{ID}] has been already created. so that it would be created again.

Like TemplateForm[1]. it will be created on first call. In the second call, it should check to see whether 1=form is created or not. Is there any inbuilt system proc to check this.

or should i simply use TStringList and add the TemplateID and compare it when FormCreation is called?

thx
celina
0
 
LVL 17

Expert Comment

by:mokule
ID: 10916809
You can fill TemplateForm with nil and then check.
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 10917127

  use ini file
   for example

  [Form1]
  Color=clBlue
  Left=200
 
  [Form1Label1]
  Caption=Test

  then

     uses IniFiles.... etc
0
 
LVL 3

Expert Comment

by:Kunfufaresi
ID: 10917464
hello

you can also

TemplateForm : Array[0..300] of Record
                                                 form:Tform2;
                                                 inuse:boolean;
                                               end;

then you could in the begining set all inuse to false and later turn it to true while creating them. but
if templateform[0]<>null then ... should work too i think

Kunfu Faresi
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question