Solved

Creating Dynamic GUI at runtime.

Posted on 2004-04-26
7
633 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
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

759 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now