Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-09

Sample code needed to create form at runtime only (see mock up below).

13 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Peter E Williams

Hi All,

This is a rough mock-up of a TForm that I need to create at runtime only.

+------------------------------------------+
| Form caption |
+------------------------------------------+
|+------------------+S+-------------------+|
|| |P| ||
|| |L| ||
|| Memo1 |I| ||
|| (TMemo) |T| Image1 ||
|| |T| (TImage) ||
|| |E| ||
|| |R| ||
|| ||| ||
|+------------------+|| ||
|+--------++--------+|| ||
|| OK || Cancel ||| ||
|+--------++--------+|+-------------------+|
+--------------------+---------------------+

It contains a TSplitter (??? I have never used one of these before) vertically down the middle of the form.

On the left of the TSplitter there is a TMemo and below it 2 TButtons: OK_button (with modal result of mrOK), and Cancel_button (with a modal result of mrCancel). To the right of the the TSplitter I want a TImage.

I need some sample code to create this at runtime only.

Questions:
1) Does the Memo1, OK_Button and Cancel TButton need to be in a TGroupBox???
2) Also, should the TImage be in a TGroupBox???

Note: The Image1 will be loaded with an image passed as Image_filename (string). It may be: JPEG, GIF or PNG and the size (width and height) will vary... so you will need to read that from the file. Is this possible and are these image formats supported by Timage?

The idea of this form is that the user can resize the form and the TMemo and TImage will dynamically resize as the user adjusts the form's size properties.

Best Regards,
PEW
Hobart, Tasmania, Australia

Proudly developing Quality Cross Platform Open Source Games Since 1970 with a Commodore PET 4016 with 16 KRAM http://pews-freeware-games.org (<--- brand new)

Reply by email

Felipe Monteiro de Carvalho
to Peter E Williams
Peter E Williams wrote
Questions: 1) Does the Memo1, OK_Button and Cancel TButton need to be in a TGroupBox??? 2) Also, should the TImage be in a TGroupBox???

I think that to use the splitter you need to group the elements using a panel. I vaguely remember that if you have something like:

Panel 1 - Splitter - Panel 2

Then Panel 1 should have Align=alClient, Splitter.Align = alRight, Panel2.Align = alRight

Yes, a group box would probably do it as well, but the panel is just as good and can be configured to have no borders and the user won't note he is in the form.

Felipe Monteiro de Carvalho

Reply by email

Peter E Williams
to Felipe Monteiro de Carvalho

Hi Felipe and All,

Felipe Monteiro de Carvalho wrote 11 lines
On Sun, Sep 5, 2010 at 6:39 AM, Peter E Williams wrote: > Questions: > 1) Does the Memo1, OK_Button and Cancel TButton need to be in a > TGroupBox??? > 2) Also, should the TImage be in a TGroupBox??? I think that to use the splitter you need to group the elements using a panel. I vaguely remember that if you have something like: Panel 1 - Splitter - Panel 2

My question is:
How do I create a TForm and TSplitter and 2 x TPanel's at runtime?!?

I would guess something like:
{ this code is all untested and typed straight into my email client }

procedure create_formA(
  Image_filename : string; StringList1 : TStringList );
var
  FormA : TForm;
  Splitter1 : TSplitter;
  Panel1, Panel2 : TPanel;
  success_modal_result : boolean;
  OK_button, Cancel_button : TButton;
  Image1 : TImage;
begin
  FormA := TForm.Create; // Are there any parameters here????
  try
    FormA.caption := 'Image and Comments for ' + Image_filename;
    Splitter1 := TSplitter.Create( FormA );
    Splitter1.Parent := FormA;
    Splitter1.Visible := True;
    Splitter1.Align := alRight;
    // do I need to set any other properties like Height, Width, Top,
Left ???
    Panel1 := TPanel.Create( FormA );
    Panel1.Parent := FormA;
    Panel1.Visible := True;
    Panel1.Align := alClient;
    Memo1 := TMemo.Create( FormA );
    Memo1.Parent := Panel1;
    Memo1.Visible := True;
    Memo1.Align := ?????????
    // do I need to set any other properties like Height, Width, Top,
Left ???
    // will this work ????
    Memo1.Strings := StringList1.Strings;
    OK_Button := TButton.Create( FormA );
    OK_Button.Parent := FormA;
    OK_Button.Visible := True;
    OK_Button.ModalResult := mrOK;
    OK_Button.Align := ????????????
    // do I need to set any other properties like Height, Width, Top,
Left ???
    Cancel_Button := TButton.Create( FormA );
    Cancel_Button.Parent := FormA;
    Cancel_Button.Visible := True;
    Cancel_Button.ModalResult := mrCancel;
    Cancel_Button.Align := ??????????
    // do I need to set any other properties like Height, Width, Top,
Left ???
    Panel2 := TPanel.Create( FormA );
    Panel2.Parent := FormA;
    Panel2.Visible := True;
    Panel2.Align := alRight;
    Image1 := TImage.Create( FormA );
    Image1.Parent := Panel2;
    Image1.Visible := True;
    Image1.Align := ??????????
    // do I need to set any other properties like Height, Width, Top,
Left ???
    // will this work ????
    if FileExists ( Image_filename ) then
    begin
      Image1.Filename := Image_filename;
      Image1.LoadFromFile( Image_filename );
    end
    else
      showmessage( 'Error: Image filename "+ Image_filename + '" Cannot
be loaded because it does not exist.');
    // Showmodal the form!!!
    success_modal_result := (formA.showmodal = mrOK);
  finally
    FormA.free; // free the form
    // all the other components will automatically be freed because
    // they were created with FormA as their create parameter.
  end;
end;

I would appreciate it if anyone could be fill in the Align statement question marks and comment on the code below the comments "will this work ????".

Show quoted text 6 lines
Then Panel 1 should have Align=alClient, Splitter.Align = alRight, Panel2.Align = alRight Yes, a group box would probably do it as well, but the panel is just as good and can be configured to have no borders and the user won't note he is in the form.

Best Regards,
PEW
Hobart, Tasmania, Australia

Proudly developing Quality Cross Platform Open Source Games Since 1970 with a Commodore PET 4016 with 16 KRAM http://pews-freeware-games.org (<--- brand new)

Reply by email

Alberto Narduzzi
to Peter E Williams
Show quoted text 8 lines
I would guess something like: { this code is all untested and typed straight into my email client } procedure create_formA( Image_filename : string; StringList1 : TStringList ); var FormA : TForm; (...)

wouldn't it be better to define the form within the IDE, with all of its components; then exclude it from the autocreate forms list (remove also the Var Form1: TForm1 from the unit if you like...) and finally create/free an instance of it whenever needed, like:

you'll have already:
Type TFormA: Class(TForm)
blablabla

then you do

procedure create_formA(Image_filename :string; StringList1: TStringList);
var
   FormA : TFormA;
   success_modal_result : boolean;
begin
   try
     FormA := TFormA.Create; // Are there any parameters here????
     FormA.Memo1.Strings := StringList1.Strings;
     if FileExists ( Image_filename ) then
     begin
       FormA.Image1.Filename := Image_filename;
       FormA.Image1.LoadFromFile( Image_filename );
       success_modal_result := (formA.showmodal = mrOK);
     end
     else
       showmessage(format('Error: Image filename %s Cannot be loaded
because it does not exist.', [Image_filename]);
   finally
     FreeAndNil(FormA);
   end;
end;

Just my 2c, I would do so...

Cheers, A.

Reply by email

Felipe Monteiro de Carvalho
to Peter E Williams: My question is: How do I create a TForm and TSplitter and 2 x TPanel's at runtime?!? I…
?FormA := TForm.Create; // Are there any parameters here????

use:

FormA := TForm.Create(Application); if you want the form to be freed
when the program ends automatically
FormA := TForm.Create(nil); if you want to control where the form will be freed
? ?Splitter1.Align := alRight; ? ?// do I need to set any other properties like Height, Width, Top, Left ???

No, you can use either position variables or align, not both at the same time. Sometimes Top and Left before align can be useful I think, but I am not sure.

Show quoted text 6 lines
? ?Memo1 := TMemo.Create( FormA ); ? ?Memo1.Parent := Panel1; ? ?Memo1.Visible := True; ? ?Memo1.Align := ????????? ? ?// do I need to set any other properties like Height, Width, Top, Left ???

This doesn't matter. You can place this anywhere you want. Usually by specifying Height, Width, Top and Left and Align isn't used then.

The same for all other very similar questions in different controls inside the panels.

? ?// will this work ???? ? ?Memo1.Strings := StringList1.Strings;

No, it should probably be:

Memo1.Lines.Assign(StringList1);
? ?if FileExists ( Image_filename ) then <<<--- Unicode issue, use FileUtil.FileExists instead ? ?begin ? ? ?Image1.Filename := Image_filename; <<-- Wrong one ? ? ?Image1.LoadFromFile( Image_filename ); <<<--- Correct one

See also:

http://lazarus-ccr.sourceforge.net/docs/lcl/extctrls/tcustomimage.html

I don't think that TImage has a property FileName. You can use the Lazarus code editor to check which properties and methods are available in a class. Type "Image1." and wait a few seconds for the list of methods to appear. As you type more letters it will refine the list to show the ones that match your partial string.

Felipe Monteiro de Carvalho

Reply by email

Peter E Williams
to Alberto Narduzzi: wouldn't it be better to define the form within the IDE, with all of its components; then…

Hi Alberto and All,

Alberto Narduzzi wrote 13 lines
> I would guess something like: > { this code is all untested and typed straight into my email client } > > procedure create_formA( > Image_filename : string; StringList1 : TStringList ); > var > FormA : TForm; > (...) wouldn't it be better to define the form within the IDE, with all of its components; then exclude it from the autocreate forms list (remove also the Var Form1: TForm1 from the unit if you like...) and finally create/free an instance of it whenever needed, like:

Yes, it would be easier IFF (= IF and only IF) I understood how TSplitter, and 2 x TPanels worked when designing forms at design time (e.g. with the IDE). I don't understand and I find it confusing!!! That's why I want to add it using code at runtime instead.

Can't I just create my form on the fly and not use autocreate???

Show quoted text 34 lines
you'll have already: Type TFormA: Class(TForm) blablabla then you do procedure create_formA(Image_filename :string; StringList1: TStringList); var FormA : TFormA; success_modal_result : boolean; begin try FormA := TFormA.Create; // Are there any parameters here???? FormA.Memo1.Strings := StringList1.Strings; if FileExists ( Image_filename ) then begin FormA.Image1.Filename := Image_filename; FormA.Image1.LoadFromFile( Image_filename ); success_modal_result := (formA.showmodal = mrOK); end else showmessage(format('Error: Image filename %s Cannot be loaded because it does not exist.', [Image_filename]); finally FreeAndNil(FormA); end; end; Just my 2c, I would do so... Cheers, A.
Proudly developing Quality Cross Platform Open Source Games Since 1970 with a Commodore PET 4016 with 16 KRAM http://pews-freeware-games.org (<--- brand new)

Reply by email

Dimitri Smits
to Felipe Monteiro de Carvalho: use: FormA := TForm.Create(Application); if you want the form to be freed when the…

Hi,

you've got to love the IDE experts like GExperts in Delphi. There you define your form as you want it to be through the editor and then "export to code". In other words, a kind of "dfm"-writer that writes creation-initialization code in objpas/fpc-code to the clipboard.

maybe an idea for anybody with too much time on their hands to create for lazarus too? :-)

kind regards,
Dimitri Smits

----- "Felipe Monteiro de Carvalho" wrote 66 lines
> ?FormA := TForm.Create; // Are there any parameters here???? use: FormA := TForm.Create(Application); if you want the form to be freed when the program ends automatically FormA := TForm.Create(nil); if you want to control where the form will be freed > ? ?Splitter1.Align := alRight; > ? ?// do I need to set any other properties like Height, Width, Top, > Left ??? No, you can use either position variables or align, not both at the same time. Sometimes Top and Left before align can be useful I think, but I am not sure. > ? ?Memo1 := TMemo.Create( FormA ); > ? ?Memo1.Parent := Panel1; > ? ?Memo1.Visible := True; > ? ?Memo1.Align := ????????? > ? ?// do I need to set any other properties like Height, Width, Top, > Left ??? This doesn't matter. You can place this anywhere you want. Usually by specifying Height, Width, Top and Left and Align isn't used then. The same for all other very similar questions in different controls inside the panels. > ? ?// will this work ???? > > ? ?Memo1.Strings := StringList1.Strings; No, it should probably be: Memo1.Lines.Assign(StringList1); > ? ?if FileExists ( Image_filename ) then <<<--- Unicode issue, use FileUtil.FileExists instead > ? ?begin > ? ? ?Image1.Filename := Image_filename; <<-- Wrong one > ? ? ?Image1.LoadFromFile( Image_filename ); <<<--- Correct one See also: http://lazarus-ccr.sourceforge.net/docs/lcl/extctrls/tcustomimage.html I don't think that TImage has a property FileName. You can use the Lazarus code editor to check which properties and methods are available in a class. Type "Image1." and wait a few seconds for the list of methods to appear. As you type more letters it will refine the list to show the ones that match your partial string. -- Felipe Monteiro de Carvalho -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Hans-Peter Diettrich
to Dimitri Smits
you've got to love the IDE experts like GExperts in Delphi. There you define your form as you want it to be through the editor and then "export to code". In other words, a kind of "dfm"-writer that writes creation-initialization code in objpas/fpc-code to the clipboard.

This is how most *other* GUI designers work, lacking any useful *visual* form designer. In contrast Delphi allows to even create forms etc. at runtime, by using LoadComponentRes with e.g. an DFM file (not sure about the correct name). This approach allows to e.g. update the appearance of entire forms, without recompilation of the EXE, by only distributing new DFM files to the users. Dunno about equivalent Lazarus support...

But the preference of concrete code vs. abstract form descriptions is a matter of taste and habits. I for my part don't understand how one ever wants to write code for a GUI design, when the GUI also can be constructed in different, more intuitive and reusable form.

DoDi

Reply by email

Graeme Geldenhuys
to Dimitri Smits: you've got to love the IDE experts like GExperts in Delphi. There you define your form as…
Dimitri Smits wrote
you've got to love the IDE experts like GExperts in Delphi. There you define your form as you want it to be through the editor and then "export to code". In other words, a kind of "dfm"-writer that writes creation-initialization code in objpas/fpc-code to the clipboard.

You can always port that to Lazarus, just like I have done for a few other GExperts features. Then again, manually translating a dfm/lfm to code is a rather simple task, so I don't really know if it's worth the effort writing a tool to do that.

Long before GExperts I often used to select components in Delphi's form designed. Copy to clipboard, and paste in code - especially data aware components. Then translated them to Object Pascal code. The task was very easy.

eg:
lfm code (copied to clipboard from form designer)
------------------------------
object Button1: TButton
Left = 54
Height = 25
Top = 27
Width = 75
Caption = 'Hello'
TabOrder = 0
end
object Edit1: TEdit
Left = 56
Height = 25
Top = 64
Width = 80
TabOrder = 1
Text = 'Edit1'
end
------------------------------

...now translated to Object Pascal code...

---------------------------------------
Button1 := TButton.Create(self);
with Button1 do
begin
  Left := 54;
  Height := 25;
  Top := 27;
  Width := 75;
  Caption := 'Hello';
  TabOrder := 0;
end;
Edit1 := TEdit.Create(self);
with Edit1 do
begin
  Left := 56;
  Height := 25;
  Top := 64;
  Width := 80;
  TabOrder := 1;
  Text := 'Edit1';
end;
----------------------------------------

See, near identical. A quick regex search and replace is all that is required.

Regards, ? - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Graeme Geldenhuys
to Hans-Peter Diettrich: This is how most *other* GUI designers work, lacking any useful *visual* form designer.…
Hans-Peter Diettrich wrote
This is how most *other* GUI designers work, lacking any useful *visual* form designer.

fpGUI being the exception. :-) It has a useful Visual Forms Designer, and outputs Object Pascal code in the code unit itself, not in some external lfm or dfm file.

I'm pretty sure Mattias made some changes to Lazarus Form Designer recently, to allow for such customizations (I know you can use no LCL toolkits too) - not sure how easy it would be to implement though. I don't know the code.

Regards, ? - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Mattias Gaertner
to Graeme Geldenhuys
Show quoted text 12 lines
On 6 September 2010 05:44, Hans-Peter Diettrich wrote: > > This is how most *other* GUI designers work, lacking any useful *visual* > form designer. fpGUI being the exception. :-) It has a useful Visual Forms Designer, and outputs Object Pascal code in the code unit itself, not in some external lfm or dfm file. I'm pretty sure Mattias made some changes to Lazarus Form Designer recently, to allow for such customizations (I know you can use no LCL toolkits too)

Yes. Since last year. See here:

http://wiki.lazarus.freepascal.org/Extending_the_IDE#Writing_a_designer_mediator

But at the moment all class names must be unique. So you can not use a TForm, because the LCL already defines that.

- not sure how easy it would be to implement though. I don't know the code.

There is only a simple pascal stream writer, that does not stream DefineProperties. There is no pascal stream reader. So it should be easy to add a function to write a form/component as pascal code. Of course the missing DefineProperties is quite a show stopper for LCL controls. But maybe it is still helpful for some tasks.

Mattias

Reply by email

Mattias Gaertner
to Peter E Williams: My question is: How do I create a TForm and TSplitter and 2 x TPanel's at runtime?!? I…
Show quoted text 17 lines
Hi Felipe and All, On Sun, 2010-09-05 at 07:01 +0200, Felipe Monteiro de Carvalho wrote: > On Sun, Sep 5, 2010 at 6:39 AM, Peter E Williams > wrote: > > Questions: > > 1) Does the Memo1, OK_Button and Cancel TButton need to be in a > > TGroupBox??? > > 2) Also, should the TImage be in a TGroupBox??? > > I think that to use the splitter you need to group the elements using > a panel. I vaguely remember that if you have something like: > > Panel 1 - Splitter - Panel 2 My question is: How do I create a TForm and TSplitter and 2 x TPanel's at runtime?!?

I created an example here:
http://wiki.lazarus.freepascal.org/Working_with_TSplitter

Show quoted text 21 lines
I would guess something like: { this code is all untested and typed straight into my email client } procedure create_formA( Image_filename : string; StringList1 : TStringList ); var FormA : TForm; Splitter1 : TSplitter; Panel1, Panel2 : TPanel; success_modal_result : boolean; OK_button, Cancel_button : TButton; Image1 : TImage; begin FormA := TForm.Create; // Are there any parameters here???? try FormA.caption := 'Image and Comments for ' + Image_filename; Splitter1 := TSplitter.Create( FormA ); Splitter1.Parent := FormA; //Splitter1.Visible := True;

Visible=true is default.

Splitter1.Align := alRight; // do I need to set any other properties like Height, Width, Top, Left ???

You can set the Width.

Show quoted text 10 lines
Panel1 := TPanel.Create( FormA ); Panel1.Parent := FormA; Panel1.Visible := True; Panel1.Align := alClient; Memo1 := TMemo.Create( FormA ); Memo1.Parent := Panel1; Memo1.Visible := True; Memo1.Align := ?????????
Memo1.Align := alClient; // fill Panel1
// do I need to set any other properties like Height, Width, Top, Left ???

No.

// will this work ???? Memo1.Strings := StringList1.Strings;
Memo1.Lines := StringList1; // this calls Assign
Show quoted text 6 lines
OK_Button := TButton.Create( FormA ); OK_Button.Parent := FormA; OK_Button.Visible := True; OK_Button.ModalResult := mrOK; OK_Button.Align := ????????????

Don't know. Maybe you should put all the buttons into a TPanel or use TButtonPanel or use anchors.

See here:
http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Example:_a_button_panel

// do I need to set any other properties like Height, Width, Top, Left ???
Normally you do
OK_Button.AutoSize:=true;
[...]

Mattias

Reply by email

Mattias Gaertner
to Felipe Monteiro de Carvalho: On Sun, Sep 5, 2010 at 6:39 AM, Peter E Williams I think that to use the splitter you…
Show quoted text 9 lines
On Sun, Sep 5, 2010 at 6:39 AM, Peter E Williams wrote: > Questions: > 1) Does the Memo1, OK_Button and Cancel TButton need to be in a > TGroupBox??? > 2) Also, should the TImage be in a TGroupBox??? I think that to use the splitter you need to group the elements using a panel.

No. You can use anchors as well. Just set Splitter1.Align to alNone and anchor controls to it.

Show quoted text 10 lines
I vaguely remember that if you have something like: Panel 1 - Splitter - Panel 2 Then Panel 1 should have Align=alClient, Splitter.Align = alRight, Panel2.Align = alRight Yes, a group box would probably do it as well, but the panel is just as good and can be configured to have no borders and the user won't note he is in the form.

Mattias

Reply by email