Announcement

Collapse
No announcement yet.

Showmodal aus formcreate

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Showmodal aus formcreate

    Und noch ein Problem
    Ich habe gerade versucht aus einer Formcreate Procedure ein showmodal aufruf zu machen. Leider mit dem Erolg dass ich einen wundschönen Ergebnis einer EAccessviolation.
    ICh erklär mal kurz was ich vorhabe, vielleicht könnt ihr mir ja dann helfen.
    Also, wenn ich das Programm starte, lese ich im Formcreate einen Registryschlüssel aus, ist dieser nicht vorhanden, soll das Optionen Fenster des Progs erscheinen und dem User die Möglichkeit geben einige Einstellungen zu machen. Leider bekomme ich aber statt des Fensters die oben genannte Violation.
    Mach ich etwas falsch mit dem Showmodal oder gibt es ander Möglichkeiten, am Start des Progs so etwas abzufragen??

    Würde mich freuen wenn ihr mir helfen könnet.

  • #2
    Hallo Christopher,<br>
    Du versuchst wahrscheinlich im OnCreate-Event des Hauptformulars ein anderes<br>
    Formular anzuzeigen. Wenn dieses Formular automtisch erzeugt wird, muß es schief gehen.<br>
    Da das Hauptformular das erste Formular ist das erzeugt wird, kann das andere Formular <br>
    im OnCreate Event des Hauptformulars noch nicht existieren. Daher die Schutzverletzung.<br>
    Die Lösung liegt darin, das zweite Formular per Hand zu erzeugen. <b>Dafür ist es wichtig,<br>
    das Du das Formular unter Projekt/Optionen/Formulare in die Liste mit den<br>
    verfügbaren Formularen schiebst.<br>
    </b> Hier jetzt das Beispiel:<br>
    <pre>
    <font face="Verdana" size="1" color="#000000">unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    unit2;

    type
    TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    private
    { Private-Deklarationen }
    public
    { Public-Deklarationen }
    procedure ShowUserWindow;
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.DFM}

    procedure TForm1.ShowUserWindow;
    begin
    With TForm2.Create(Application) do
    begin
    Try
    If ShowModal=mrOk then
    begin
    // Hier kann evt. noch etwas gemacht werden
    end;
    Finally
    Release;
    end;
    end;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    ShowUserWindow;
    end;

    end.

    unit Unit2;

    interface

    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls;

    type
    TForm2 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    private
    { Private-Deklarationen }
    public
    { Public-Deklarationen }
    end;

    var
    Form2: TForm2;

    implementation

    {$R *.DFM}

    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    Action:=caHide;
    end;

    procedure TForm2.Button1Click(Sender: TObject);
    begin
    Close;
    end;

    end.</font>
    </pre>
    &#10

    Comment


    • #3
      Hier die Formulardateien für das Beispiel<br>
      <pre>
      <font face="Verdana" size="1" color="#000000">object Form1: TForm1
      Left = 265
      Top = 263
      Width = 412
      Height = 244
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      OnCreate = FormCreate
      PixelsPerInch = 96
      TextHeight = 13
      end

      object Form2: TForm2
      Left = 292
      Top = 272
      Width = 352
      Height = 129
      Caption = 'Form2'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      Position = poScreenCenter
      OnClose = FormClose
      PixelsPerInch = 96
      TextHeight = 13
      object Label1: TLabel
      Left = 8
      Top = 4
      Width = 309
      Height = 37
      AutoSize = False
      Caption =
      'Dieses Fenster wurde zur Laufzeit erzeugt. Hier könnten die Anwe' +
      'nder jetzt einige Daten eingeben.'
      WordWrap = True
      end
      object Button1: TButton
      Left = 132
      Top = 64
      Width = 75
      Height = 25
      Caption = 'Schließen'
      TabOrder = 0
      OnClick = Button1Click
      end
      end</font>
      </pre>
      Jens Schuman

      Comment


      • #4
        Ich verstehe zwar nicht genau was das bewirkt, was ich da schreibe(eigentlich sollte man dann aufhören zu programmieren), aber es funktioniert und das freut mich schonmal.

        Wenn du Spaß dran hast kannst du mir bei Gelegenheit ja mal sagen, was da konkret passiert.
        Was Try und finaly machen weiß ich, das man sich mit dem with xxx do schreibarbeit erleichtert auch, aber beim rest, kann ich nur ahnen was der macht

        Comment


        • #5
          Hallo,
          die Projektdatei ihrer Anwendung hat folgenden Aufbau:<PRE>

          begin
          Application.Initialize;
          Application.CreateForm(TForm1, Form1);
          Application.CreateForm(TForm2, Form2);
          Application.Run;
          end.
          </PRE>
          Sie haben nun versucht im FormCreate von Form1 das Form2 modal anzuzeigen und genau hier liegt das Problem, denn Form2 kann nicht modal angezeigt werden, da es noch gar nicht existiert. Sie sehen in der Projektdatei, das erst nach dem Erzeugen von Form1 das Form2 erzeugt wird.<br><br>
          Der Trick ist nun (bei dem Beispiel von Jens Schumann), dass Sie Form2 nicht automatisch von Delphi erzeugen lassen, sondern einfach im FormCreate von Form1 den Constructor von Form2 aufrufen und es dann modal anzeigen. Da sie es modal anzeigen wollen und nach dem schließen die Ressourcen gleich wieder freigeben wollen, können sie die WITH-Anweisung zum Erzeugen nutzen. Sie brauchen nicht Form2:= TForm2.create; schreiben, da am Ende der With-Anweisung auch der Lebenszyklus des Formulars endet, sprich sie nutzen es nicht mehr, geben den Speicher frei und brauchen deshalb keine Variable, um noch einmal auf die Instanz von Form2 zuzugreifen. Da sie selbst den Speicher alloziert haben, geben sie ihn auch selbst mit release frei, deshalb muss als TCloseAction von Form2 caHide angegeben werden, damit beim Schliessen des Formulars das Form2 nur verdeckt wird(unsichtbar). Sie kehren nach dem Drücken des Buttons Schliessen in folgende Abfrage zurück und könnten dann immer noch etwas ausführen, sprich mit den Daten des Form2 arbeiten.
          <PRE>
          If ShowModal=mrOk then
          begin
          // Hier kann evt. noch etwas gemacht werden
          end;
          </PRE>Erst nach dem Verlassen dieser Abfrage wird der Speicher freigegeben. Zu beachten ist, dass Button1Click durch Close das Ereignis OnClose aufruft. ShowUserWindow kapselt nun alle Anweisungen dieses Vorgangs und wird von Form1Create aufgerufen.<br><br>Gruß Ale

          Comment


          • #6
            Gut das habe ich nun verstanden, funktioniert auch so wie es soll, aber nun bin ich einen Schritt weiter . Nun blende ich auf selbe Art und weise beim Start ein Fenster mit Benutzername und Kennwort auf, klickt nun der Benutzer aud abbrechen, soll das Programm beendet werden. Habt ihr da auch noch eine Idee?? Das HauptFenster ist ja noch immer nicht komplett erstellt, demnach kann ich es nicht schliessen.

            Christophe

            Comment


            • #7
              Hallo,
              beim Suchen nach "Splash" -Screen habe ich folgenden Beitrag von Andreas Kosch gefunden, wie man einen Login-Dialog erzeugen kannAlternativ könntest du bei deinem Abbrechen-Button Application.terminate oder Halt aufrufen)<br><br>
              Zuerst wird geprüft, ob in Delphi im Dialog Projekt | Optionen | Formulare alle Hilfsformular in der rechten Liste der Verfügbaren Formulare stehen. Nur das Hauptformular steht in der linken Liste der automatisch erzeugten Formulare.

              Dann kann man direkt in der DPR-Datei die Hilfsformular bei Bedarf erst zur Laufzeit erzeugen/aufrufen/auswerten. Das folgende Beispiel demonstriert, dass das automatisch erzeugten Hauptformular erst dann von Delphi erzeugt wird, wenn der vorgeschaltete Passwortdialog richtig beantwortet wurde:
              <PRE>
              program Vorbinder; uses
              Forms, SysUtils,
              VorbinderFrmMain in 'VorbinderFrmMain.pas' {FormMain},
              VorbinderFrmPassword in 'VorbinderFrmPassword.pas' {FormPassword}; {$R *.RES} var
              bLoginOK : Boolean; const
              mrYes = 6; // anstelle Controls.pas einzubinden begin
              FormPassword := TFormPassword.Create(nil);
              try
              FormPassword.ShowModal;
              bLoginOK := FormPassword.ModalResult = mrYes;
              finally
              FormPassword.Free;
              end;
              if bLoginOK then
              begin
              Application.Initialize;
              Application.CreateForm(TFormMain, FormMain);
              Application.Run;
              end;
              end.
              </PRE>
              Wenn die globale Variable bLoginOK auf TRUE gesetzt wird, startet die Anwendung auf dem für Delphi typischen Weg. Das Splashfenster muss dann nach Initialize eingefügt werden, ab dieser Stelle gibt es keine Besonderheiten mehr

              Comment


              • #8
                Das wäre ne Methode..
                habe mir gerade aber noch was ausgedacht und in ansetzten auch schon getestet.
                Es ist wie ich finde ein wenig simpler als dein Vorschlag.
                Anstatt den close Befehl aus der create Form für das PW Fenster zu starten, kann man ganz einfach einen Timer aufrufen. Dieser hat dann eine Zeit von 1 (müsste man testen ob man bei älteren PCs höher gehen muss) und ruft einfach den CLose BEfehl auf. Aufgrund der Verzögerung von der einen Millisekunde, baut sich das Form auf und kann geschlossen werden.
                Beim schliessen geht es, beim öffnen werde ich es nun mal testen.

                Dennoch danke.

                Christophe

                Comment


                • #9
                  Hallo,<br>das Beispiel sollte nur zeigen, wie man einen Login-dialog realisiert. Deine Timer-methode kann ich nicht nachvollziehen. Was willst du konkret programmieren

                  Comment


                  • #10
                    So habe nun auch den rest getestet.<br>
                    Wie ich mir gedacht habe, kann man auch die Form auf diese Art und Weise öffnen. Wer nun wegen der Wartezeit auf Nr. sicher gehen will, kann ja noch ein Try einbauen. Scheitert der Versuch die Form zu öffnen, läuft der Timer weiter, andernfalls wird er auf false gesetzt.

                    So long

                    Christophe

                    Comment


                    • #11
                      Viele Wege führen nach Rom

                      Comment


                      • #12
                        Dummerweise sind momentan fast alle zugeschneit , aber das nur so am Rande, um mal ein wenig vom Thema abzuweichen.

                        Christophe

                        Comment


                        • #13
                          Hi Christopher,<br>
                          <br>
                          und hier (Hamburg) werden die Wege schon wieder freier :-)<br>
                          Aber noch mal zurück zum Thema:
                          Aufzuhören mit dem Programmieren, wenn man was nicht verstanden hat? Ich weiss nicht so recht...?!<br>
                          Da sehe ich eher zwei Möglichkeiten:<br>
                          1. Sich darüber freuen, dass es funktioniert und mit dem Rest weitermachen. (und später die 2. Möglichkeit)<br>
                          2. Schritt für Schritt durch die unverständlichen Stellen gehen, und so nach und nach für Verständnis sorgen<br>
                          <br>
                          Das ist zwar manchmal auch nicht ganz leicht und kostet Zeit, die kannst Du aber locker wieder einsparen, da damit auch Deine programmiertechnischen Möglichkeiten/Varianten sich vermehren.<br>
                          Ist schon richtig, dass viele Wege zum Ziel führen, und im seltensten Fall gibt es nur einen richtigen.<br>
                          Aber je mehr Wege man kennt, umso besser kann man den für das aktuelle Problem richtigen auswählen.<br>
                          <br>
                          Ciao<br>
                          Chri

                          Comment


                          • #14
                            Hallo Christopher,

                            Ich hab mir mal die ganzen schönen Kommentare hier durchgelesen und auch prinzipiell keine Einwände dagegen, wobei ich das mit dem Timer auch nicht so richtig nachvollziehen kann.
                            Aber zu deinem Problem am Anfang. Die Idee das Formular dynamich zu erstellen ist glaub ich für den Umfang deines Projektes etwas zu übertrieben. wie Findest du die Idee, wenn du einfach in den Projektoptionen im Feld <I>Automatisch erzeugen</I> deine "Dialoge", die du vor dem Hauptformular brauchst, vor das Hauptformular ziehst. Somit änderst du die Erstellungsfolge der Formulare. Das ist nicht so aufwendig, und bewirkt das Gleiche.

                            mfg Stefa

                            Comment

                            Working...
                            X