Forum > General

[Solved] Exception "In HandlerObject reference is Nil" from frmActivate

(1/2) > >>

Wilko500:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---//Snippet from end of frmActivate  FActivated:=True;  ValidateOn:=True;  cmdStart.Enabled:=True;  cmdStop.Enabled:=False;  cmdExit.Enabled:=True;  GetInvState;  //Do some checks on inverter state  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

Zvoni:
Put the code, that's inside your cmdStartClick into its own Procedure.
you can then call that procedure from wherever you want


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TForm1 = Class(TForm)//A lot of Stuff   Procedure cmdStartClick(Sender:TObject);Private   Procedure MyOwnStartCode;//Other StuffEnd;..Procedure TForm1.MyOwnStartCode;Begin   DoSomething;End; Procedure TForm1.cmdStartClick(Sender:TObject);Begin   MyOwnStartCode;End; Procedure TForm1.OnActivate; //Or whatever it's calledBegin    //Snippet from end of frmActivate     FActivated:=True;      ValidateOn:=True;      cmdStart.Enabled:=True;      cmdStop.Enabled:=False;      cmdExit.Enabled:=True;      GetInvState;  //Do some checks on inverter state      MyOwnStartCode;...... 

Wilko500:
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?

cdbc:
Hi
You should read up on 'Application.QueueAsyncCall(@MyProc,someint64var);'

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.MyProc(aData: ptrint);begin  /// do your delayed stuff here ///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

cdbc:
Hi
The long and better solution will be:
--- Quote ---One option would be to have DoSomething start the processing in a separate thread
--- End quote ---
If you need comms, let me know, I have a 'MessageQueue' for that...
Regards Benny

Navigation

[0] Message Index

[#] Next page

Go to full version