* * *

Author Topic: [SOLVED] Something wrong with query of commands in my code. How to fix it?  (Read 3123 times)

Areso

  • New member
  • *
  • Posts: 21
    • My Github
Hello there.
I have a problem with an order of execution of my commands in program.
Code: Pascal  [Select]
  1. tStory.Lines.Clear;
  2.     tStory.Lines.Add('Mancipi vero res sunt, quae per mancipationem ad alium transferuntur.');
  3.     tStory.Lines.Add('Res mobiles non nisi praesentes mancipari possunt, et non plures, quam quot manu capi possunt. Immobiles autem etiam plures simul, et quae diversis locis sunt, mancipari possunt.');
  4.     lbAct1.Caption := 'please, continue';
  5.     lbAct2.Caption := 'run from here, now';
  6.     lbAct3.Caption := '';
  7.     if lbAct2.Caption = '' then
  8.       lbAct2.Visible := False;
  9.     if lbAct3.Caption = '' then
  10.       lbAct3.Visible := False;
  11.     soundAddress:='content/eng/'+'v1.wav';
  12.     sndPlaySound(PChar(soundAddress),SND_NODEFAULT Or SND_SYNC);
  13.  
First program added lines to my TMemo, then it plays sound, and only then it works with my labels. It is quite strange, isn't it?
All code and exe file available there https://github.com/Areso/fpc-unordered
« Last Edit: May 01, 2017, 09:53:16 pm by Areso »
Lazarus 1.4.4, FPC 2.6.4, target platforms: Windows, Linux (both x86).

molly

  • Hero Member
  • *****
  • Posts: 2345
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #1 on: May 01, 2017, 09:11:55 pm »
just before calling sndPlaySound(),  make a call to Application.ProcessMesasges

The GUI does not get the time to get updated so you have to 'instruct' the GUi to do so. Using Application.ProcessMessages is one way of doing so (and it is the simplest solution).
« Last Edit: May 01, 2017, 09:22:33 pm by molly »

Areso

  • New member
  • *
  • Posts: 21
    • My Github
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #2 on: May 01, 2017, 09:52:37 pm »
Thank you very much, it solved issue.
Lazarus 1.4.4, FPC 2.6.4, target platforms: Windows, Linux (both x86).

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 408
    • Lebeau Software
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #3 on: May 02, 2017, 01:13:46 am »
just before calling sndPlaySound(),  make a call to Application.ProcessMesasges

Or, call the Form's Update() method instead, which processes only pending paint messages and no other messages.  ProcessMessages() processes all messages that are currently in the message queue, which could cause reentry issues if you are not careful.

Otherwise, use sndPlaySound() asynchronously instead, so you are not blocking the message queue while the sound is playing.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Areso

  • New member
  • *
  • Posts: 21
    • My Github
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #4 on: May 02, 2017, 03:00:35 am »
just before calling sndPlaySound(),  make a call to Application.ProcessMesasges

Or, call the Form's Update() method instead, which processes only pending paint messages and no other messages.  ProcessMessages() processes all messages that are currently in the message queue, which could cause reentry issues if you are not careful.

Otherwise, use sndPlaySound() asynchronously instead, so you are not blocking the message queue while the sound is playing.
Thank you.
Form's Update works fine.
Code: Pascal  [Select]
  1. sndPlaySound(PChar(soundAddress1),SND_NODEFAULT Or SND_ASYNC);
  2. sndPlaySound(PChar(soundAddress2),SND_NODEFAULT Or SND_ASYNC);
  3. sndPlaySound(PChar(soundAddress3),SND_NODEFAULT Or SND_ASYNC);
  4.  
I cannot use sndPlaySound() ASYNC, because in this case instead of sequence of audiofiles it plays only last one.
Lazarus 1.4.4, FPC 2.6.4, target platforms: Windows, Linux (both x86).

molly

  • Hero Member
  • *****
  • Posts: 2345
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #5 on: May 02, 2017, 03:31:32 pm »
Or, call the Form's Update() method instead, which processes only pending paint messages and no other messages.  ProcessMessages() processes all messages that are currently in the message queue, which could cause reentry issues if you are not careful.
Thank you for the correction. You are of course correct.

As could be seen, i was trying to be careful there as i did not know the context in which OP's code was operating. So, my chances were 50-50 :-)

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 408
    • Lebeau Software
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #6 on: May 02, 2017, 10:03:12 pm »
Code: Pascal  [Select]
  1. sndPlaySound(PChar(soundAddress1),SND_NODEFAULT Or SND_ASYNC);
  2. sndPlaySound(PChar(soundAddress2),SND_NODEFAULT Or SND_ASYNC);
  3. sndPlaySound(PChar(soundAddress3),SND_NODEFAULT Or SND_ASYNC);
  4.  
I cannot use sndPlaySound() ASYNC, because in this case instead of sequence of audiofiles it plays only last one.

That is because you can't play sounds back-to-back like that when using SND_ASYNC.  You have to wait for a sound to finish playing before calling sndPlaySound() again for the next sound.

If you don't want to use SNC_ASYNC, then you should move the sndPlaySound() calls to another thread so you don't block the UI thread.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Areso

  • New member
  • *
  • Posts: 21
    • My Github
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #7 on: December 16, 2017, 02:01:58 pm »
If you don't want to use SNC_ASYNC, then you should move the sndPlaySound() calls to another thread so you don't block the UI thread.
How can I do that? Is there any examples, demos or manual?
Lazarus 1.4.4, FPC 2.6.4, target platforms: Windows, Linux (both x86).

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 408
    • Lebeau Software
Re: Something wrong with query of commands in my code. How to fix it?
« Reply #8 on: December 18, 2017, 06:56:35 pm »
How can I do that? Is there any examples, demos or manual?

Have you never worked with threads before?  Just create a class derived from TThread and override its virtual Execute() method.

Multithreaded Application Tutorial

For example:

Code: [Select]
type
  TMyThread = class(TThread)
  protected
    FSounds: TStringList;
    procedure Execute; override;
  public
    constructor Create(const ASounds: array of String); reintroduce;
    destructor Destroy; override;
  end;

constructor TMyThread.Create(const ASounds; array of String);
var
  I: Integer;
begin
  inherited Create(False);
  FreeOnTerminate := True;
  FSounds := TStringList.Create;
  for I := Low(ASounds) to High(ASounds) do
    FSounds.Add(ASounds[I]);
end;

destructor TMyThread.Destroy;
begin
  FSounds.Free;
  inherited;
end;

procedure TMyThread.Execute;
var
  I: Integer;
begin
  I := 0;
  while (I < FSounds.Count) and (not Terminated) do
    sndPlaySound(PChar(FSounds[I]), SND_NODEFAULT or SND_SYNC);
end;

Then you can do this when needed:

Code: [Select]
TMyThread.Create([soundAddress1, soundAddress2, soundAddress3]);

Of course, this is just a simple example.  In a real world application, you will probably want a queue that you can push sounds into, and then have the thread running continuously in the background polling sounds from the queue and playing them.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus