Jump to content

Ian Branch

Members
  • Content Count

    1274
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by Ian Branch

  1. Hi Team, For years (Decades?) I have used the following coding style/structure, or similar.. procedure MainForm.ButtonClick(Sender: Object) var myForm: TMyForm; begin MyForm :- TMyForm.Create(nil); try MyForm.ShowModal; finally FreeAndNil(MyForm); end; MyForm is not declared as a var in the MyForm.pas. I recently came across a change in this style/structure that results in this.. procedure MainForm.ButtonClick(Sender: Object) begin with TMyForm.Create(nil) do try ShowModal; finally Free; end; Leaving aside the use of 'FreeAndNil()' and 'with' discussions, to me this is a simpler structure, easier to code and read, and it works. Those things make my life easier.. 😉 So To my question - As you can see in the first code I use FreeAndNil(), as much for peace of mind, imagined or real, as anything else. Is there a way to implement the equivalent in the second code structure? Regards & TIA, Ian
  2. Ian Branch

    Change of coding style/structure..

    Hi All, The passion behind not using 'with' is interesting. Also interesting is that I see no advocates. Yes, yes, you will say "And the reason is....". 🙂 To me it is just another tool in the tool box of the language. I can see and understand where concerns may be but as with any tool, used correctly, there is no issue. So, I wonder where you all stand on something like this... with TTaskDialog.Create(Self) do try Title := 'Warning!'; Text := 'Relevant/selected Records prior to ' + sArchivedDate + ' have been Archived!' + #13 + 'This may make the figures inaccurate!'; CommonButtons := [tcbOk]; Execute; finally Free; end; Should it become.. MyDialog := TTaskDialog.Create(Self); try MyDialog.Title := 'Warning!'; MyDialog.Text := 'Relevant/selected Records prior to ' + sArchivedDate + ' have been Archived!' + #13 + 'This may make the figures inaccurate!'; MyDialog.CommonButtons := [tcbOk]; MyDialog.Execute; finally MyDialog.Free; end; Or perhaps.. MyDialog := TTaskDialog.Create(Self); MyDialog.Title := 'Warning!'; MyDialog.Text := 'Relevant/selected Records prior to ' + sArchivedDate + ' have been Archived!' + #13 + 'This may make the figures inaccurate!'; MyDialog.CommonButtons := [tcbOk]; try MyDialog.Execute; finally MyDialog.Free; end; Regards, Ian
  3. Ian Branch

    Change of coding style/structure..

    Hi Team, Never heard of, nor seen TForm.Release in use. Intriguing Would someone care to demonstrate its use/application with a bit of code?? Ian
  4. Ian Branch

    Change of coding style/structure..

    All, I thank you for your constructive responses. Whilst I understand the aversion to using 'With', I do believe it has its place. I don't see the issue with its use here within a single code block opening a from from a button or menu selection. Yes, at a later date there may be the need to add additional code into the block, at that point in time is when the use of With becomes a serious question. Having said the above, I will in any case stick with my original code structure. Again, thank you all, Regards, Ian
  5. Ian Branch

    Any advantage to using FastMM5??

    Hi Team, In the 'Old' days I used FastMM4 in lieu of Delphi's MM because there was tangible performance, amongst other, benefit. Since then, Emba has incorporated aspects of FastMM4 to improve their own Delphi MM. Nevertheless I moved to FastMM5 when it was released and have incorporated it in every App since. I know I don't use FastMM5 to its fullest. FWIW I use EurekaLog for debugging/logging. All my Apps are simple Win32 Apps with only the occasional foray into a single thread for a database or background process. So, to my question, given the current state of play of Delphi's MM, I use D11.2 now, is using FastMM5 of any benefit to me/my Apps or am I simply including it because I always have, to no benefit?? As a side note: EurekaLog actually accommodates FastMM5 so that may be an influencing factor, or it may be simply to ride on some aspect of FastMM5... Regards & TIA, Ian
  6. Ian Branch

    Change of coding style/structure..

    Dave - 🙂 Lajos - W.. n..? Lars - I'm not exactly sure which code block you are referring to? David - It isn't complicated. It can just be easier.
  7. Hi Team, When creating a form in code.. i.e. MyForm := TMyForm.Create(xxx); If the code the creation is happening is in the MainForm's code, what are the Pros and Cons of xxx being 'Application.MainForm', 'Self' and 'Nil' please?? Does it matter?? Regards & TIA, Ian
  8. Ian Branch

    Application.MainForm v Self v Nil??

    Tks Remy.
  9. Ian Branch

    Application.MainForm v Self v Nil??

    Hi Team, Thank you for your inputs. This link gave me the insight I was after. https://www.thoughtco.com/tform-createaowner-aowner-1057563 Regards, Ian
  10. Ian Branch

    Application.MainForm v Self v Nil??

    Hi Uwe, Apologies. In my MainForm I create subforms depending on the menu selection. I currently use the format MyForm := TMyForm.Create(nil); Just an old habit/practice. I have seen variously 'Application.MainForm', 'Self' and 'Nil' in the .Create(). I am curious, if the subform creation is from the MainForm's code, what are the Pros and/or Cons of using 'Application.MainForm', 'Self' or 'Nil' in the .Create()?? Is Application.MainForm the same as Self in this context? HTH. Regards, Ian
  11. Ian Branch

    wuppdi Welcome Page for Delphi 11 Alexandria?

    Perfect. Thank you. Follow up.. Getting this error when I go to close an App I am editing, or trying to close Delphi. Running D11.2. Need to use Task Manager to close Delphi.
  12. Ian Branch

    wuppdi Welcome Page for Delphi 11 Alexandria?

    Hi @gkobler, I have one tiny preference... In a favorite's folder I have my Project Group and Projects. It would be really nice, and this is a personal preference, no obligation, if when sorting the projects the the group was the first entry. I'm sure others would have a different preference.. Regards Ian
  13. Ian Branch

    Any advantage to using FastMM5??

    Hi David, I wasn't expecting insights into my own programs performance. Rather, I was seeking the experiences of others. I have tossed the coin and removed FastMM5 att and loaded it to the Customer. We shall see if they notice anything. Ian
  14. Ian Branch

    Any advantage to using FastMM5??

    Hi David, You know, as I was writing the item I thought to myself.. The first thing someone is going to say is "it depends". 🙂 I don't believe timing it on my dev PC is not going to reveal anything useful one way or the other, compared to the real-world usage on a LAN with diverse workstation OSs, RDP & WEB access usage. And, I don't feel it is good practice to use the Customers as test agents for something like this. Ian
  15. Ian Branch

    Close App on PC Shutdown??

    Hi Team, D11.2. Apps residing on a Win 2012 Server, running on the User's PC. Most of the Users are using Win 7 but several are on Win 10. My Apps write to a log file when they open and when they close. Auditable. I have been trying to find out how/why some 'sessions' stay open in the Log overnight. The Apps have an Idle Timeout that closes them after x minutes of no mouse or keyboard activity in the App. I have discovered that some Users are not closing the App at the end of the day and are simply shutting down their PCs, while the App(s) are still open. 😞 Is there some way to detect that the PC has been set to shutdown and stall it while the App(s) close gracefully? Regards & TIA, Ian
  16. Ian Branch

    Close App on PC Shutdown??

    Hi Angus, Pat, I have a working solution the minimizes the amount of changes I have to make to other Apps. I made some changes to Pat's code to facilitate this. procedure TMainForm.CloseDB; var TS: TTimeSpan; StartDateTime, FinishDateTime: TDateTime; lUsersLogWritten: Boolean; sAction: string; begin // if dmC.DBC1.Connected then begin // // ' check savepoints or cache status? CancelEditsInsertsInDatamodules; CancelEditsInsertsInOpenForms; // CloseOpenForms; // Pat says Boo! // dmC.DBC1.CloseDataSets; // end; // case iTerminateAction of 0: sAction := 'Logged Out'; 1: sAction := 'Timed Out'; 2: sAction := 'Browser Closed'; 3: sAction := 'PC Shut Down'; end; // dmC.UsersLog.IndexName := 'SessionKey'; dmC.UsersLog.Open; // if dmC.UsersLog.FindKey([sSessionKey]) then begin // dmC.UsersLog.Edit; // dmC.UsersLog.FieldByName('Action').AsString := sAction; dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime := now; StartDateTime := dmC.UsersLog.FieldByName('StartDateTime').AsDateTime; FinishDateTime := dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime; TS := TTimeSpan.Subtract(FinishDateTime, StartDateTime); dmC.UsersLog.FieldByName('Duration').AsString := Format('%.3d:%.2d:%.2d:%.2d', [TS.Days, TS.Hours, TS.Minutes, TS.Seconds]); dmC.UsersLog.Post; // lUsersLogWritten := True; // end; // dmC.UsersLog.Close; // DBWReg.WriteString('Session Key', 'DBiWorkflow', ''); // dmC.DBC1.Close; dmC.DBS1.Close; dmC.DBE1.Close; // if iTerminateAction = 0 then begin // if not lUsersLogWritten then TaskMessageDlg('Workflow Closing error!', 'Note:- The Users Log was NOT updated. Workflow will now close..', mtError, [mbOK], 0); // end; // enlightenedCanClose := True; // Close; // end; procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin // CanClose := enlightenedCanClose; // SendMessage(Handle, EM_SETMODIFY, WPARAM(True), 0); // or have a MS product open that needs saved // if not CanClose then begin // if (GetSystemMetrics(SM_SHUTTINGDOWN) > 0) then begin // iTerminateAction := 3; CloseDB; // app is being closed by workstation shutdown // end; // enlightenedCanClose := True; // end; // end; My thanks to both of you for your input/education. Regards, Ian
  17. Ian Branch

    Close App on PC Shutdown??

    Hi Pat, Well I'm surprised! It seems the logging, Codesite, was influencing/affecting it and preventing the flow of the program continuing... 😞 Some more experimenting to happen. Regards, Ian
  18. Ian Branch

    Close App on PC Shutdown??

    Hi Pat, I replaced FormCloseQuery per above. I found an end; in the wrong place but commented out that section att anyway, and added some additional logging to CloseDB. procedure TMainForm.CloseDB(const ditto: string); var TS: TTimeSpan; StartDateTime, FinishDateTime: TDateTime; lUsersLogWritten: Boolean; begin // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('Enter CloseDB.'); {$ENDIF} // // if dmC.DBC1.Connected then // begin // // //{$IF Defined(ELogging) or Defined(Codesite)} // LogMessage('DBC1 is connected att.'); //{$ENDIF} // // // ////' check savepoints or cache status? // CancelEditsInsertsInDatamodules; // CancelEditsInsertsInOpenForms; // //end; // // // ///CloseOpenForms; ///Pat says Boo! // // // dmC.DBC1.CloseDataSets; // // // end; // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('dmC.UsersLog.IndexName := SessionKey'); {$ENDIF} // dmC.UsersLog.IndexName := 'SessionKey'; dmC.UsersLog.Open; // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('if dmC.UsersLog.FindKey([sSessionKey]) then'); {$ENDIF} // if dmC.UsersLog.FindKey([sSessionKey]) then begin // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('dmC.UsersLog.Edit;'); {$ENDIF} // dmC.UsersLog.Edit; // //case iTerminateAction of dmC.UsersLog.FieldByName('Action').AsString := ditto; dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime := now; StartDateTime := dmC.UsersLog.FieldByName('StartDateTime').AsDateTime; FinishDateTime := dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime; TS := TTimeSpan.Subtract(FinishDateTime, StartDateTime); dmC.UsersLog.FieldByName('Duration').AsString := Format('%.3d:%.2d:%.2d:%.2d', [TS.Days, TS.Hours, TS.Minutes, TS.Seconds]); dmC.UsersLog.Post; // lUsersLogWritten := True; // end; // dmC.UsersLog.Close; // DBWReg.WriteString('Session Key', 'DBiWorkflow', ''); // dmC.DBC1.Close; dmC.DBS1.Close; dmC.DBE1.Close; // if iTerminateAction = 0 then begin // if not lUsersLogWritten then TaskMessageDlg('Workflow Closing error!', 'Note:- The Users Log was NOT updated. Workflow will now close..', mtError, [mbOK], 0); // end; // enlightenedCanClose := True; // close; // // end; end; It is only logging/showing "Enter CloseDB", no further. I am going to turn off the logging and see if that is affecting it in some way. Will advise.
  19. Ian Branch

    Close App on PC Shutdown??

    Interesting. I tried again and got this .. but no further.
  20. Ian Branch

    Close App on PC Shutdown??

    @Pat Foley I have implemented this att.. procedure TMainForm.CloseDB(const ditto: string); var TS: TTimeSpan; StartDateTime, FinishDateTime: TDateTime; lUsersLogWritten: Boolean; begin // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('Enter CloseDB.'); {$ENDIF} // if dmC.DBC1.Connected then begin {$IF Defined(ELogging) or Defined(Codesite)} //LogMessage(IndexText[0]); LogMessage('DBC1 is connected att.'); {$ENDIF} // ////' check savepoints or cache status? CancelEditsInsertsInDatamodules; CancelEditsInsertsInOpenForms; //end; // ///CloseOpenForms; ///Pat says Boo! // dmC.DBC1.CloseDataSets; // dmC.UsersLog.IndexName := 'SessionKey'; dmC.UsersLog.Open; // if dmC.UsersLog.FindKey([sSessionKey]) then begin dmC.UsersLog.Edit; // //case iTerminateAction of dmC.UsersLog.FieldByName('Action').AsString := ditto; dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime := now; StartDateTime := dmC.UsersLog.FieldByName('StartDateTime').AsDateTime; FinishDateTime := dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime; TS := TTimeSpan.Subtract(FinishDateTime, StartDateTime); dmC.UsersLog.FieldByName('Duration').AsString := Format('%.3d:%.2d:%.2d:%.2d', [TS.Days, TS.Hours, TS.Minutes, TS.Seconds]); dmC.UsersLog.Post; // lUsersLogWritten := True; // end; // dmC.UsersLog.Close; // DBWReg.WriteString('Session Key', 'DBiWorkflow', ''); // dmC.DBC1.Close; dmC.DBS1.Close; dmC.DBE1.Close; // if iTerminateAction = 0 then begin // if not lUsersLogWritten then TaskMessageDlg('Workflow Closing error!', 'Note:- The Users Log was NOT updated. Workflow will now close..', mtError, [mbOK], 0); // end; enlightenedCanClose := True; close; end; end; procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('Enter FormCloseQuery.'); {$ENDIF} // CanClose := enlightenedCanClose; // {$IF Defined(ELogging) or Defined(Codesite)} if CanClose then LogMessage('Can Close.') else LogMessage('Can Not Close.'); {$ENDIF} // SendMessage(Handle, EM_SETMODIFY, WPARAM(True), 0); //or have a MS product open that needs saved // if not CanClose then begin if (GetSystemMetrics(SM_SHUTTINGDOWN) > 0) and not dmC.DBC1.Connected then closeDB('Workstation shut down'); // app is being closed by workstation shutdown // enlightenedCanClose := True; Close; end; end; From Codesite logging, neither CloseDB or FormCloseQuery are entered when I shut down the PC with the App running. 😞 May be a Win 11 thing. Ian
  21. Ian Branch

    Close App on PC Shutdown??

    Hi Guys, I am going to try each and see which is my best option. @Sherlock Where is this from - "Message.Unused", Delphi tells me "Message" is an undeclared identifier. Regards, Ian
  22. Ian Branch

    Change order of experts in GExperts Expert Manager

    Tks Thomas. Appreciated. Ian
  23. Ian Branch

    Close App on PC Shutdown??

    Gentlemen, Thank you for your patience and contributions. Very much appreciated and educational. As it was then and still is now, this is not an area I have any expertise in. Does it show? 😉 I will work with your suggestions. Regards & Tks again, Ian
  24. Ian Branch

    Close App on PC Shutdown??

    Hi Sherlock, Yes I did go back to that and I am just as confused now as I was then. I have the closing actions on the OnCloseQuery event. Under normal circumstances it works fine, but when the User shuts down their PC while the App is running/open it doesn't. The following is my OnCloseQuery.. procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); var TS: TTimeSpan; StartDateTime, FinishDateTime: TDateTime; lUsersLogWritten: Boolean; begin // if GetSystemMetrics (SM_SHUTTINGDOWN) > 0 then iTerminateAction := 3; // app is being closed by a system shutdown // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('iTerminateAction = '+IntToStr(iTerminateAction)); {$ENDIF} // lUsersLogWritten := False; // LTI1.ShowBalloonHint('Closing Workflow Database...', 'Any Open Edits and/or Inserts are being cancelled and the Database closed.'); // if dmC.DBC1.Connected then begin // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('DBC1 is connected att.'); {$ENDIF} // CancelEditsInsertsInDatamodules; CancelEditsInsertsInOpenForms; end; // CloseOpenForms; // dmC.DBC1.CloseDataSets; // dmC.UsersLog.IndexName := 'SessionKey'; dmC.UsersLog.Open; // if dmC.UsersLog.FindKey([sSessionKey]) then begin dmC.UsersLog.Edit; // case iTerminateAction of 0: dmC.UsersLog.FieldByName('Action').AsString := 'Logged Out'; 1: dmC.UsersLog.FieldByName('Action').AsString := 'Timed Out'; 2: dmC.UsersLog.FieldByName('Action').AsString := 'Browser Closed'; 3: dmC.UsersLog.FieldByName('Action').AsString := 'System Shutdown'; end; // dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime := now; StartDateTime := dmC.UsersLog.FieldByName('StartDateTime').AsDateTime; FinishDateTime := dmC.UsersLog.FieldByName('FinishDateTime').AsDateTime; TS := TTimeSpan.Subtract(FinishDateTime, StartDateTime); dmC.UsersLog.FieldByName('Duration').AsString := Format('%.3d:%.2d:%.2d:%.2d', [TS.Days, TS.Hours, TS.Minutes, TS.Seconds]); dmC.UsersLog.Post; // lUsersLogWritten := True; // end; // dmC.UsersLog.Close; // DBWReg.WriteString('Session Key', 'DBiWorkflow', ''); // dmC.DBC1.Close; dmC.DBS1.Close; dmC.DBE1.Close; // if iTerminateAction = 0 then begin // if not lUsersLogWritten then TaskMessageDlg('Workflow Closing error!', 'Note:- The Users Log was NOT updated. Workflow will now close..', mtError, [mbOK], 0); // end; // end; It doesn't work on my Win 11 PC. Happy to have the error of my ways pointed out. Regards, Ian
  25. Ian Branch

    Close App on PC Shutdown??

    Thanks Guys, Angus - I will have a look at the component. Peter - In FormCloseQuery, how can I tell if it was triggered by WM_QUERYENDSESSION ? Regards, Ian
×