![]() |
Buttonabhängiges Schließen des Programms
Hi DPler,
ich habe mich jetzt schon zum zweiten Mal gefragt, wie man das schließen einer Anwendung abhängig davon machen kann, welcher Button gedrückt wird. Konkret geht es darum, dass ich gerade ein Chat schreibe. Nun wollte ich am Anfang ein Anmeldefenster einfügen. Wenn man das Programm startet, dann sieht man im Hintergrund das eigentliche Chatfenster (ist nicht enabled). Davor ist eine kleiner Fenster zu sehen, in welchem man Benutzername und Passwort eingibt, dann auf Anmelden klickt. Beim Klick auf den Button Anmelden soll nur dieses Fenster geschlossen werden. Wenn man aber auf das rote Kreuz oben in der Ecke des Fenster klickt, soll das Programm beendet werden. Hoffe ihr könnt nachvollziehen, wo mein Problem liegt. Ich habe mir auch schonmal OnCloseQuery angeschaut, aber das passt auch nicht auf mein Problem. Denn das Anmeldefenster soll ja in jedem Fall geschlossen werden, nur die Behandlung des Hauptfensters soll ja abhängig von dem gedrückten Button sein. LG, hans ditter |
AW: Buttonabhängiges Schließen des Programms
Guck dir mal TForm.ShowModal und TForm.ModalResult an, bzw. auch TButton.ModalResult. (Tipp: Schließen über das rote X dürfte "mrNone" liefern.)
|
AW: Buttonabhängiges Schließen des Programms
Hey, danke für die Antwort. Werds mir morgen mal anschauen... bin jetzt echt müde... :|:vernupft::corky::drunken: :pale: :freak:
(Ok, ich geb zu, hab's grad ein biiischen übertrieben mit den Smileys.... :D und schon wieder einer, ein Teufelkreis ... :lol: :firejump:) |
AW: Buttonabhängiges Schließen des Programms
Zitat:
Siehe Quelltext für Anwendung:
Delphi-Quellcode:
So wird erst dein Chatfenster erstellt, wenn dein Login ein mrOk liefert, falls es das nicht tut und wird beendet, schließt sich die komplette Anwendung.
begin
Application.Initialize; Application.MainFormOnTaskBar:= true; frm_Login:= Tfrm_Login.Create(nil); try if frm_Login.ShowModal = mrOk then Application.CreateForm(Tfrm_Start, frm_Start); finally frm_Login.Free; end; Application.Run; end. |
AW: Buttonabhängiges Schließen des Programms
hm, werds gleich nochmal googlen, aber könntest du an meinem Quelltext nochmal die Änderungen, die ich vornehmen muss mit Kommentaren posten?
Hier mein Quelltext:
Delphi-Quellcode:
program Client;
uses Forms, Unit1 in 'Unit1.pas' {Form4}, Unit2 in 'Unit2.pas' {Form2}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.CreateForm(TForm2, Form2); Application.Run; end. |
AW: Buttonabhängiges Schließen des Programms
Welches ist denn das LoginForm?
|
AW: Buttonabhängiges Schließen des Programms
Form1 --> Hauptform
Form2 --> Loginform Beide Forms werden (eigentlich) bei Programmstart erstellt. Ich hatte mir zu Hause auch Gedanken gemacht. Das ist rausgekommen:
Delphi-Quellcode:
Der restliche Quelltext funzt auch nicht. Da wird das Loginfenster halbwegs erzeugt, dann kommt aber eine Fehlermeldung, dass aus einem sichtbaren Fenster kein modales gemacht werden kann.
program Client;
uses Forms, Unit1 in 'Unit1.pas' {Form4}, Unit2 in 'Unit2.pas' {Form2}; {$R *.res} begin Application.Initialize; //Application.MainFormOnTaskBar:=True; --> failure: Application kennt diesen Bezeichner nicht Form2:=TForm2.Create(nil); try if Form2.ShowModal = mrOk then Application.CreateForm(TForm1,Form1); finally Form1.Free; end; Application.Run; end. |
AW: Buttonabhängiges Schließen des Programms
Ungetestet:
Delphi-Quellcode:
program Client;
uses Forms, Unit1 in 'Unit1.pas' {Form4}, Unit2 in 'Unit2.pas' {Form2}; {$R *.res} begin Application.Initialize; Form2:=TForm2.Create(nil); try Form2.Visible := false; if Form2.ShowModal = mrOk then Application.CreateForm(TForm1,Form1); finally Form2.Free; //Form2, nicht Form1 end; Application.Run; end. |
AW: Buttonabhängiges Schließen des Programms
tja, das funktioniert schonmal fast super.
Ich hatte versehentlich eingegeben
Delphi-Quellcode:
... und was soll ich sagen, dass funktioniert. Wenn ich da angebe
if Form2.ShowModal <> 0 then
Delphi-Quellcode:
erzählt er mir, dass 'mrOk' ein 'undefinierter Bezeichner' ist.
if Form2.ShowModal = mrOk then
Und dann hab ich noch eine Verständnisfrage. Du erzeugst Form2. Machst es dann aber unsichtbar, man kann es aber trotzdem sehen? Ist mir im Moment noch ein Rätsel... :glaskugel: |
AW: Buttonabhängiges Schließen des Programms
Ein kurzer Blick in die Referenz:
Zitat:
|
AW: Buttonabhängiges Schließen des Programms
Danke! Funktioniert jetzt.
Wenn ich das jetzt als Login-Fenster nehmen will, dann hab ich mir das so gedacht, dass man eben seinen Benutzernamen und Passwort eingibt. Diese werden als 'Nachricht' an den Server geschickt, der überprüft, ob die Zugangsdaten korrekt sind und schickt eine Nachricht zurück, die dann das Schließen des Fensters regelt. Wenn alles korrekt war, dann eben das, was man mir hier freundlicherweise gezeigt hat. Wenn die Daten aber nicht stimmen, dann soll das Fenster geöffnet bleiben, möglicherweise auch eine Fehlermeldung kommen. ABER: Wie realisier ich das jetzt? lg, hans ditter |
AW: Buttonabhängiges Schließen des Programms
Das dürfte mit dem jetzigen Lösungsweg schwierig bzw. sehr umständlich werden. Nur so als Gedankengang:
-die Client-/Server-Funktionalität in eine eigene Unit (z.B. ein Datenmodul) auslagern -das LoginForm zum Hauptformular machen -nach erfolgreichem Login verstecken, Form1 erzeugen und anzeigen -um die Anwendung zu beenden, dann eben das versteckte MainForm (also Form2) schließen |
AW: Buttonabhängiges Schließen des Programms
Warum nicht im Constructor des Mainforms den Logindialog öffnen , wenn hier nicht erfolgreich abgearbeitet wird , Meldung anzeigen und ein Terminateflag setzen welches die Anwendung beendet.
|
AW: Buttonabhängiges Schließen des Programms
@ Bummi ... äääääh, weil ich das nicht kann?!:cry:
@ daddyH Ja, ok... ich versteh nicht ganz was du meinst mit Zitat:
|
AW: Buttonabhängiges Schließen des Programms
Ich vermute, dass Du die Socket- (oder Indy, oder welche auch immer) Komponenten auf Form1 hast. Diese kannst Du in ein TDataModule packen und dann von beiden Units darauf zugreifen.
|
AW: Buttonabhängiges Schließen des Programms
Sorry hatte etwas wenig Zeit gehabt, aber DeddyH hat es dir ja erklärt gehabt.
Ich zeig dir mal wie ich mein Login Form benutze:
Delphi-Quellcode:
Exception Behandlung habe ich mal weg gelassen.
Try
QueryLogin.SQL.Text:='Select * from `Table` WHERE username LIKE EINGABE;'; QueryLogin.Open; if QueryLogin.FieldByName('pw').AsString = md5string(EditPasswort.Text) then // PW ist in MD5 gespeichert ModalResult:= mrOk Else Showmessage('Benutzername und Passwort stimmen nicht überein.'); Finally QueryLogin.Close; // Schließe Query zum schluss QueryLogin.Free; End; |
AW: Buttonabhängiges Schließen des Programms
Liste der Anhänge anzeigen (Anzahl: 1)
Aaaaaaaarggggghhhhhhhhhhhh!!!!!!!!!!!!!!!!!!!!:evi l::evil::x:x:x:x:x:x:wall::wall::wall::wall::wall: :wall::wall::wall::kotz: :kotz: :kotz: :kotz: :kotz: :kotz: :kotz:
Jetzt hab ich gerade versucht umzusetzen, was DeddyH gesagt hat... und rausgekommen ist nur, dass mein Chat jetzt wieder Macken hat!!! :kotz::wall: Das mit dem Datenmodul hat leider gar nicht geklappt. Das hab ich jetzt auch mal eben schnell wieder gelöscht, aber jetzt funktionieren auch andere Sachen wieder nicht mehr. Wenn mein Server jetzt nicht online ist, dann bekomme ich so ein **** PopUp-Fenster, dass mir sagt, das ein "Asynchroner Socket Fehler 10061" vorliegt. Mir ist klar, dass das der Fehler ist, wenn der Client den Server nicht erreichen kann, aber ich will dieses blöde Fenster nicht :wall:! Dabei gibt es eigentlich eine Routine, die das verhindern soll. Und jetzt stell ich gerade fest, dass das Programm gar nicht mehr kompiliert werden kann!! :wall::wall::wall::wall::wall::wall::wall::wall::w all::wall::wall::wall::wall::wall::wall::wall: :wall::wall::kotz::kotz::kotz::kotz::kotz::kotz::k otz::kotz::kotz::kotz::kotz::kotz::kotz::kotz: :kotz::kotz: Entschuldigt bitte meinen emotionalen Ausbruch, aber manchmal geht mir das tierisch auf den ****! Hoffe ihr könnt mir nochmal helfen. Ich hab den kompletten Quelltext nochmal angehängt. LG, hans ditter |
AW: Buttonabhängiges Schließen des Programms
Dann behandele die Exception halt.
|
AW: Buttonabhängiges Schließen des Programms
Und benutze ein VersionsSystem Ala SVN (so was geht auch ohne Server), dann könntest du jetzt einfach wieder zurückstellen
|
AW: Buttonabhängiges Schließen des Programms
@ Lucki: Das ist ja das Merkwürdige. Es gibt ja eine Fehlerbehandlung. Bei OnClientError (oder so ähnlich heisst das ja) wird ja auf jeden Fehler reagiert und der Fehlercode auf '0' gestellt, damit kein Fenster aufpoppt.
Aber irgendwie funktioniert das nicht mehr. @ DeddyH: Vielleicht könntest du nochmal für Deppen erklären, wie das funktionieren soll. (Wie du diese Unit machst / wie du auf die Komponenten dann zugreifst) [OFFTOPIC] @SirRufo: Da du das ansprichtst. Könntest du da mal ein paar Links posten, oder Stichwörter nach denen ich suchen kann? [/OFFTOPIC] |
AW: Buttonabhängiges Schließen des Programms
Also, ich hab das Probelm mit den Fehlern wieder hinbekommen. Aus irgendeinem kühlen Grund, bestand die Zuweisung der Ereignisroutine zu dem ClientSocket nicht mehr. Konnte ich wieder durch Dplklicken im OI herstellen. Das funktioniert wieder! :) Tut mir nochmal Leid für meinen Wutanfall... :oops:
@DeddyH: Vielleicht könntest du trotzdem mal posten, wie genau man das jetzt macht, ohne das Programm neu zu schreiben. Vielen Dank! hans ditter |
AW: Buttonabhängiges Schließen des Programms
|
AW: Buttonabhängiges Schließen des Programms
Und zum Datenmodul: das kann ich auch nicht besser beschreiben als die Hilfe selbst:
![]() |
AW: Buttonabhängiges Schließen des Programms
Wow, cool! Das hat funktioniert! Danke für den Link! Sollte häufiger mal auf diese Seite schauen... :oops:
Mir ist aber aufgefallen, dass man immer
Code:
schreiben muss, um auf Komponenten zugreifen zu können. Geht das nicht einfacher? Das man irgendwie definieren kann, dass
Unit3.DataModule3.{...}
Delphi-Quellcode:
ist?
var Unit3.DataModule3: DataModule;
Das wär noch ganz nett, aber erstmal vielen Dank dafür soweit! hans ditter |
AW: Buttonabhängiges Schließen des Programms
Es steht Dir doch frei, eine entsprechende Variable zu deklarieren und zu belegen.
|
AW: Buttonabhängiges Schließen des Programms
Ja, das dachte ich auch. Ich poste mal den Anfang vom Quellcode...
Delphi-Quellcode:
Während der Entwicklungszeit geht das auch alles ohne Fehler. Der Fehler tritt aber auf, wenn
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, StdCtrls, ComCtrls, StrUtils, superobject, ExtCtrls; const MY_PORT = 30000; // an diesem Port wartet der Server auf Clients type TForm1 = class(TForm) ServerAdress: TEdit; Online: TCheckBox; Input: TEdit; BtnSend: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; log: TRichEdit; lstUsers: TListBox; edtOwnUserNick: TEdit; Shape1: TShape; Shape2: TShape; Shape3: TShape; combContentSize: TComboBox; combContentColor: TComboBox; combContentStyle: TComboBox; ClientSocket: TClientSocket; procedure FormCreate(Sender: TObject); procedure OnlineClick(Sender: TObject); procedure BtnSendClick(Sender: TObject); procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); procedure FormDestroy(Sender: TObject); procedure InputKeyPress(Sender: TObject; var Key: Char); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation uses Unit3; var DataModule: Unit3.TDataModule3;
Delphi-Quellcode:
aufgerufen wird.
DataModule.ClientSocket.Port:=MY_PORT;
Dann sagt er, dass eine EAccessViolation aufgetreten ist. Wie hab ich das dann denn zu verstehen? lg, hans ditter |
AW: Buttonabhängiges Schließen des Programms
Ok, Problem hat sich gerade erledigt. Es reicht wenn ich DataModule3.{...} schreibe. Das reicht mir, ist kurz genug... ;)
Zur Funktion hab ich noch eine Frage. Ich möchte ja ein Anmeldefenster anzeigen lassen, in dem man Nick und Passwort eingibt. Wenn diese vom Server authentifiziert werden, dann soll ja die Form1 aufgerufen werden. Vom Prinzip kein Problem, aber wenn der Client sich mit dem Server connected hat, wird (im Moment noch) im Verlaufsfenster (des noch nicht erzeugten Form1) einige Informationen angezeigt. Da kommte natürlich eine Fehlermeldung, dass ein AccessFehler aufgetreten ist. Doch wie umgehe ich das? Ich dachte schon einen zweiten Clienten dynamisch erzeugen, der nur dafür da ist, die Authentifizierung vorzunehmen, find ich persöhnlich aber nicht so schick. Habt ihr noch andere Ideen? (Habt ihr überhaupt mein Problem verstanden, manchmal umschreibe ich das wirklich etwas wirr... :roll: :mrgreen: |
AW: Buttonabhängiges Schließen des Programms
Entweder Form1 vorher erzeugen oder die Daten zwischenspeichern (beispielsweise in einer eigenen Klasse oder einem Record) und in Form1 dann wieder auslesen.
|
AW: Buttonabhängiges Schließen des Programms
Das Problem liegt tiefer im Fehlen von Grundlagen.
Ein AccessFehler kommt immer dann, wenn man auf eine Struktur (Klasse) zugreifen möchte, wo es aber keine gültige Instanz gibt.
Delphi-Quellcode:
Mit einem Beispiel aus dem Leben gegriffen, könnte man es so erklären:
type
TFoo = class Data : string; end; var foo : TFoo; begin foo.Data := 'Hallo'; // <- AccessFehler foo := TFoo.Create; foo.Data := 'Hallo'; // Alles ok foo.Free; foo.Data := 'Hallo'; // <- AccessFehler foo := TFoo.Create; foo.Data := 'Hallo'; // Alles ok foo := nil; // <- Upps, ein Speicherleck erzeugt foo.Data := 'Hallo'; // <- AccessFehler end; Zitat:
|
AW: Buttonabhängiges Schließen des Programms
Wieso, die Ursache hat er doch schon selbst erkannt.
Zitat:
|
AW: Buttonabhängiges Schließen des Programms
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
und wundert sich, warum er einen AccessFehler bekommt.
DataModule: Unit3.TDataModule3;
Gelöst hat er das dann so Zitat:
|
AW: Buttonabhängiges Schließen des Programms
Mir scheint eher, dass er damit Probleme hat, zu wissen, was wann vorhanden ist.
|
AW: Buttonabhängiges Schließen des Programms
Zitat:
|
AW: Buttonabhängiges Schließen des Programms
Naja, habt ihr beiden wohl nicht so unrecht. Ich weiß nicht, wie ihr programmieren gelernt habt und wann, aber ich bring mir das (hauptsächlich) selbst bei, aus Büchern, viel Internet und eben diesem Forum. Die Informatik AG (10. Klasse) konnte ich auch leider nicht komplett machen, da bin ich auch erst später eingestiegen. Und da bei mir keiner ist, der Ahnung davon hat und mir Tipps gibt, womit ich anfangen sollte und wie ich weiter machen sollte, mache ich irgendwie und das was mir gerade in den Sinn kommt... dabei überspring ich dann wohl manches (wichtige)... :roll:
Ich werd mich nochmal ransetzten und über das letzte Problem nachgrübeln... wenn ich mal wieder Zeit hab... :roll: ****** Schule... ;) Auf jeden Fall vielen Dank für eure Hilfe, ich werd mich in diesem Thread auf jeden Fall nochmal rühren, wenn ich einen Ansatz gefunden hab. Ach ja, und vielen Dank, dass ihr mir klar gemacht habt, wo mein (vielleicht) größtes Problem liegt. Ich werd mal versuchen das aus der Welt zu schaffen! LG, hans ditter |
AW: Buttonabhängiges Schließen des Programms
Gern geschehen :) Das sollte übrigens keine Kritik an Deiner Person sein, nicht dass Du Dich jetzt auf den Schlips getreten fühlst.
|
AW: Buttonabhängiges Schließen des Programms
Nein, hab ich auch nicht so verstanden!!:!:
Das ist sogar gut, dann kann ich dagegen was unternehmen (hoffe ich zumindest ;)). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 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