2

I have the following code and it correctly shows the InvoicingUnit on the message box. It also shows the value in the caption correctly.

  ADItemRecord := GetInvItemRecord(txtItemCode.Text);
  ShowMessage(ADItemRecord.InvoicingUnit );
  lblUnit.Caption := ADItemRecord.InvoicingUni;

But the following change (i.e., removing the Message box), shows no caption. The caption is blank.

  ADItemRecord := GetInvItemRecord(txtItemCode.Text);
  lblUnit.Caption := ADItemRecord.InvoicingUni;

I believe this is to do with the program moving on to the next line before the data is ready in the record. So I did the following change hoping that the program will correctly complete the fetch and then move on.

  ADItemRecord := GetInvItemRecord(txtItemCode.Text); //Fetch data from DB
  Application.ProcessMessages; //Wait for it to complete (I think)
  lblUnit.Caption := ADItemRecord.InvoicingUnit;
  Application.ProcessMessages;

But the above change has no effect.

Am I correct to assume that calling Application.ProcessMessages will wait till the previous line correctly completes?

The function GetInvItemRecord is meant to fetch the record from the DB. The program is built on Ubuntu with Postgres.

Charles
  • 50,943
  • 13
  • 104
  • 142
itsols
  • 5,406
  • 7
  • 51
  • 95

2 Answers2

4

Application.ProcessMessages signals that the app can execute events from its event queue. Let's say that you have 2 buttons on a form with to onclick procedures assigned. The first procedure is a lengthly process (eg. repeat ... until true). The second button has only ShowMessage('haha').

Now, without appllication.processmessages inserted in the first procedure in the repeat statement, if you press the first button then you will not be able to press the seccond button (or anything else) until the repeat statement finishes. So the user interface is frozen.

With the application.processmessages inserted like

 repeat
   Application.ProcessMessages;
   ...
 until true;

if you press the first button and then the second button the showmessage will happen! So, it is a way to fake a multithread app :-))

I hope that i was clear.

itsols
  • 5,406
  • 7
  • 51
  • 95
mdalacu
  • 171
  • 4
  • +1 and thanks for your example of how ProcessMessages works. I also like the idea that it's an easy alternative to mutli-threading - although not the same. – itsols Jul 17 '14 at 05:08
  • I'd probably add that Application.ProcessMessages here probably is more a band-aid than a solution. There's always a chance that the chain of messages triggered by GetInvItemRecord don't come back in time to get processed by that first call, and you'll need to put another call, and then another... It's probably better to use some sort of "OnDataReceived" event on the Record class, which hopefully exists. – user4815162342 May 29 '15 at 14:16
1

This was one of the difficult ones since I did not know what to look for. I've included my answer here so that someone else may also benefit from this.

I thought perhaps it was not the problem (delay) in calling the function to fetch data, but an issue with delayed screen painting or refreshing. Then I found these two links:

What's the difference between Refresh, Update and Repaint?

and this:

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Controls_TControl_Update.html

So I decided to call the Update procedure after assigning the value to the caption. That was the solution to my problem.

I still am not sure how Application.ProcessMessages works - smiles.

Community
  • 1
  • 1
itsols
  • 5,406
  • 7
  • 51
  • 95