Recent

Author Topic: Program flow  (Read 3809 times)

lewhite

  • Newbie
  • Posts: 1
Program flow
« on: September 26, 2017, 01:49:20 am »
I'm trying to find examples of program flow in the documentation.  Where do I find illustrations of using (as examples) application.run or application.terminate or application.xxxx topics? If I have some code I want run after the main form has been created but the form is displayed, where do I put it?.  If I used multiple forms, is there a formx.show or something simliar? Seems to me like there must be a long list of functions / methods / procedures that can be used that I cannot find reference to in the free pascal / Lazarus documentation. Thanks

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: Program flow
« Reply #1 on: September 26, 2017, 05:22:34 am »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Program flow
« Reply #2 on: September 26, 2017, 10:38:08 am »
Handoko already gave you some good links, however those would perhaps not answer all your question or discuss all options.

If I have some code I want run after the main form has been created but the form is displayed, where do I put it?.
There are several options, alll have their pro's and con's.

For example, you could use the onShow event, but that fires every time your form is 'shown'. If that event only happens once for the duration of your application then that is fine, otherwise you would have to account for your code to run oly once (that is, if your code is only suppose to run once).

Another option is using the Application onidle event, again you would have to account foronly running the code once as the onidle event is fired quite a lot.

Using a timer on your form is also an option. you would then put your code at the ontimer event and disable the timer once your code has run.

I'm sure i forgot to mention many other solution or approach. It kind of depends on what should be done exactly where and if it fits your program's flow.
Quote
If I used multiple forms, is there a formx.show or something simliar? Seems to me like there must be a long list of functions / methods / procedures that can be used that I cannot find reference to in the free pascal / Lazarus documentation. Thanks
Look at your applications .lpr file. There is where your application object gets initialized and forms are created and added. Do realize that the code you see in there can be manipulated with your project's settings, e.g. you can tell your project which forms should be created automatically for you (or not).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Program flow
« Reply #3 on: September 26, 2017, 01:34:11 pm »
Quote
If I have some code I want run after the main form has been created ....
It depends on what you really want to achieve...  :)

This would be one way...
Code: Pascal  [Select][+][-]
  1. // PRIVATE
  2. //  booOnce: Boolean;
  3. Procedure TForm1.FormPaint(Sender: TObject);
  4.  Begin
  5.   If Not booOnce
  6.   Then
  7.    Begin
  8.     ShowMessage('OnPaint');
  9.     booOnce:= True;
  10.    End;
  11.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Program flow
« Reply #4 on: September 26, 2017, 01:47:47 pm »
Or like this...

Code: Pascal  [Select][+][-]
  1. Procedure TForm1.FormClick(Sender: TObject);
  2.   Var
  3.    wnd: TForm;
  4.  Begin
  5.   wnd            := TForm.Create(Self);
  6.   wnd.Caption    := 'MyNewWindow';
  7.   wnd.SetBounds  (300, 300, 300, 300);
  8.   wnd.PopupMode  := pmExplicit;
  9.   wnd.PopupParent:= Self;
  10.   wnd.Show;
  11.  
  12.   ShowMessage('After creating my new window...');
  13.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Program flow
« Reply #5 on: September 26, 2017, 02:19:25 pm »
Or like this... (Thaddy's idea .... saw it somewhere else...)

Code: Pascal  [Select][+][-]
  1. Procedure TForm1.FormClick(Sender: TObject);
  2.   Var
  3.    wnd: TForm;
  4.  Begin
  5.   wnd:= TForm.Create(Self);
  6.    Try
  7.     wnd.Caption  := 'MyNewWindow';
  8.     wnd.SetBounds(300, 300, 300, 300);
  9.     wnd.OnPaint  := @MyNewWindowOnPaint;
  10.     wnd.ShowModal;
  11.    Finally
  12.     wnd.Release;
  13.     wnd:= Nil;
  14.    End;
  15.  End;
  16.  
  17.  
  18. {$J+}
  19. Procedure TForm1.MyNewWindowOnPaint(Sender: TObject);
  20.   Const
  21.    booOnce: Boolean = False;
  22.  Begin
  23.   Inherited;
  24.  
  25.   If Not booOnce
  26.   Then
  27.    Begin
  28.     ShowMessage('After creating my new modal window...');
  29.     booOnce:= True;
  30.    End;
  31.  End;
  32. {$J-}
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Program flow
« Reply #6 on: September 26, 2017, 05:47:18 pm »
In other words: the easiest thing is always to delete the AutoCreation line inside the LPR-file and create the window at your own position.

Open the LPR file: PROJECT, VIEW PROJECT SOURCE
Code: Pascal  [Select][+][-]
  1. PROGRAM Project1;
  2. {$MODE OBJFPC}{$H+}{$J-}
  3.  
  4.  USES
  5.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  6.    cThreads,
  7.   {$ENDIF}{$ENDIF}
  8.    Interfaces,
  9.    Forms,
  10.    Unit1, unit2;
  11.  
  12.   {$R *.RES}
  13.  
  14. BEGIN
  15.  RequireDerivedFormResource:= True;
  16.   Application.Initialize;
  17.   Application.CreateForm(TForm1, Form1);
  18.    // Delete this line Application.CreateForm(TForm2, Form2);
  19.    // No AutoCreation of the form !!!
  20.   Application.Run;
  21. END.

And then create the form at your own position...
Code: Pascal  [Select][+][-]
  1. UNIT Unit1;
  2. {$MODE OBJFPC}{$H+}{$J-}
  3.  
  4. Interface
  5.  USES
  6.   Windows, Classes,  SysUtils,
  7.   Forms,   Controls, StdCtrls;
  8.  
  9.  TYPE
  10.   TForm1 = Class(TForm)
  11.  
  12.    Button1: TButton;
  13.  
  14.    Procedure Button1Click (Sender: TObject);
  15.  
  16.     PRIVATE
  17.      Procedure AsyncSound(Data: PtrInt);
  18.   End;
  19.  
  20.  VAR
  21.   Form1: TForm1;
  22.  
  23. Implementation
  24.  {$R *.LFM}
  25.   USES Unit2;
  26.  
  27. Procedure TForm1.Button1Click(Sender: TObject);
  28.  Begin
  29.   Form2:= TForm2.Create(Self);
  30.   Form2.Show;
  31.  
  32.   // After FormCreation do whatever you like !!!
  33.   Form2.StaticText1.Caption:= 'I am Form2...';
  34.   Form2.Button1.Caption    := 'I am the first button';
  35.   Form2.Edit1.Text         := 'Hello Hello Hello';
  36.  
  37.   // Windows.Beep(800, 1000);
  38.   Application.QueueAsyncCall(@AsyncSound, 0);
  39.  End;
  40.  
  41.  
  42. Procedure TForm1.AsyncSound(Data: PtrInt);
  43.  Begin
  44.   Windows.Beep(800, 1000);
  45.  End;
  46.  
  47. END.

This would be my first try in general...  :)

If the form isn't accessible, depending on what you want to do, then use a second thread...
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

mariodosreis

  • New Member
  • *
  • Posts: 16
Re: Program flow
« Reply #7 on: July 12, 2022, 11:58:21 pm »
 On Delphi i used the following code:
procedure TMainForm.OnMessageOwn(var Msg: TMsg; var Handled: Boolean) ;
var
  KeyState: TKeyboardState;
begin
 // Põe no ecram CpasLock NumLock etc...
  GetKeyboardState(KeyState);

  if KeyState[VK_NUMLOCK] = 0 then
    oStatusBar.Panels[5].Text:= '!'
  else
    oStatusBar.Panels[5].Text:= 'Num.';

  if KeyState[VK_CAPITAL] = 0 then
    oStatusBar.Panels[6].Text:= '!'
  else
    oStatusBar.Panels[6].Text:= 'Caps.';

  if KeyState[VK_INSERT] = 0 then
    oStatusBar.Panels[7].Text:= '!'
  else
    oStatusBar.Panels[7].Text:= 'Ins.';

end;
On Lazarus, since we don't have  Application.OnMessage := OnMessageOwn;
I' using the Application.OnIdle=IdleHandler like this:

procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
Var KeyState: Smallint;
begin
 // Delphi:    GetKeyboardState(KeyState);      // And $80
    if  GetKeyState(VK_SHIFT) <> 0 then
      StatusBar1.Panels[4].Text:= 'Shift'
    else
     StatusBar1.Panels[4].Text:= '?!'    ;

    if  GetKeyState(VK_NUMLOCK)) = 0 then
      StatusBar1.Panels[5].Text:= '?!'
    else
      StatusBar1.Panels[5].Text:= 'NºLock';

    if  GetKeyState(VK_CAPITAL)  = 0 then
      StatusBar1.Panels[6].Text:= '?!'
    else
      StatusBar1.Panels[6].Text:= 'Caps.';

    if  GetKeyState(VK_INSERT)  = 0 then
      StatusBar1.Panels[7].Text:= '?!'
    else
      StatusBar1.Panels[7].Text:= 'Ins.'

end;

The only inconvinient is the never ending loop while Idle!
Is there some other to achieve the same result?
Best regards

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: Program flow
« Reply #8 on: July 13, 2022, 10:55:01 pm »
When you open a Form for editing, the "Object Inspector" "Events" pane has a list of events with help on what each is used for. These include OnCreate, OnShow, OnActivate, etc. Perhaps this is of help.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

Thausand

  • Sr. Member
  • ****
  • Posts: 292
Re: Program flow
« Reply #9 on: July 14, 2022, 03:16:20 am »
Can make use typed const: https://www.freepascal.org/docs-html/ref/refse10.html#x22-210002.2

Code: Pascal  [Select][+][-]
  1. procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
  2. Var KeyState: Smallint;
  3. const HaveKeyState:boolean=false;
  4. begin
  5.     if HaveKeyState then exit;
  6.  
  7.  // Delphi:    GetKeyboardState(KeyState);      // And $80
  8.     if  GetKeyState(VK_SHIFT) <> 0 then
  9.       StatusBar1.Panels[4].Text:= 'Shift'
  10.     else
  11.      StatusBar1.Panels[4].Text:= '?!'    ;
  12.  
  13.     if  GetKeyState(VK_NUMLOCK)) = 0 then
  14.       StatusBar1.Panels[5].Text:= '?!'
  15.     else
  16.       StatusBar1.Panels[5].Text:= 'NºLock';
  17.  
  18.     if  GetKeyState(VK_CAPITAL)  = 0 then
  19.       StatusBar1.Panels[6].Text:= '?!'
  20.     else
  21.       StatusBar1.Panels[6].Text:= 'Caps.';
  22.  
  23.     if  GetKeyState(VK_INSERT)  = 0 then
  24.       StatusBar1.Panels[7].Text:= '?!'
  25.     else
  26.       StatusBar1.Panels[7].Text:= 'Ins.'
  27.  
  28.     HaveKeyState:=true;
  29. end;
  30.  

 

TinyPortal © 2005-2018