[Lazarus] Sending messages
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.)
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.)
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.
More information about the Lazarus