Recent

Author Topic: Message loop event interaction ???  (Read 4154 times)

LSE

  • New member
  • *
  • Posts: 8
Message loop event interaction ???
« on: December 09, 2018, 01:28:33 pm »
How can window message loop events communicate with each other ?

I have a window with several "action buttons" and events controlled by a message loop.

One event is an animation, which I would like to run in a repeat loop until a "Stop" button is pressed.

The animation event is running in a procedure a la:

REPEAT
...
...
UNTIL (???);

How can the UNTIL condition access window message loop to detect whether the "Stop" buttonhas been pressed (and then terminate) ?

Any help or hint would be much appreciated.
I am a little novice in the Windows concept of message loop and anarchistic user interaction (as opposed to old fashioned strict sequential control).

Regards, LSE


   

Handoko

  • Hero Member
  • *****
  • Posts: 5129
  • My goal: build my own game engine using Lazarus
Re: Message loop event interaction ???
« Reply #1 on: December 09, 2018, 03:16:27 pm »
I'm not going to answer your question about message loop event interaction.

It seems you want to build an animation program or maybe game. Do you use Lazarus or Free Pascal only? If you don't use Lazarus, I suggest you to try it.

Nothing wrong with Free Pascal. But it will be easier for beginners to use Lazarus to create animations and games.

Here are some Lazarus examples showing how to do simple animations and games for you to download, test and study:

Sprite Demo by wp:
https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/examples/sprites/?root=lazarus

Simple Form Transition by Handoko:
http://forum.lazarus.freepascal.org/index.php/topic,37943.msg256549.html#msg256549

Moving Objects Moving2.zip by Handoko:
https://forum.lazarus.freepascal.org/index.php/topic,38136.msg263143.html#msg263143

Simple Pong Game by Handoko
http://forum.lazarus.freepascal.org/index.php/topic,42439.msg297949.html#msg297949

In Simple Pong Game you can learn:
- Use a TTimer as the game loop
- Use GetKeyState to detect user keyboard inputs
- How to pause/resume game if user switch to/from other program
- How to handle form resize

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Message loop event interaction ???
« Reply #2 on: December 09, 2018, 03:20:37 pm »
Simple put don't do that...

Use a Ttimer and do that code within..

allow the event method block to exit.
The only true wisdom is knowing you know nothing

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Message loop event interaction ???
« Reply #3 on: December 09, 2018, 05:12:01 pm »
Your question has little to do with events. Simplifying a lot, an event is something that happens generally from outside your application and to which it can respond through an event handler. For example, in your application an event  would be the pressing of a button and the response woud be in the OnClick event handler, something like TForm1.MyButtonClick(). The only way for events, message loops, etc. to have anything to do with your animation would be having an animation class that responds to events by itself.

Now to your question. It's difficult to answer without seeing your code since there are mny ways of doing animation but let's supposse you just show a series of pictures one after the other. Your animation class should have methods to start and stop it, something like:

Code: [Select]
{ Ultra-simplified! }
type
  TAnimation = class
  protected
    StopNow: Boolean;
  public
    procedure Start;
    procedure Stop;
  end;

{. . .}

procedure TAnimation.Start;
{ Just an example!!!
  It will not return until terminated!}
begin
  StopNow := False;
  repeat
    {Do the animation thingy}
  until StopNow;
end;

procedure Stop;
begin
  StopNow := True;
end;

As you can see, responding to "Play" and "Stop" buttons in your form is then very simple:

Code: Pascal  [Select][+][-]
  1. procedure TMyForm.PlayButtonClick(Sender: TObject);
  2. begin
  3.   if not Assigned(Animation) then begin
  4.     Animation := TAnimation.Create;
  5.     { other initialzations of Animation,
  6.       like LoadFromStream, setting size, etc.}
  7.   end;
  8.   Animation.Start;
  9. end;
  10.  
  11. procedure TMyForm.StopButtonClick(Sender: TObject);
  12. begin
  13.   if Assigned(Animation) then
  14.     Animation.Stop;
  15. end;

Yes, it's just an extremely simplified example but that's really all there is to it. The rest really depends on your other code, which we don't know.

HTH! :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Handoko

  • Hero Member
  • *****
  • Posts: 5129
  • My goal: build my own game engine using Lazarus
Re: Message loop event interaction ???
« Reply #4 on: December 09, 2018, 05:33:56 pm »
@LSE

I found it. Here is a demo I wrote to show a simple animation with pause/resume feature:

https://forum.lazarus.freepascal.org/index.php/topic,39790.msg274096.html#msg274096

LSE

  • New member
  • *
  • Posts: 8
Re: Message loop event interaction ???
« Reply #5 on: December 09, 2018, 06:17:56 pm »
Thanks for comments & hints.
I think especially Lucamars explanations may contain some useful hints, although I need to familarize myself with Threads (I think).

The application is in FP. I know Lazarus is probably better/easier, but it is an old program and I have not yet come to LAzarus.

It is really a very simple animation of a vibration model simulation to visualize vibration modes.
I simply calculate corner positions of vibrating bodies from solution at various phases (15 deg. ~ 24 situations per cycle), draw the result in a bitmap and sequntially refresh bitmap portion of window via vw_paint (plus a delay timer in between to slow down animation).
There are probably much better ways to do this, but it works fine.

Below is a segment of my event loop (some features not related to question has been removed for clarity).     

--- ooo ---

wm_Command: { Event in window registered }
      Begin
        NotiCode := LoWord(WParam); { Restrieve event ID }
        Case NotiCode Of
            IDC_Anim_Go: { Animation button }
            Begin
               { Dispatch for animation calculation }
               Animation_Calc (hWindow_Visu, Anim_Freq);
            End;
            IDC_Anim_Stop: { Animation stop button }         
            Begin
               MessageBox(0, 'Stop button pressed', nil, mb_Ok);
            End;
        End;

--- ooo ---

IDC_Anim_Go is triggerede by a "Go button" and the procedure "Animation_Calc" is a traditional procedure doing all the calculation and drawing work.
Currently it runs through 10 cycles and then terminate.

IDC_Anim_Stop is another (stop) button, currently (for test purposes) just triggering a message box.

From testing it appears Stop button action is only registered/executed after the Go action has terminated.

I was hoping I could detect the Stop Button event from within the "Animation_Calc" procedure and then terminate this event.

It looks like Lucamar's example is something like this, but perhaps I need to restructure the "Animation_Calc" event so it is not just a simple procedure call ?

LSE



   

LSE

  • New member
  • *
  • Posts: 8
Re: Message loop event interaction ???
« Reply #6 on: December 09, 2018, 06:34:03 pm »
Handoko,

Thanks for new hint which crossed my reply.
I think there is something useful (for me) in this example, although I have to study Classes and Threads a bit to fully undertsand the code.

Currently I have defined animation buttons in question in the form as follows:

    { Put animation buttons on window }
    CreateWindow('button', 'Animate', WS_CHILD Or WS_VISIBLE, 410, 0, 60, 20, hwindow, IDC_Anim_Go, 0, Nil);
    CreateWindow('button', 'Stop', WS_CHILD Or WS_VISIBLE, 410, 50, 60, 20, hwindow, IDC_Anim_Stop, 0, Nil);

Probably they should rather be defined as another type of (click ?) button to detect them "globally" (like looking for a keyborad action).

LSE



lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Message loop event interaction ???
« Reply #7 on: December 09, 2018, 06:58:24 pm »
OK, your problem then is that your message loop is locked unitl the call to Animation_Calc (); returns. In this kind of situations you should really be using a separate thread for your calculations, drawing, etc. The handler for the "Play" button then should just set up, start running the thread and return.

The handler for the "stop" button might then set a flag var, like in my previous example, that the thread can pool at intervals to see whether it has been requested to end prematurely.

I think you'll find the examples pointed to by Handoko very instructive, if not directly aplicable to you.

A real honest to goodness message loop ... it has been some time since I saw code like that. Since the times of TP for Windows, in fact. :D


ETA
Even if you're using just FPC, you may find useful to use the LCL for your application even if you have to controls in code. It's much more easy to use:
Code: Pascal  [Select][+][-]
  1. PlayButton := TButton.Create(Self);
  2. PlayButton.Caption := '&Play';
  3. PlayButton.OnClick := @PlayAnimation;
than cope with CreateWindow(), message loops, etc.

Easiest of all, of course, is to use Lazarus for GUI apps :)
« Last Edit: December 09, 2018, 07:07:08 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

LSE

  • New member
  • *
  • Posts: 8
Re: Message loop event interaction ???
« Reply #8 on: December 09, 2018, 10:31:26 pm »
Thanks to all of You.

The problem is eactly as You (Lucamar) points out.
I now think I have the clues to get on with it, but need to read a little more on Threads.

You are right it is very basic FP code, pieced together from examples with minimum understanding and a lot of trial and error in small steps (building on a program which were first created under MS Pascal v1.0 back in 1986, but still going strong with regard to content).
Lazarus is probably much more efficient, but it would be a giant step for me since I jumped directly from old DOS environment to FP Windows without TP or Delphi or any  other intermediate steps. Working with Lazarus, which as I gather create its own code, I would be completely lost and uncomfortable (but I may get there one day).

Thanks again for assistance.

LSE

 



lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Message loop event interaction ???
« Reply #9 on: December 09, 2018, 11:16:07 pm »
Working with Lazarus, which as I gather create its own code, I would be completely lost and uncomfortable (but I may get there one day).

Lazarus is a lot like Delphi: if you're making a GUI application using all the RAD features, by adding controls, double-clicking here and there to write code, etc. they add some code behind your back to smooth the process (in fact, the extra code has to be there in the components for this to work right).

But there is the other facet: you can use it just as an advanced editor--a very advanced editor that knows a lot about Pascal and Pascal programs and what Pascal programmers find most useful when writing code. Even if you're writing just a simple (or not-so-simple :) ) FPC program, using Lazarus as your editor makes coding a better experience.

Once you start using Lazarus to edit your old-style code, you'll soon find yourself tempted to see what's the deal with RAD, what all those controls in the palette do, ... and soon you'll find yourself building GUI applications as the gods intended they should be built :D

At first (lo, so many years ago) I used to think like you and used fp, the fpc IDE, for console programs and Lazarus for Delphi-style applications. Then one day I opened one of the console programs in Lazarus, started to modify it and never looked back: now I only use fp when I'm in DOS or similar environments.

Go for it: it's worth the (little) effort to get started.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Handoko

  • Hero Member
  • *****
  • Posts: 5129
  • My goal: build my own game engine using Lazarus
Re: Message loop event interaction ???
« Reply #10 on: December 10, 2018, 02:45:52 am »
Lazarus is probably much more efficient, but it would be a giant step for me since I jumped directly from old DOS environment to FP Windows without TP or Delphi or any  other intermediate steps. Working with Lazarus, which as I gather create its own code, I would be completely lost and uncomfortable (but I may get there one day).

Because you already understand how to use FP you should be able to learn Lazarus easily. Lazarus is a complex tool, no wonder you felt lost trying it.

I found these video tutorials are very suitable for beginners to start with:
http://wiki.lazarus.freepascal.org/Lazarus_videos

Just relax and watch the videos, just in days you will be confident in using Lazarus.

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Message loop event interaction ???
« Reply #11 on: December 10, 2018, 04:49:58 am »
call the message loop procedure from inside your repeat until loop manually.

LSE

  • New member
  • *
  • Posts: 8
Re: Message loop event interaction ???
« Reply #12 on: December 11, 2018, 12:14:15 am »
The last suggestion by HeavyUser sounds very tempting/simple.
I could let the stop button action set a boolean to test in the "Until" condition.

If I do call the message loop procedure from within the Animation loop (in a Procedure) will program execution then return to the procedure or get caugth in the message loop e.g. if nothing has happened in the meantime ?

I will test in anyway, probably tomorrow.

LSE

 

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Message loop event interaction ???
« Reply #13 on: December 11, 2018, 04:57:59 pm »
The last suggestion by HeavyUser sounds very tempting/simple.
I could let the stop button action set a boolean to test in the "Until" condition.

If I do call the message loop procedure from within the Animation loop (in a Procedure) will program execution then return to the procedure or get caugth in the message loop e.g. if nothing has happened in the meantime ?

I will test in anyway, probably tomorrow.

LSE
depends on the  code inside the procedure, but the idea is sound.

 

TinyPortal © 2005-2018