![]() |
Loginform soll geschlossen werden bevor MainForm erscheint
Hi,
ich habe hier ne Anwendung die eine MainForm hat sowie eine Form mit Login und n paar anderen Forms. Als erstes wird die Login Form erzeugt und angezeigt. Wenn Username und Password stimmen soll die Form aber verschwinden und die MainForm angezeigt werden. Ich habe mir ueberlegt ich kann ja die LoginForm mit .Hide verstecken und wenn ich die MainForm schliesse ist sie mit weg. ABER: Man sieht sie nochmal fuer einen Bruchteil einer Sekunde. Das moechte ich aber nicht. Mit .Close kann ich die LoginForm auch nicht schliessen da dann das ganze Programm geschlossen wird komischerweise. Hat mir jemanden n guten Rat/Idee deshalb? Danke |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Wird das Login-Fenster mit Close geschlossen und dadurch das Programm beendet, dann bedeutet das, das dein Login-Fenster das Hauptformular deines Programmes ist.
Besser ist es, die Automatische Erzeugung des Login-Fensters komplett zu verbieten und im OnCreate-Event deines Mainforms das Login-Fenster händisch zu erzeugen und im Fehlerfall die Applikation zu beenden (Application.Terminate()) |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Hi, ...schon mal versucht, den ShowModal-Aufruf deiner Login-Form in der Projektdatei noch vor dem deiner Mainform zu starten?
Delphi-Quellcode:
program Project1;
uses Forms, Controls, Unit1 in 'Unit1.pas' {Form1}, Unit2 in 'Unit2.pas' {Form2}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.CreateForm(TForm2, Form2); // deine Login-Form if Form2.ShowModal = mrCancel then Application.Terminate; Application.Run; end. |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Ich würde das eher so machen:
Delphi-Quellcode:
An dieser Stelle verweise ich dich auch mal auf den Sourcecode von meinem Spiel:
program Project1;
uses Forms, Controls, Unit1 in 'Unit1.pas' {Form1}, Unit2 in 'Unit2.pas'; {$R *.res} var login:TForm2; begin Application.Initialize; login := TForm2.Create(nil); if login.ShowModal = mrCancel then begin Application.Terminate; end else begin Application.CreateForm(TForm1,Form1); Application.Run; end; end. ![]() [Edit]Kleiner Fehler[/Edit] [Edit2]Fehler im URL Tag[/Edit2] [Edit3]Noch eine kleine Verbesserung[/Edit3] |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Und ich würde sogar das Login-Form als Hauptformular definieren.
Klickt man auf Login, wird einfach eine Instanz des 'Mainforms' erzeugt und angezeigt. Nach Beendigung des MainForms ist man wieder im Login-Formular. Alternativ kann man die Eigenschaft 'ModalResult' des Login-Buttons auch auf mrClose setzen. Im OnClick-Ereignis des Login-Buttons wird die Hauptanwendung mit ShowModal gezeigt. Wenn der Anwender dann in der Hauptanwendung auf 'Beenden' klickt, wird zuerst das Hauptformular und dann der Login-Dialog geschlossen.
Delphi-Quellcode:
Das hat gegenüber den anderen beiden Lösungen den Vorteil, das man erstens nicht im Projektquelltext rumwurschteln muss und 2. keine unliebsamen Überrraschungen erlebt, wenn man im OnCreate der Hauptanwendung gleich ein Application.Terminate aufruft.
Procedure TMyLoginDialog.btLoginClick (Sender : TObject);
Begin With TMainForm.Create(Nil) Do Begin ShowModal; Release; End; // ModalResult := mrClose; <-- die '//' wegnehmen, wenn der Login-Dialog immer da sein soll. End; |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Ich würde gar nix davon machen!
Hauptformular:
Delphi-Quellcode:
procedure TMainFrm.FormShow(Sender: TObject);
begin PasswordFrm.ShowModal; end; Passwortformular:
Delphi-Quellcode:
var
AllowClose: Boolean; procedure TPasswordFrm.AcceptBtnClick(Sender: TObject); begin if PasswordEdit.Text = 'Passwort' then begin Accepted := True; Close; end else begin ShowMessage('Das Passwort ist ungültig!'); PasswordEdit.Clear; end; end; procedure TPasswordFrm.ExitBtnClick(Sender: TObject); begin Application.Terminate; end; procedure TPasswordFrm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin if AllowClose = True then CanClose := True else CanClose := False; end; |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Äh...Soll ich mich jedesmal einloggen, wenn das Hauptformular mal wieder sichtbar wird?
Wenn überhaupt, dann im OnActivate. Das ist dann besser. Also: Nachdem hier alle wild durcheinander gepostet haben, ist das hier (99% Muetze) wohl das Einfachste:
Delphi-Quellcode:
Wobei 'LoginCorrect' natürlich eine Funktion ist, die True liefert, wenn der Anwender sich korrekt eingeloggt hat und False, wenn nicht.
Procedure MyMainForm.OnActivate (Sender : TObject);
Begin If Not LoginCorrect Then Application.Terminate; End; |
Re: Loginform soll geschlossen werden bevor MainForm erschei
:shock: MuTzE bitte und nich Muetze!!!!!!!!! :evil:
|
Re: Loginform soll geschlossen werden bevor MainForm erschei
Ich habe das in mehreren kommerziellen Applikationen wie folgt gelöst und fahre sehr gut damit:
Delphi-Quellcode:
Nachtrag! Die Funktion CHECK im Formular / Unit "FPassword":
begin
Application.Initialize; if ( not Assigned( FPassword ) ) then FPassword := TFPassword.Create( FPassword ); if ( not Session.Users.LoadFromFile( ApplicationPath + c_ConfigDir + 'Users.xml' ) ) then mBox( _( 'FEHLER!' ), _( 'Ein Fehler beim Lesen der Benutzerdaten ist aufgetreten. '+ 'Login NUR Superuser möglich. Abbruch!' ), TRUE ); if ( FPassword.Check( mode_start, TRUE, FALSE ) = pass_ok ) then begin Application.CreateForm(TFUserManager, FUserManager); Application.CreateForm(TFTrackoutManager, FTrackoutManager); Application.Run; end else begin Session.Free(); FPassword.Free(); end; end.
Delphi-Quellcode:
function TFPassword.Check( mode: TMode;
ShowCloseButton: Boolean; ShowOKButtonOnly: Boolean = FALSE ): TPasswordResultType; begin result := pass_failed; MayClose := FALSE; PWResult := pass_failed; accessmode := mode; if ( ShowOKButtonOnly ) then button_cancel.Enabled := FALSE else button_cancel.Enabled := TRUE; if ( showCloseButton ) then begin button_cancel.ModalResult := mrAbort; button_cancel.Caption := _( '&Beenden' ); end else begin button_cancel.ModalResult := mrCancel; button_cancel.Caption := _( '&Abbrechen' ); end; // If the workstation has a valid login, quit here... if ( Session.Active ) then begin if ( ( ( Session.CheckUserRights( mode ) ) AND ( Session.Users.Count > 0 ) ) OR ( Session.UserType = type_superuser ) ) then begin result := pass_ok; exit; end else begin if ( mBox( _( 'Zugriff verweigert!' ), _( 'Sie besitzen nicht die nötigen Rechte, um auf diese ' + 'Resource zugreifen zu können. Wollen Sie den Vorgang ' + 'abbrechen?' ), FALSE ) ) then exit; end; end; self.ShowModal(); result := PWResult; accessmode := mode_none; resetInput(); close(); end; |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Und außerdem! Wenn dann beim OnCreate und nich beim OnActivate!
* OnCreate * OnShow * OnPaint * OnActivate * OnResize * OnPaint :wink: _____________ EDIT: So und wie ich grad feststellen musste geht mit meiner Methode nur OnShow! Ich wusste schon warum das so ist. Aber wenn die von moonwhaler geht, nimm die. |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
|
Re: Loginform soll geschlossen werden bevor MainForm erschei
@moonwhaler: MuTzE :mrgreen: ) seine Version ist aber doch ein klein wenig kürzer. Und auch gilt, das ich den Projektquelltext nicht so gerne anfasse. Da kommt dann Delphi ab und an doch durcheinander.
Die Version im OnCreate ist latürnich noch eleganter. Sagen wir: MuTzE's Version mit meiner Anmerkung und MuTzE's abschließenden Kommentar ist optimal*, ergo:
Delphi-Quellcode:
* jedenfalls meine Meinung.
Procedure TMyMainForm.OnCreate (Sender : TObject);
Begin If Not LoginCorrect then Application.Terminate; End; |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Also ich hab ja hier schon nen Programm, aber da haut das nich hin, wenn ich das Passwortformular zeige im OnCreate! Es geht bei mir nur im OnShow Modus, wobei, das wie du schon sagtest immer kommt, wenn das Formular eingeblendet wird.
Man könnte aber noch eine 2. Varible einbinden, anhand der überprüft wird, ob das Passwort bereits richtig eingegeben wurde. Hauptformular:
Delphi-Quellcode:
public
Passed: Booloean; end; procedure TMainFrm.FormShow(Sender: TObject); begin if not Passed then PasswordFrm.ShowModal; end; Passwortformluar:
Delphi-Quellcode:
procedure TPasswordFrm.AcceptBtnClick(Sender: TObject);
begin if PasswordEdit.Text = 'Passwort' then begin Accepted := True; MainFrm.Passed := True; Close; end else begin ShowMessage('Das Passwort ist ungültig!'); PasswordEdit.Clear; end; end; |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Ich kenn das Problem. Weil ich Dir erstmal gar nicht geglaubt habe, hab ich also einen Drei-Zeiler geschrieben, mit der Passwortabfrage im OnCreate. Dann darf aber kein anderes Formular automatisch instantiiert werden.
Dr Projekt-Quelltext sieht also so aus:
Delphi-Quellcode:
Und die MyMainForm wie oben beschrieben. Dann kann ich mich einloggen (oder nicht).
Begin
Application.Initialize; Application.CreateForm(TMyMainForm, MyMainForm); Application.Run End.
Delphi-Quellcode:
wichtig ist, das das 'Application.Terminate' ja nicht sofort aufhört, sondern nur eine WM_QUIT Message in die Messagequeue schiebt. Das Application.Run fängt dann an, die Messages zu verarbeiten. Mehr oder minder früh wird dann das WM_QUIT entdeckt. Deshalb ist es imho wichtig, wirklich nur die eine Form im Hauptprogramm der Anwendung zu instantiieren.
Procedure TMyMainForm.FormCreate (Sender : TObject);
Begin If InputBox('Login','Benutzername','') <> 'MuTzE' Then Application.Terminate Else Begin // Initialize application's datamodules, forms etc. End; End; |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Hi,
vielen Dank euch allen hier. Werd mich da mal durchwurschteln heute abend! |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
So wie es aussieht, scheint nur die Methode von igel457 und moonwahler diesbezüglich was zu taugen (allerdings fehlte irgendwie im positiven Login-Fall jeweils noch ein Free, oder?). Nur durch ein erstes Aufrufen von Application.CreateForm scheint die MainForm definiert zu werden, so dass mittels 'nur' TForm.Create-Anweisungen ohne Schwierigkeiten davor andere Formen erzeugt und genutzt werden können. ..und warum nicht im Projekt-File herumschreiben. Das ist imo Raum für Quellcode wie jeder andere! |
Re: Loginform soll geschlossen werden bevor MainForm erschei
:roll:
|
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
edit: gut gut, ich meinte jetzt natürlich das MainForm-Flackern, welches ebenfalls für einen Bruchteil einer Sekunde in dem Falle zu sehen ist, in dem man den Login abbricht. Dann nämlich taucht das MainWindow nochmal ganz kurz auf, weil es ja eben schon createt ist. Und ich nehme doch mal sehr schwer an, dieses Flackern mag Mackhack mindestens genausowenig.... :mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen: |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Genau,
ich will kein Flackern des Login-Fensters. Also muss ich als MainForm das Login-Fenster in den Projekt-Optionen einstellen sehe ich das richtig? |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Bei mir flackert nicht das Loginfenster, sondern das Hauptformular, wenn man das Programm schon beim Loginfenster beendet.
Du müsstest dich mal entscheiden, ob du willst das es nicht flackert oder ob du etwas im projectcode veränderst, das du ja nicht gerne machst, wie du meintest. Ich denke mehr Optionen gibt es nicht, es sei denn jemand finde eine. ____________ EDIT: Ähhhhhh, der letzte Absatz kommt einfach weg, da hab ich mich wohl verlesen :mrgreen: |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mich mal kurz hingesetzt. Ich hoffe das reicht so.
Man könnte ja zusätzlich noch den Taskbareintrag vom Passwortformular entfernen. |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Weiß jetzt nicht ob ich das richtig verstanden habe
aber es gäbe eine möglichkeit jegliches flackern zu unterbinden ohne viel aufwand. Versuchs mal mit der Sendmessage .. SendMessage( hwnd, WM_SETREDRAW, False, 0); Dies verhinder das neuzeichnen einer Form oder eines Control. Den status wieder auf standard setzen geht so.
Delphi-Quellcode:
Gruß
procedure(Redraw);
var ClientRect : TRect; Begin SendMessage(hwnd , WM_SETREDRAW, True, 0); GetClientRect(hwnd ,ClientRect); RedrawWindow(hwnd, ClientRect, 0, RDW_ERASE Or RDW_INVALIDATE Or RDW_ALLCHILDREN Or RDW_UPDATENOW); End |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Klappt leider nicht!
Und es müsste so heißen: SendMessage(hWnd, WM_SETREDRAW, 0, 0); |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Eigentlich waere meine liebste Loesund diese dass das MainForm das Mainform ist, die auch gestartet wird. Von da aus kommt automatisch die Login Form zum einloggen, oder wenn man auf Cancel klickt der Login Form dass das Programm beendet wird.
Nach erfolgreichem Login soll der Login Screen weg am liebsten .Close und nur noch die MainForm da sein! |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
Das sind boolische werte. False verhindert das zeichnen, True aktiviert es wieder. gruß |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
Ansonsten mal als mögliche Lösung für euer Problem die MainForm nicht aufflackern zu lassen:
Delphi-Quellcode:
Bringt das vielleicht Abhilfe, wenn man es vor dem Mainform anzeigen setzt?
Application.ShowMainform := False;
|
Re: Loginform soll geschlossen werden bevor MainForm erschei
@ Muetze1
Wo ist dein Problem? Er hat es so geschrieben - SendMessage( hwnd, WM_SETREDRAW, False, 0); Ich habs so geschrieben - SendMessage( hwnd, WM_SETREDRAW, 0, 0); Und wenn du dir mein Projekt angeschaut hättest, dann hättest gesehn, dass ich da "Application.ShowMainForm = False" genutzt habe, somit ist dein Beitrag nutzlos! :evil: @ EWeiss Der Compiler meckert bei mir, wenn ich Boolsche Werte nehme, da muss Integer rein. func Windows.SendMessage(hWnd: HWND; Msg: Cardinal; wParam: Integer; lParam: Integer): Integer |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
Sorry habe mich da im Namen vertan Zitat:
Entweder 0 oder -1 Ok hat sich erledigt. Gruß EDIT: Mag an den Compiler liegen wie du sagst. In VB ist das wurscht der compiler weiß das Bool=Integer ist. |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
Es wäre ab und zu mal angebracht nicht nur zu lesen, sondern auch mal Anhänge zu laden und zu testen. Ich bin der Meinung, dass mein Projekt so funktioniert wie er es haben will. Zitat:
|
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zitat:
Ein versuch war es allemal wert. Ich benutze das für List oder Treeviews damit beim einladen langer Playlisten die Controlls nicht flackern. Funktioniert super! Wenn mir nochwas einfällt meld ich mich wieder. Gruß |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Hi all,
auch mir missfällt das Abändern des Projekt-Quelltextes. Mir missfällt aber auch so ziemlich jede andere Restriktion. Bei Datenbankanwendungen gibt es einen sehr komfortablen Ansatz, der lediglich die automatische Erzeugung des Hauptdatenmoduls vor allen anderen Datenmodulen und Formularen erfordert. Im Ereignis OnCreate() werden dort zuerst die user credentials entgegengenommen. Scheitert der Verbindungsaufbau mit diesen Angaben, dann kann die Anwendung einfach verlassen werden.
Delphi-Quellcode:
In allen anderen Fällen hat sich bei mir das Einklinken in die InitProc bewährt.
procedure HaltApplication(msg: String);
begin if msg <> '' then ShowMessage(msg); // shutdown reason with Application do begin Terminate; // walk the TermProc chain Free; // free resources Halt; // shut down end; end; procedure TDM.DataModuleCreate(Sender: TObject); var userName, passWord, roleName: String; canceled: Boolean; begin with TLoginForm.Create(nil) do begin canceled := not Execute(); Free; end; if canceled then HaltApplication(''); Connection.ConnectionString := GetConnectionString(userName, passWord, roleName); try Connection.Connected := True; except on E: Exception do HaltApplication(E.message); end; // ... end; Grüße vom marabu |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Hallo,
also ich finde, das "Rumwurschteln im Projekt-Quellcode" am einfachsten. Allerdings steht in meiner DPR nur 1 Zeile
Delphi-Quellcode:
naja, program bla; uses unit_Start; usw. ;)
DoStart;
und die Unit Start enthält dann halt
Delphi-Quellcode:
unit_Start;
bla procedure DoStart; begin Application.Initialize; if not ExcecuteFormLogin32(Application) then Exit; Application.CreateForm(TForm_MainZES, Form_MainZES); Application.Run; end; Heiko |
Re: Loginform soll geschlossen werden bevor MainForm erschei
Zugegeben: Den Projektquelltext für diesen Zweck zu modifizieren mag dem ein oder anderen nicht gefallen, für mich persönlich ist es eine elegante und absolut fehlerfreie Möglichkeit vor Ausführung von egal-was-auch-immer diverse Einstellungen und Abfragen vorzunehmen. Probleme hatte ich damit bisher nie und diese Art von Programmierung nutze ich jetzt seit Delphi 5 und aufwärts ohne jemals damit auf die Nase zu fallen.
Letztlich ist das natürlich Geschmackssache, denn jeder hat so seine Eigenarten und Vorstellungen, wenn es ums Programmieren geht. Viele Wege führen nach Rom. In diesem Sinne. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:36 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz