Recent

Author Topic: [Solved] Exception "In HandlerObject reference is Nil" from frmActivate  (Read 538 times)

Wilko500

  • Full Member
  • ***
  • Posts: 132
I have a frmActivate procedure in my program that does a number of initialisations and checks prior to completing the form load and program start.   Under certain circumstances I require that a program procedure is started automatically on program start.  For testing purposes I started this procedure with a command button on main form.  When program is loaded click this button and procedure runs as expected.

Then, I thought, why not click the button in my formActivate procedure. But no, I seem to have invoked a number of issues.
Code: Pascal  [Select][+][-]
  1. //Snippet from end of frmActivate
  2.  FActivated:=True;
  3.   ValidateOn:=True;
  4.   cmdStart.Enabled:=True;
  5.   cmdStop.Enabled:=False;
  6.   cmdExit.Enabled:=True;
  7.   GetInvState;  //Do some checks on inverter state
  8.   cmdStartClick(Form1);   //complies with "In HandlerObject reference is Nil"

I would add that the outcome of adding this click to frmActivate seems also to depend on platform.  On my aged iMac outcome is very unpredictable, might work, might not, might even crash. My MacBook Pro (MacOs Sequoia) works more consistently at last never crashes !

I am thinking that at the time my cmdStartClick is executed the form is not complete hence the error (and unpredictable behaviour)? 

I could perhaps use a timer to delay before calling for the click execution. I do think that there must be a more elegant way to have a procedure automatically run based on a set of criteria. It seems that there are limits to what can be done in frmActivate? Pointers to a better approach would be welcome, thanks
« Last Edit: March 15, 2025, 01:58:22 pm by Wilko500 »
MacBook Pro mid 2015 with OS Monterey 12.7.6
FPC 3.2.3 Lazarus 3.7
FPC 3.2.2 Lazarus 3.4

Zvoni

  • Hero Member
  • *****
  • Posts: 2961
Re: Exception "In HandlerObject reference is Nil" from frmActivate
« Reply #1 on: March 13, 2025, 02:15:28 pm »
Put the code, that's inside your cmdStartClick into its own Procedure.
you can then call that procedure from wherever you want

Code: Pascal  [Select][+][-]
  1. TForm1 = Class(TForm)
  2. //A lot of Stuff
  3.    Procedure cmdStartClick(Sender:TObject);
  4. Private
  5.    Procedure MyOwnStartCode;
  6. //Other Stuff
  7. End;
  8. .
  9. .
  10. Procedure TForm1.MyOwnStartCode;
  11. Begin
  12.    DoSomething;
  13. End;
  14.  
  15. Procedure TForm1.cmdStartClick(Sender:TObject);
  16. Begin
  17.    MyOwnStartCode;
  18. End;
  19.  
  20. Procedure TForm1.OnActivate; //Or whatever it's called
  21. Begin
  22.     //Snippet from end of frmActivate
  23.      FActivated:=True;
  24.       ValidateOn:=True;
  25.       cmdStart.Enabled:=True;
  26.       cmdStop.Enabled:=False;
  27.       cmdExit.Enabled:=True;
  28.       GetInvState;  //Do some checks on inverter state
  29.       MyOwnStartCode;
  30. ......
  31.  
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Wilko500

  • Full Member
  • ***
  • Posts: 132
Re: Exception "In HandlerObject reference is Nil" from frmActivate
« Reply #2 on: March 13, 2025, 04:16:54 pm »
Thank you for your suggestion. I think that this will not achieve the requirement I seek. I have not coded this yet but the procedure in question is actually a continuous poll of my inverter looking for data and processing it. Thus I think that the DoSomething procedure will never return control to frmActivate and that would mean that my main form never gets displayed. One option would be to have DoSomething start the processing in a separate thread but I’m not keen to go down that route because there will be a lot of data to manipulate, updating charts, log files etc.
Am I mis-understanding your suggestion?
MacBook Pro mid 2015 with OS Monterey 12.7.6
FPC 3.2.3 Lazarus 3.7
FPC 3.2.2 Lazarus 3.4

cdbc

  • Hero Member
  • *****
  • Posts: 2095
    • http://www.cdbc.dk
Re: Exception "In HandlerObject reference is Nil" from frmActivate
« Reply #3 on: March 13, 2025, 04:18:11 pm »
Hi
You should read up on 'Application.QueueAsyncCall(@MyProc,someint64var);'
Code: Pascal  [Select][+][-]
  1. procedure TForm1.MyProc(aData: ptrint);
  2. begin
  3.   /// do your delayed stuff here ///
  4. end;
This will put a message in the back of the app's messagequeue, and will be run when your form is up and ready to process messages...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

cdbc

  • Hero Member
  • *****
  • Posts: 2095
    • http://www.cdbc.dk
Re: Exception "In HandlerObject reference is Nil" from frmActivate
« Reply #4 on: March 13, 2025, 04:22:26 pm »
Hi
The long and better solution will be:
Quote
One option would be to have DoSomething start the processing in a separate thread
If you need comms, let me know, I have a 'MessageQueue' for that...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Wilko500

  • Full Member
  • ***
  • Posts: 132
Re: Exception "In HandlerObject reference is Nil" from frmActivate
« Reply #5 on: March 13, 2025, 04:40:57 pm »
Thanks Benny
Quote
Application.QueueAsyncCall
I think this is probably the approach I was hoping for. This is new to me so I'll do some reading on this and give it a try.  Thanks also for your offer on MessageQueue.  I'll get back to you if and when I need to go that route.  I have not yet tried threads.  It is a subject I would like to get familiar with but right now I have more than enough to occupy my time.
MacBook Pro mid 2015 with OS Monterey 12.7.6
FPC 3.2.3 Lazarus 3.7
FPC 3.2.2 Lazarus 3.4

Wilko500

  • Full Member
  • ***
  • Posts: 132
Re: Exception "In HandlerObject reference is Nil" from frmActivate
« Reply #6 on: March 15, 2025, 01:58:02 pm »
You should read up on 'Application.QueueAsyncCall(@MyProc,someint64var);'
Thanks Benny.  Works a treat.   Two questions.
In my case I do not need to pass a value as in the Wiki example with FCounter.  I tried to leave it out re-coding the procedure definition(s) but didn't work, something like wrong number of arguments. I have added a dummy value in my program. 
Quote
  Application.QueueAsyncCall(@Async,FCounter);
Second can the QueueAsyncCall be called from a procedure in a different unit? I will probably restructure the code in my frmActivate so that is not needed and I always expected to need to do that as part of my development. Just curious.
MacBook Pro mid 2015 with OS Monterey 12.7.6
FPC 3.2.3 Lazarus 3.7
FPC 3.2.2 Lazarus 3.4

cdbc

  • Hero Member
  • *****
  • Posts: 2095
    • http://www.cdbc.dk
Hi
Yes, you just pass in a dummy variable, when not used.
No, you cannot change the callback signature, IT HAS TO BE:
Code: Pascal  [Select][+][-]
  1. TAsyncProc = procedure (aData: ptrint) of object;
A #2:
'Application' lives in unit 'Forms', basically the GUI apparatus of Lazarus.
If you want to use it in another unit, it's possible if you include unit 'Forms' in the other unit's uses clause...
BUT  ...if you do MVP or other sort of programming, where you separate Business logic and user interface, you might not want to have GUI-stuff in your backend / business-end...
One solution is to define a Method with the same signature as 'Application.QueueAsyncCall' and then at runtime assign your alias method like this:
Code: Pascal  [Select][+][-]
  1. /// this is your other unit ///
  2. var
  3.   MyQAC: TQac;
  4.  
  5. implementation
  6.  
Code: Pascal  [Select][+][-]
  1.  
  2. procedure TForm1.FormCreate(Sender: TObject);
  3. begin
  4.   MyQAC:= @Application.QueueAsyncCall;
  5. end;
  6.  
Then you don't have to have 'Forms' in your other unit and you can use it by calling
Code: Pascal  [Select][+][-]
  1.  MyQAC(@MyClass.HandleAC,SomePtrintParam);
  2.  
HTH
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Wilko500

  • Full Member
  • ***
  • Posts: 132
Thank you Benny for explanations and suggested workarounds, very helpful. Was just having a chuckle looking at your strap line. “If it ain’t broken don’t fix it”.  Very appropriate here. You have provided a solution to my original issue so I’ll just review my coding and avoid unnecessary complication.
MacBook Pro mid 2015 with OS Monterey 12.7.6
FPC 3.2.3 Lazarus 3.7
FPC 3.2.2 Lazarus 3.4

cdbc

  • Hero Member
  • *****
  • Posts: 2095
    • http://www.cdbc.dk
Hi
No worries mate, you're welcome  ;)
...Still think you should go the 'Thread' route though  8-)
Well, you know where to find me...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

 

TinyPortal © 2005-2018