Ian Branch 127 Posted May 11, 2019 Hi Team I am playing with calling a login form/dialog before the main form is created/run. Based on work by Zarko Gajic. https://www.thoughtco.com/display-a-login-password-dialog-1058469 program Passwordapp; uses Vcl.Forms, System.UITypes, MainFrm in 'MainFrm.pas' {MainForm} , LogInFrm in 'LogInFrm.pas' {LogInForm}; {$R *.res} begin // if TLogInForm.Execute then begin Application.Initialize; Application.CreateForm(TMainForm, MainForm); Application.Run; end .. .. The LoginForm is destroyed when closed. It is no longer required. procedure TLogInForm.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; I need to be able to preserve the UserID from the LogIn dialog. Is there a way to pass the UserID from the LogIn form back to the above and be able to then read it into the main form when it is created? Regards & TIA, Ian P.S. D10.3.1. Share this post Link to post
Remy Lebeau 1396 Posted May 11, 2019 (edited) 2 hours ago, Ian Branch said: Is there a way to pass the UserID from the LogIn form back to the above and be able to then read it into the main form when it is created? Of course there is. The easiest way would be to update your TLogInForm.Execute() method to return the UserID when it exits, and then add a UserID variable to your TMainForm class that you can assign to after the MainForm has been created, eg: unit LogInFrm; interface ... type TLogInForm = class public ... class function Execute: string; ... end; ... implementation class function TLogInForm.Execute: string; begin ... if LoggedIn then Result := UserID else Result := ''; end; end. program Passwordapp; uses Vcl.Forms, System.UITypes, MainFrm in 'MainFrm.pas' {MainForm} , LogInFrm in 'LogInFrm.pas' {LogInForm}; {$R *.res} var UserID: string; begin // UserID := TLogInForm.Execute; if UserID <> '' then begin Application.Initialize; Application.CreateForm(TMainForm, MainForm); MainForm.UserID := UserID; Application.Run; end ... end. Otherwise, just have the Login Form save the UserID to a global variable if successfully logged in, and then your MainForm can use that global variable when needed. PS: {code} blocks do not work on this forum. You need to use the "Code" (</>) button on the post editor's toolbar instead. Edited May 11, 2019 by Remy Lebeau Share this post Link to post
Ian Branch 127 Posted May 11, 2019 Hi Remy, Thanks for that. I was fixated on keeping the logic boolean return from the login form that I didn't think of using the UserID return. Thanks for the advice. Regards, Ian Share this post Link to post
Ian Branch 127 Posted May 11, 2019 Test for code.. class function TLogInForm.Execute(const sDatabase: string): string; begin // MessageDlg('The database passed is..' + sDatabase, mtInformation, [mbOK], 0); // with TLogInForm.Create(nil) do try if ShowModal = mrOk then Result := edtUserID.Text else Result := ''; // Result := ShowModal = mrOK; finally Free; end; // end; Ahhh. I see. Tks Remy Share this post Link to post
Gary Mugford 12 Posted May 14, 2019 Remy, Ian et al, Oddly enough, within the last few days, Larry Hengen at TPersistent also raised this issue, but in the course of doing the blog, he said, " Any long time Delphi user knows that messing with the generated DPR code in Delphi can cause all sorts of grief later when Delphi tries to auto create forms and add units to the uses clause." I've long 'fooled' around with the DPR in my programming, which might only further prove my lack of bonafides. I've noticed a noisome habit of the IDE to play around with the lines I use to create my data modules, eliminating the indentations. But I correct them. Add other data modules. Correct them again. and so on and so on. I haven't found anything grievous to this point. What am I missing? Oh, and obviously, I have to fess up to still using Delphi 7. Here's the 'annoyance' in action. I've obfuscated some of the stuff for the obvious reasons ... begin Application.Initialize; // 3/14/2003 6:06:12 PM ED: Moved this from main form create gmSetPrivateDir; session.addPassword('STILLLEARNIN'); // NOT the password Application.Title := 'SYS:2011'; DlgLogin2 := TDlgLogin2.create(nil); with DlgLogin2 do begin TblPw.DatabaseName := 'SYS'; TblPW.TableName := 'NotAPasswordDatabase'; TblPW.Active := true; showmodal; if ModalResult = 1 then begin // create main form and data modules Application.CreateForm(TFrmMain, FrmMain); Application.CreateForm(TdMain, dMain); // always resets to col 1 Application.CreateForm(TdLU, dLU); // always resets to col 1 Application.CreateForm(TdmRep, dmRep); // always resets to col 1 Application.CreateForm(TFrmHistorySearch, FrmHistorySearch); // always resets to col 1 Globals.Version := '2011.8.8.'; // always resets to col 1 Globals.UserName := DlgLogin2.TblPW.FieldByName('User').asString; Globals.DEB := DlgLogin2.TblPW.FieldByName('MiniID').asString; Globals.RandomDateNum := CreateRandomNumDateInt64(0); if Globals.DEB = '' then Globals.DEB := 'UNK'; Globals.SecLevel := DlgLogin2.TblPw.FieldByName('SecLevel').asInteger; //----------Security Levels--------Enable/Disable Menus--------------------- FrmMain.mManager.Enabled := (Globals.SecLevel >= 80); FrmMain.mExecutive.Enabled := (Globals.SecLevel >= 90); FrmMain.mProgrammer.Enabled := (Globals.SecLevel >= 100); FrmMain.mODefaults.Enabled := (Globals.SecLevel >= 80); FrmMain.mOEditCustomer.Enabled := (Globals.SecLevel >= 75); FrmMain.mOSuperCusEd.Enabled := FrmMainOT6.mOEditCustomer.Enabled; FrmMain.mEDupePart.Enabled := (Globals.SecLevel >= 80); //---------------------------------------------------------- txt := gmPrinterName(False); FrmMain.StatusBar.Panels[3].text := txt; txt := uppercase(txt); if (pos('HP',txt) + pos('LEX',txt) + pos('XRX',txt) + pos('XEROX',txt) + pos('SAMS',txt) + pos('KINGS',txt) + pos('PDF',txt) + pos('BROTHER',txt) = 0) then ShowDlgOops('WARNING: You''re default printer is not on ' +'the standard printer list. This could be because ' +'you are signing on from a computer that you have ' +'no prior account with and the list of default ' +'printers has not been installed. Be aware of this ' +'when trying to print. You might have to switch ' +'printers or contact me to get printers ' +'installed'); FrmMain.StatusBar.Panels[4].text := Globals.DEB + ' / ' + intToStr(Globals.SecLevel); DlgLogin2.free; dMain.mTblPW.close; Application.Run; end else DlgLogin2.free; end; end. As you can see, the lines right after main forms createForm line always revert to flush left. I space them over, save the DPR and the next time I go to edit it, they are right back where they started from. Finally, I stopped worrying about it. I have a Globals record that is brought in through a unit specifically designed for it, that I can share around all the apps. DEB stands for DataEnteredBy and is a short indicator of the full name. SecLevel is Security Level and it's on a 30-100 gradiant with me being the only 100 and the Boss being a 99. The minions fall somewhere short of that depending on oversight capability. I make menus appear to people who have the title. I check for printers because in doing so, I also check to see whether they've signed in from a fully-setup account in the process. Guess that's about it. I know it's not artful and WHO knows whether it breaks down in newer versions of Delphi. But what is the grief? Thanks, GM Share this post Link to post
PeterBelow 238 Posted May 14, 2019 Modifying the DPR file's body can be done safely, if you know what you are doing and where the IDE may step on your modifications 😉. In my experience is best to just not add reams of code to the main block directly but only the absolute minimum you get away with, usually a single call to a function that then does the brunt of the work. This has never caused a problem for me if said line was added directly after the Application.Initialize line. What the IDE modifies are the uses clause and the lines to create the autocreated objects (after the first Application.CreateForm line). Additions you make there may get wiped out, so don't touch these sections of the dpr file. Adding procedures, functions, types, constants, even classes to the dpr file works without problems otherwise, although it is a bad idea in my opinion. Share this post Link to post
Gary Mugford 12 Posted May 14, 2019 2 hours ago, PeterBelow said: Modifying the DPR file's body can be done safely, if you know what you are doing and where the IDE may step on your modifications 😉. In my experience is best to just not add reams of code to the main block directly but only the absolute minimum you get away with, usually a single call to a function that then does the brunt of the work. This has never caused a problem for me if said line was added directly after the Application.Initialize line. What the IDE modifies are the uses clause and the lines to create the autocreated objects (after the first Application.CreateForm line). Additions you make there may get wiped out, so don't touch these sections of the dpr file. Adding procedures, functions, types, constants, even classes to the dpr file works without problems otherwise, although it is a bad idea in my opinion. Sage advice. I've been through SOME puzzles coping with DPR manipulation by the IDE. It's why I keep a commented complete copy of the code that resembles my sample, PLUS having the DPR in my versioning software from AJC. Because of long term comfort, I've continued to do it, but like many things (including my change in database backbone), maybe it's time to do things the way the professionals do. The thought that my way of DPR manipulation might have crept into the issue I've had with BDE and Windows 10, prompted me to ask about the comment in TPersistent. Thanks, GM Share this post Link to post