RAD Studio VCL Reference
ContentsIndex
PreviousUpNext
TApplication.HandleMessage Method

Interrupts the execution of an application while Windows processes a message in the Windows message queue.

Pascal
procedure HandleMessage;
C++
__fastcall HandleMessage();

HandleMessage interrupts the execution of the application so that Windows can process a single message from the Windows message queue before returning control to the application. If the message queue is empty, HandleMessage generates an OnIdle event and starts the process of updating the actions in the application.

Note: If the application goes idle, HandleMessage may take a long time to return. Therefore, do not call HandleMessage when waiting for something message-based while priority actions are also being processed. Instead, call ProcessMessages when processing more than just messages.
 

C++ Examples: 

 

/*
The following code demonstrates background processing using
the OnIdle event, and using the HandleMessage method to 
permit messages or background processing to get through.
Note: You must add MyIdleHandler to the Form1 methods.
*/
// global variables to show the order of events
int  XPos, YPos, Delta;

// This is a utility procedure to display messages
// add this at the beginning of the unit

void StatusMsg(TForm *Form, TCanvas *Canvas, char *Message, bool Bkg)
{
  if (!Bkg)
    Canvas->Font->Style = TFontStyles() << fsBold; // foreground messages are bold
  Canvas->TextOut(XPos, YPos, Message);
  if (!Bkg)
    Canvas->Font->Style = TFontStyles();
  // change Xpos and YPos to prepare for the next message
  YPos += Delta;
  if (YPos >= Form->ClientHeight - 10)
  {
    YPos = 10;
    XPos += 180;
  }
  if (XPos >= Form->ClientWidth - 100)
  {
    if (Canvas->Font->Color == clRed)
      Canvas->Font->Color = clBlack;
    else
      Canvas->Font->Color = clRed;
    XPos = 10;
  }
}

/*
This is the OnCreate event handler for Form1.  It
initializes global values and sets the application’s OnIdle
event handler
*/
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  Button1->Caption = "Do not yield";
  Button2->Caption  = "Handle Message";
  Application->OnIdle = MyIdleHandler;
  XPos = 10;
  YPos = 10;
  if (Canvas->Font->Height > 0)
    Delta = Canvas->Font->Height + 1;
  else
    Delta = 1 - Canvas->Font->Height;
}

/*
This is the OnIdle event handler. It is set in the Form’s
OnCreate event handler, so you need only add it as a private
method of the form.  Usually it would perform some background
processing for the application.  This one simply writes a
message to let you know when it’s there.
*/
void __fastcall TForm1::MyIdleHandler(TObject *Sender, bool &Done)
{
  StatusMsg(Form1, Canvas, "This represents a background process.", true);
}

/*
This is the OnClick event handler for Button1.  It
simulates a lengthy process
*/
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int X, Y;
  StatusMsg(Form1, Canvas, "The Button1Click handler is starting", false);
  for (int I = 0; I < 100; I++)
  {
    randomize();
    for (int J = 0; J < 100; J++)
      Y = random(J);
    X = random(I);
  }
  StatusMsg(Form1, Canvas, "The Button1Click handler is done", false);
}

/*
This is the OnClick event handler for button2.  It
simulates a lengthy process that allows other messages to be
processed.
*/
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  int X, Y;
  StatusMsg(Form1, Canvas, "The Button2Click handler is starting", false);
  for (int I = 0; I < 100; I++)
  {
    randomize();
    for (int J = 0; J < 100; J++)
    {
      Y = random(J);
    }
    // Yield to OnIdle or other messages
    Application->HandleMessage();
    X = random(I);
  }
  StatusMsg(Form1, Canvas, "The Button2Click handler is done", false);
}

 

Delphi Examples: 

{
The following code demonstrates background processing using
the OnIdle event, and using the HandleMessage method to 
permit messages or background processing to get through.
Note: You must add MyIdleHandler to the Form1 methods.
} 
var
{ global variables to show the order of events. }
  XPos, YPos, Delta: integer;

{ This is a utility procedure to display messages }
{ add this at the beginning of the implementation section }
procedure StatusMsg(
  MyForm : TForm1; Canvas : TCanvas; Message : string; Bkg : Boolean);
begin
  if not bkg then
    Canvas.Font.Style := [fsBold]; {foreground messages are bold }
  Canvas.TextOut(XPos, YPos, Message);
  if not bkg then
    Canvas.Font.Style := [];
  { change Xpos and YPos to prepare for the next message }
  Ypos := Ypos + Delta;
  if YPos >= MyForm.ClientHeight - 10 then
  begin
    YPos := 10;
    Xpos := Xpos + 180;
  end;
  if (Xpos >= MyForm.ClientWidth - 100) then
  begin
    if (Canvas.Font.Color = clRed) then
      Canvas.Font.Color := clBlack
    else
      Canvas.Font.Color := clRed;
    Xpos := 10;
  end;
end;

{This is the Form’s OnCreate event handler.  }
{ It initializes global variables and sets the  the OnIdle 
event handler }
procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.Caption := 'Do not yield';
  Button2.Caption := 'Handle Message';
  Application.OnIdle:= MyIdleHandler;
  XPos := 10;
  YPos := 10;
  Delta := Abs(Canvas.Font.Height) + 1;
 end;

{
This is the OnIdle event handler. It is set in the Form’s 
OnCreate event handler, so you need only add it as a private
method of the form.  Usually it would perform some 
background processing for the application.  This one simply
writes a message to let you know when it’s there.
}
procedure TForm1.MyIdleHandler(Sender: TObject; var Done: Boolean);
begin
  StatusMsg(
    Form1, Canvas, 'This represents a background process.', True);
end;

{
Set this method as the OnClick event handler of Button1.  It
performs a calculation without yielding to other messages or
idle time.
}
procedure TForm1.Button1Click(Sender: TObject);
var
  I, J, X, Y: Word;
begin
  StatusMsg(
    Form1, Canvas, 'The synchronous handler is starting', False);
  I := 0;
  J := 0;
  while I < 10 do
  begin
    Randomize;
    while J < 10 do
    begin
      Y := Random(J);
      Inc(J);
    end;
    X := Random(I);
    Inc(I);
  end;
  StatusMsg(
    Form1, Canvas, 'The synchronous handler is done', False);
end;

{
Set this method as the OnClick event handler of Button2.  It
performs a calculation but calls HandleMessage to allow idle
time or asynchronous message processing.
}
procedure TForm1.Button2Click(Sender: TObject);
var
  I, J, X, Y: Word;
begin
 StatusMsg(
    Form1, Canvas, 'The asynchronous handler is starting', False);
  I := 0;
  J := 0;
  while I < 10 do
  begin
    Randomize;
    while J < 10 do
    begin
      Y := Random(J);
      Inc(J);
    end;
    X := Random(I);
    Inc(I);
    { yield to OnIdle or other messages }
    Application.HandleMessage;
  end;
  StatusMsg(
    Form1, Canvas, 'The asynchronous handler is done', False);
end; 

 

Copyright(C) 2008 CodeGear(TM). All Rights Reserved.
What do you think about this topic? Send feedback!