[Lazarus] Sending messages

Michael Schnell mschnell at lumino.de
Thu Nov 24 10:02:57 CET 2011


On 11/24/2011 08:44 AM, Hans-Peter Diettrich wrote:
>
> Can somebody explain the real implementation in the LCL?
>
There already have been some threads on this issue on forum, so you 
might want to take a look back for further reference.

(In fact I was about to enhance the Lazarus documentation regarding 
these and some related functions, but at that time, I was not able to 
create working offline doc files (such as *.inf) from the source code 
and so I did not dare to modify the sources, as I could not be sure not 
to destroy them.)

In short:

These calls are not part of the "common" LCL, but are implemented 
multiple times in the files related to the different "LCLWidgetType"s 
(aka "Interfaces"). So they work in with some LCLWidgetTypes and don't 
work with others (e.g all non GUI related ones) (even though 
PostMessage() - using a "procedure...message" as a target - could be a 
useful feature with non-GUI-enabled but threaded applications.)

In short:

For non-Windows controls, SendMessage() works like "Dispatch()": it 
calls the handler function for the appropriate control. AFAIK, in 
Windows additionally SendMessage() can additionally pass information to 
a WinControl, bypassing the LCL's representation of same. SendMessage 
works like a normal call to the LCL and thus it is forbidden to use it 
in a Worker Thread, as SendMessage() is a non-reentrant call. OTOH, this 
is why SendMessage() can provide a return result from the target control 
to the caller.

PostMessage() queues the message in the EventQueue of the Main thread 
and thus the delayed action will occur on a maybe much later point in 
time. This is why no result can be passed back to the caller. The target 
always is the main thread. In Windows, the target of PostMessage() even 
can be another running program. "Locally", the target can be 
(implicitly) a control defined via the LCL, or (explicitly) a user 
function defined with "procedure...message.

A less windowish, more straight forward, and more versatile work-alike 
to PostMessage() -> "procedure...message" is 
TApplication.QueueAsyncCall(), that does work with Windows and GTK2, but 
regrettably does not work in many other LCLWidgetTypes.

I did a testing program for the thread related use of these functions. 
It can be found in the bugtracker.

-Michael




More information about the Lazarus mailing list