Recent

Author Topic: Trying to save data with OnCloseQuery on PC shutdown, Am I doing it wrong?  (Read 3524 times)

Firewrath

  • New Member
  • *
  • Posts: 35
See This Post for how I got it working.


First, I'm on winXP, using Lazarus 1.6.4 (FPC 3.0.2).

So I thought you weren't allowed to write to a file when your PC shuts off, maybe I'm right, I don't know.
...but Windows Notepad will stop the PC from shutting to ask if you want to save a changed file, sooo...
Is there any way to save a file when the PC is shutting down?
(Well, even Lazarus can stop the PC from shutting down if a project isn't saved, so I'm going with 'yes'?)
...Actually, the more I think about it the less sense it makes, so I'm thinking some 'internet myth' and leaving it at that. Anyways...

Right now I'm just looking at saving settings in an INI file, but later I'd like to do it with an SQL file.
(or at least write a commit to the SQL file anyways)
I tried using 'OnClose' and then 'OnCloseQuery' (with 'CanClose := false;') but it seems in either one, my files are not writen to, saved, or created when the PC shuts down.
They save just fine when I close the program myself (Obviously :P) but not when the PC shuts the program down when turning off. :(

I also tried 'OnClose' and 'OnDestroy', those didn't work either.

The simplest way to put it is like so:
Code: Pascal  [Select][+][-]
  1. PROCEDURE TForm1.FormCloseQuery(Sender: TObject; VAR CanClose: boolean);
  2. var
  3.   f: textfile;
  4. BEGIN
  5.   if not FileExists('.\Test.txt') then
  6.   begin
  7.     CanClose := false;
  8.     assignfile(f, 'Test.txt');
  9.     rewrite(f);
  10.     writeln(f,'Testing.');
  11.     closefile(f);
  12.   END;
  13. end;
  14.  
(This doesn't work.)
but my test for INI files are in the zipped project.
« Last Edit: January 10, 2019, 12:51:45 am by Firewrath »
Sorry. I currently don't have Internet Access. So my replies might take a week. -_-

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: Trying to save data with OnCloseQuery on PC shutdown, Am I doing it wrong?
« Reply #1 on: November 14, 2018, 06:46:30 pm »
Code: Pascal  [Select][+][-]
  1. procedure  TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean);
  2. var
  3.   f: textfile;
  4. begin
  5.   CanClose :=False;
  6.   if not FileExists('.\Test.txt') then
  7.   begin
  8.     assignfile(f, 'Test.txt');
  9.     rewrite(f);
  10.     writeln(f,'Testing.');
  11.     closefile(f);
  12.   end;
  13.   CanClose := True;
  14. end;
But it is horrible code anyway.
Specialize a type, not a var.

Firewrath

  • New Member
  • *
  • Posts: 35
Re: Trying to save data with OnCloseQuery on PC shutdown, Am I doing it wrong?
« Reply #2 on: November 14, 2018, 07:04:06 pm »
But it is horrible code anyway.

Thanks! :P
And
A) I'm still learning, ^-^
B) That was just quick test code to see if a file would save even though my INI file wasn't being written to.

But I see, I need to set 'CanClose' first before testing my file creation / INI writing. Interesting.
I shall try it as soon as I can.
So Thank you. ^-^
Sorry. I currently don't have Internet Access. So my replies might take a week. -_-

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: Trying to save data with OnCloseQuery on PC shutdown, Am I doing it wrong?
« Reply #3 on: November 14, 2018, 09:03:57 pm »
B) That was just quick test code to see if a file would save even though my INI file wasn't being written to.

It should.  It is perfectly acceptable to write files during the OnCloseQuery event.

But I see, I need to set 'CanClose' first before testing my file creation / INI writing. Interesting.

No, you don't.  All you are doing is setting a variable, nothing ACTS on that variable until after the event handler exits.  So, in fact, you don't even need to set the variable at all (since it defaults to True).  You are not ABORTING shutdown, so there is no point in setting CanClose to False in your example.  During OnCloseQuery, the PC has not shutdown yet.  It hasn't even BEGUN to shutdown yet.  It is still asking apps for PERMISSION to shutdown.  So, you can still do whatever you want during that time.  OnCloseQuery is a perfectly good place to save unsaved data (though, Microsoft suggests you save data periodically during the app's lifetime so there is less need to save anything during shutdown).
« Last Edit: November 14, 2018, 09:06:15 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Firewrath

  • New Member
  • *
  • Posts: 35
Re: Trying to save data with OnCloseQuery on PC shutdown, Am I doing it wrong?
« Reply #4 on: November 19, 2018, 09:53:59 pm »
(Edit: I made a mistake in the code and one of the attached zips. So it's now fixed.)

Alright, so I've been trying some stuff to get this to work, and...

This Does NOT work:
Code: Pascal  [Select][+][-]
  1. PROCEDURE TForm1.FormCloseQuery(Sender: TObject; VAR CanClose: boolean);
  2. var
  3.   f: textfile;
  4. begin
  5.   CanClose := False;
  6.   if not FileExists('.\Test.txt') then
  7.   begin
  8.     assignfile(f, 'Test.txt');
  9.     rewrite(f);
  10.     writeln(f,'Testing.');
  11.     closefile(f);
  12.   end;
  13.   ShowMessage('Test.');
  14.   CanClose := True;
  15. end;
  16.  
(This is in 'OnCloseQ_Test2.zip')
If I close the program it works just fine, but when my PC shuts down, it doesn't work, the Message doesn't even popup.
I also found 'std_actions' in the examples folder that has a 'OnCloseQuery' event, I compiled it and again the event triggers when I close the example program, but if I leave it open and shutdown my PC, the event never triggers when Windows closes the example program on Shutdown.


So I was googling and found this:
Code: Pascal  [Select][+][-]
  1.  
  2. procedure TForm1.ApplicationProperties1EndSession(Sender: TObject);
  3. var
  4.   f: textfile;
  5. begin
  6.   if not FileExists('.\Test.txt') then
  7.   begin
  8.     assignfile(f, 'Test.txt');
  9.     rewrite(f);
  10.     writeln(f,'Testing.');
  11.     closefile(f);
  12.   end;
  13.   ShowMessage('Test1.');
  14. end;
  15.  
  16.  
  17. procedure TForm1.ApplicationProperties1QueryEndSession(var Cancel: Boolean);
  18. var
  19.   f: textfile;
  20. begin
  21.    if not FileExists('.\Test2.txt') then
  22.   begin
  23.     assignfile(f, 'Test2.txt');
  24.     rewrite(f);
  25.     writeln(f,'Testing.');
  26.     closefile(f);
  27.   end;
  28.   ShowMessage('Test2.');
  29. end;
  30.  
This code (and the project in 'OnClose_Test4.zip') does NOTHING (for me anyways).
Doesn't matter if I close it or Windows does, the event never trigger at all.
No file writen, no ShowMessage. Though it is like 6-7years old...

So I don't know if it don't work, or if it's just my PC. =/
I'm going to update my Lazarus to 1.8.4 with a second install and see if that will fix anything.
« Last Edit: November 21, 2018, 05:26:48 pm by Firewrath »
Sorry. I currently don't have Internet Access. So my replies might take a week. -_-

Josh

  • Hero Member
  • *****
  • Posts: 1271
Re: Trying to save data with OnCloseQuery on PC shutdown, Am I doing it wrong?
« Reply #5 on: November 20, 2018, 12:41:34 am »
Hi

WHat would happen if you put
Code: [Select]
assignfile(f, 'Test.txt');
rewrite(f);
writeln(f,'Testing.');
closefile(f);
in your project.lpr file, after the application.run.
nb you will need to ad var f:texfile to the lpr file also

The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Firewrath

  • New Member
  • *
  • Posts: 35
Re: Trying to save data with OnCloseQuery on PC shutdown, Am I doing it wrong?
« Reply #6 on: November 21, 2018, 05:33:26 pm »
josh, That is an interesting idea. I shall give it a try and post results when I get back next week.


So all testing in this post was done in both Lazarus 1.6.4 and 1.8.4.

But first...
Ok, I'll admit I messed up. In my last post
OnCloseQ_Test3.zip
Should have been:
OnClose_Test4.zip
Sorry. =/

...I have like 10 or more of these things. >.>
(And in my defence, it went like:
Check code, Compile, Run Program, Shutdown PC ...wait 5min for PC to restart... check folder then Repeat to be sure, then "Now lets see, that was uhm, That folder." *Pretypes forum post*
Which was the wrong folder. >.>)
The project in OnClose_Test4.zip is the one that does Nothing.

OnCloseQ_Test3.zip
Was one I wasn't 100% sure about at the time and still messing with, but hadn't tested it enough at the time I posted to say anything. (I wasn't expecting to be online the day I made the post.)
So I fixed that.

In other news...
OnCloseQ_Test3.zip
Actually works, Kind of...
Sooo, ...yeah.

This works "fine" on Windows Shutdown ...Except... when I combined it in a larger test project (in 1.8.4).
Code: Pascal  [Select][+][-]
  1. ...
  2.   private
  3.     { private declarations }
  4.     procedure OnEndSession(Sender:Tobject);
  5. ...
  6. procedure TForm1.FormCreate(Sender: TObject);
  7. begin
  8.   Application.OnEndSession:=@OnEndSession;
  9. end;
  10.  
  11. procedure TForm1.OnEndSession(Sender: Tobject);
  12. var
  13.   f: textfile;
  14. begin
  15.   if not FileExists('.\Test.txt') then
  16.   begin
  17.     assignfile(f, 'Test.txt');
  18.     rewrite(f);
  19.     writeln(f,'Testing.');
  20.     closefile(f);
  21.   end;
  22. end;
  23.  
In my larger test project (in 1.8.4), it works fine if placed here:
Code: Pascal  [Select][+][-]
  1.   TForm1 = CLASS(TForm)
  2.     Memo1: TMemo;
  3.     ...
  4.     procedure EndSession(Sender: TObject);
  5.  
but in Private I get errors:
unit1.pas(77,18) Error: method identifier expected
unit1.pas(136,30) Error: Incompatible types: got "<address of procedure(TObject);Register>" expected "<procedure variable type of procedure(TObject) of object;Register>"
(These Errors are ONLY in 1.8.4. There are no Errors in 1.6.4)

(From my larger Test Project)
Code: Pascal  [Select][+][-]
  1. procedure TForm1.EndSession(Sender: TObject);
  2. var
  3.   f: textfile;
  4. begin
  5.   Memo1.Lines.Add(FormatDateTime('hh:nn:ss:ms AM/PM', Now) + ' - ' + FormatDateTime('MM/DD/YYYY', Now) + ' - ' + 'In EndSession.');
  6.   Memo1.Lines.SaveToFile('Testing.log');
  7.  
  8.   if not FileExists('.\Test_EndSession.txt') then
  9.   begin
  10.     assignfile(f, 'Test_EndSession.txt');
  11.     rewrite(f);
  12.     writeln(f,'EndSession Worked!');
  13.     writeln(f, FormatDateTime('hh:nn:ss:ms AM/PM', Now) + ' - ' + FormatDateTime('MM/DD/YYYY', Now));
  14.     closefile(f);
  15.   end;
  16. END;
  17.  
(I tried Form1.Memo1./etc thinking that might have been it, but that only fixes the first error. ...The second error confuses me a little. >.>)
So yeah, I'm going to have to see what that is about.

I think if I use both 'OnCloseQuery' and 'EndSession' it'll fix my issue with saving my INI file on program close and PC Shutdown.
...After I get the error sorted anyways. Cause even though they only happen in 1.8.4, I should look at doing it right. ^-^;
(I'm going to have to update eventually. I thought about waiting till 2.0, but...>.>)

Also, here is my OTT Testing project with everything I tried, if anyone else ever runs into anything like this and wants to try a bunch of things in one go.
« Last Edit: November 21, 2018, 05:35:12 pm by Firewrath »
Sorry. I currently don't have Internet Access. So my replies might take a week. -_-

 

TinyPortal © 2005-2018