Easiest is to look up some Delphi example, but roughly define a message handler in your class.
Be careful you call the right methods (in windows or messages unit), and not the Lazarus methods that emulate some message dispatch methods for internal use.
See https://www.freepascal.org/docs-html/ref/refsu31.html and a gazillion Delphi examples on the web.
But I think micromanaging this is overkill. TThread doesn't really have any serious overhead.
I know TThread is easy to manage but I just want to practise my skills on Free Pascal.
MainForm.pas(187,51) Error: Incompatible type for arg no. 1: Got "<class method type of function(Pointer):LongInt of object;Register>", expected "<procedure variable type of function(Pointer):LongInt;Register>"
[/tt]
I assumed that by declaring a class/static procedure, it should match BeginThread signature, but apprently I am wrong. What's wrong with my syntax?
A hint is not a warning. You can simple declare {$HINTS OFF}Or press in the Messages window with mouse right click on a specific hint/warning to suppress it over a menu (that will add conditional compiling for that line of code)
(Although in this case the hint should be a warning..... Platform)
You can even turn individual hints off using {$WARN <hint number> OFF}
A hint is not a warning. You can simple declare {$HINTS OFF}Or press in the Messages window with mouse right click on a specific hint/warning to suppress it over a menu (that will add conditional compiling for that line of code)
(Although in this case the hint should be a warning..... Platform)
You can even turn individual hints off using {$WARN <hint number> OFF}
Wow, I did not even know you can do that in Lazaru IDE.Oh yes, the IDE offers a lot of comfort :-*
Form1.pas(242,47) Hint: Conversion between ordinals and pointers is not portableTry this: https://forum.lazarus.freepascal.org/index.php/topic,45924.msg325324.html#msg325324
I successfully get both asynccall and user message working. But I get warnings when I convert record pointer to PtrInt:
*snip*
I successfully get both asynccall and user message working. But I get warnings when I convert record pointer to PtrInt:
*snip*
You should be aware that AsyncCalls can do any sort of nasty things thanks to some dangling references ... since we're talking about windows (this.Handle) ...
Messages don't have that trouble.
Well, since the Application.AsyncCall() gets a TDataEvent parameter, which is 'of object', usually it contains an internal reference to a TForm. That handler (the parameter) will be invoked in the future, the form may be non-existent, i.e. the internal reference will be dangling.
To prevent this, it isn't enough just to stop firing AsyncCall's towards that form, you should also remove the already pending:
procedure TForm1.FormDestroy(Sender: TObject); begin // Remove pending async calls Application.RemoveAsyncCalls(Self); ... end;
The same thing may happen with the second parameter of the AsyncCall() when used to transfer a pointer/reference to some dynamic object. It may be already destroyed at the time the handler is executed.
I have some advanced experience with multithreading. I believe this is not a specific problem to a single language or framework. It's a problem of multithreading design by nature. Everyone has to be very careful with async processing and bear in mind everytihng should be well guarded if it should be accessed by more than one thread.That's right.
I don't know how it works behind the scenes of RemoveAsyncCalls, I'd rather not using it because it may abruptly kill any ongoing async work which might leave some conditions corrupt (e.g., event signal'ed but not unset). In the most simple and naive case, I prefer setting up a boolean variable to indicate if it is valid to perform any work in an async procedure.It works pretty straightforward. Application.QueueAsyncCall() places a TDataEvent into a queue to be executed into the TApplication.ProcessMessages, i.e. into the UI thread where it is safe to update the UI. Application.RemoveAsyncCalls() removes from the queue the entries for a given instance. That is pretty much all.
I assumed that by declaring a class/static procedure, it should match BeginThread signature, but apprently I am wrong. What's wrong with my syntax?
BTW, I know that I can declare a top level bare procedure for this, but I am just curious why a class procedure won't do the work.