Recent

Author Topic: Create window dynamically in code  (Read 7879 times)

unistereo

  • New member
  • *
  • Posts: 9
Create window dynamically in code
« on: September 03, 2015, 10:04:58 pm »
Hi, I know this is silly, but I want to create a window strictly from code (so without any resource file). Yes I am an old school kind of guy.

I used the code below. It runs fine but it only shows the form with no border nor buttons (I am on Mac OSX).

First of all, am I doing this correctly, I mean regarding the resource-less aspect of it ?

Secondly, what is missing in order to get the full window with border & buttons ?

Thanks in advance!

Code: [Select]
program helloworld;
{$mode objfpc} {$H+}
 
uses Classes, Interfaces, Forms, StdCtrls, Controls;

type
  TForm1 = class(TForm)
    Button1: TButton;
  end;
 
var
  Form1: TForm1;
 
begin
  Application.Initialize;
  Form1 := TForm1.CreateNew(nil);
  Form1.Button1 := TButton.Create(Form1);
  With Form1.Button1 Do
  begin
    Parent := Form1;
    Visible := TRUE;
    Left := 10;
    Top := 10;
    Width := 100;
    Height := 100;
    Caption := 'PRESS ME';
  end;
  Form1.BorderStyle:= Controls.bsSizeable;
  Form1.show();
  Application.Run;
end.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me

unistereo

  • New member
  • *
  • Posts: 9
Re: Create window dynamically in code
« Reply #2 on: September 04, 2015, 02:13:38 pm »
Hi Thanks for replying. I have seen that page, as well as http://wiki.freepascal.org/Form_Tutorial#Creating_a_new_form_dynamically, from which my code is inspired.

The problem is that those pages are obsolete.

Running the source code given by those pages give the following error at runtime:
Quote
Form resource TMyForm not found. For resourceless forms CreateNew constructor must be used. See the global variable RequireDerivedFormResource.

My understanding is that something has been changed at one point regarding the use of TForm.Create / TForm.CreateNew. My knowledge of freepascal being a whopping 2 hours I fail to grasp the exact meaning and consequences of that transition, at least at this stage.

Yet I managed to modify the code given in the second URL to use TForm.CreatNew rather than TForm.Create and obtain a working version, but I just wanted to know whether what I've done was valid.

It obviously is not valid it since I don't get window borders & buttons.

Thanks in advance,

Using FPC 3.0.1 & Lazarus 1.4 on Mac
« Last Edit: September 04, 2015, 02:17:04 pm by unistereo »

derek.john.evans

  • Guest
Re: Create window dynamically in code
« Reply #3 on: September 04, 2015, 02:51:13 pm »
Your code works on Windows, but the app wont shutdown.

But, if I use:
Code: [Select]
Application.CreateForm(TForm1, Form1);  // not:  Form1 := TForm1.CreateNew(nil);   

The code shuts down correctly. Maybe this is the issue.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Create window dynamically in code
« Reply #4 on: September 04, 2015, 02:56:03 pm »
This code below works (at least for me):

Code: [Select]
procedure TfrmMain.ButtonTestClick(Sender: TObject);
var
  Form1: TForm;
  Button1: TButton;
begin
  Form1 := TForm.CreateNew(nil);
    Button1 := TButton.Create(Form1);
    With Button1 Do
    begin
      Parent := Form1;
      Visible := TRUE;
      Left := 10;
      Top := 10;
      Width := 100;
      Height := 100;
      Caption := 'PRESS ME';
    end;
    Form1.BorderStyle:= bsSizeable;
    Form1.ShowModal;
    Form1.Free;
end;

Put the code above in a button OnClick event (ButtonTest).

Note:
Button1 := TButton.Create(Form1)
BorderStyle:= bsSizeable;
Use ShowModal instead of Show

unistereo

  • New member
  • *
  • Posts: 9
Re: Create window dynamically in code
« Reply #5 on: September 04, 2015, 08:44:06 pm »
Hi guys,

If I use Application.CreateForm(...) I get the runtime error back ("Form resource TForm1 not found. For resourceless forms CreateNew constructor must be used. See the global variable RequireDerivedFormResource").
I don't know why it would happen on Mac and you don't get it on Windows.

Regarding the code posted by Handoko it works but the problem is the same as my code : it renders a bare form with no window borders/buttons. At least on Mac.

So to summarize, my goal was simply to run the code given at http://wiki.lazarus.freepascal.org/Using_the_LCL_without_Lazarus

As it did not work (it produces the error above) I searched for answers and came across http://wiki.freepascal.org/Form_Tutorial#Creating_a_new_form_dynamically. I modified my code to use that way of dynamically creating forms. It works but it does not show a full window.

As for the reason why CreateNew must be used instead of Create on the form, it is supposedly explained here:
http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-February/060229.html

I don't know. Maybe the simplest way to answer my question is: could someone update the code at http://wiki.lazarus.freepascal.org/Using_the_LCL_without_Lazarus to make it compatible with current FPC / Lazarus ?

Thanks you all,
« Last Edit: September 04, 2015, 08:54:50 pm by unistereo »

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Create window dynamically in code
« Reply #6 on: September 04, 2015, 08:56:34 pm »
Regarding the code posted by Handoko it works but the problem is the same as my code : it renders a bare form with no window borders/buttons. At least on Mac.

No window and buttons? I'm not sure what you mean. Can you please post a screenshot? I test my code, everything seems correctly running on my Ubuntu Linux 64-bit. Could it be a bug on Mac version?

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Create window dynamically in code
« Reply #7 on: September 04, 2015, 09:00:57 pm »
Here is the result on my desktop. A big "PRESS ME" button, with resizable form's borders:
« Last Edit: September 04, 2015, 09:03:58 pm by Handoko »

unistereo

  • New member
  • *
  • Posts: 9
Re: Create window dynamically in code
« Reply #8 on: September 04, 2015, 11:57:39 pm »
Okay here is a screenshot of what I got. Terminal shows code and executed commands.

Thanks

 

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Create window dynamically in code
« Reply #9 on: September 05, 2015, 04:57:36 am »
Okay, I guess you mean that you can't see the small icon buttons (minimize, maximize and close), which usually located at the title bar.

I don't use OSX nor Carbon widgetset. I also don't write Terminal programs. One possibility I can think is, the window buttons may actually exist, but because the form top position is 0 (zero), you may not able to see it. I use Ubuntu + Mate Desktop Environment (non-Ubuntu). I often experience forms being located to high that I can't the those window buttons.

I suggest you to test the code again but with top position added:
Form1.Top := 50;

So here is the code:
Code: [Select]
procedure TfrmMain.ButtonTestClick(Sender: TObject);
var
  Form1: TForm;
  Button1: TButton;
begin
  Form1 := TForm.CreateNew(nil);
    Form1.Top := 50;
    Button1 := TButton.Create(Form1);
    With Button1 Do
    begin
      Parent := Form1;
      Visible := TRUE;
      Left := 10;
      Top := 10;
      Width := 100;
      Height := 100;
      Caption := 'PRESS ME';
    end;
    Form1.BorderStyle:= bsSizeable;
    Form1.ShowModal;
    Form1.Free;
end;

About the resource error, nothing I can comment. And about the wiki pages, yes I found many of them aren't updated properly, we are lack of people to do it.

unistereo

  • New member
  • *
  • Posts: 9
Re: Create window dynamically in code
« Reply #10 on: September 05, 2015, 10:00:40 am »
Oh yeah you were right. Moving the window a few pixels lower indeeds reveal the window bar and buttons.
Woah now this is rocket science ;)

Does it respond to events in your case ?

Because I cannot move the window if I try to drag it. Looks like it doesn't catch mouse events or something.
The only thing that works is that I can close the window.

Anyway, I don't want to waste your time on this ... ;)

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Create window dynamically in code
« Reply #11 on: September 05, 2015, 10:21:53 am »
I used Ubuntu + Unity Desktop environment, never have such problem. But after I switched to Ubuntu + Mate Desktop environment, I often can't see the title bar and the buttons. So I think it's a compatibility issue between them.

Because I cannot move the window if I try to drag it. Looks like it doesn't catch mouse events or something.
The only thing that works is that I can close the window.

Anyway, I don't want to waste your time on this ... ;)

I can't drag the window too, because I can't click the title bar. Fortunately, Ubuntu users can configure shortcut for moving window to any key combination they like. I set [Alt] + [click] to move the window. So after the title bar appear, I can drag it (on the title bar).

No time is wasted, everyone earned.  :D

 

TinyPortal © 2005-2018