![]() |
Form2 soll auf das ClientSocket von Form1 zugreifen
Tag.
Ich mache gerade ein Programm mit mehreren Forms. In Form1 habe ich ein ClientSocket. Nun muss aber Form2 auch darauf zugreifen können, um etwas ins Internet zu senden. Ich habe eine extra Funktion geschrieben, welche ich in der Klassendefinition von Form1 in den public Bereich gemacht habe. Ich kann aber leider nicht darauf zugreifen, weil ich ja zu erst die Unit von Form1 inkludieren muss. Das geht aber nicht, da Form1 die Form2 schon inkludiert und es so zu einem Fehler kommt. :( Die Form1 muss die Form2 inkludieren, da sie die Form per Button anzeigt. Meine Frage: Gibt es irgendeinen Weg, dass ich von Form2 auf das ClientSocket der Form1 zugreifen kann? Bitte um Hilfe!! Danke im Vorraus! MfG: sk0r |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Guten Morgen.
Forms sind in erster Linie Bausteine der Benutzeroberfläche. Sobald du eine Überkreuznutzung entdeckst, gibt es ein einfaches Hilfsmittel: Verlagere die nicht-visuelle Komponente in eine eigene Unit, die du dann in die Uses-Klauseln der betroffenen Forms aufnimmst. Sollte dieser Ansatz einmal nicht möglich sein, dann gibt es die hier vereinfachte Regel, die dennoch helfen kann: Überkreuznutzung ist möglich, wenn die Units nicht beide in der Uses-Klausel des interface Abschnitts aufgeführt werden. Siehe dazu OH - Uses-Klausel - Zirkuläre Referenzen. Grüße vom marabu |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
da form2 nach form1 erstellt wird fände ich es am sinnvollsten das du TForm2 von TForm1 aus kreierst und der TForm2-Instanz den Clientsocket übergibst. Alles andere (zum Beispiel TForm2 greift auf die Instanz Form1 zu) ist keine sauber Objektorientierung weil auf bestimmte Instanzvariablen zu gegriffen wird und ein mehrfach erzeugen der Forms dann nicht fehlerfrei funktioniert.
Delphi-Quellcode:
TForm2 = class(TForm)
[...] private fSocket: TClientSocket; public property Clientsocket: TClientSocket read fSocket write fSocket;
Delphi-Quellcode:
TForm1 = class(TForm)
private fForm2: TForm2; [...] procedure TForm1.FormCreate(Sender: TObject); begin fForm2 := TForm2.Create(Self); fForm2.ClientSocket := Self.fClientSocket; end; procedure TForm1.FormDestroy(Sender: TObject); begin fForm2.Free; end; |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Hallo, danke erstmal für die Hilfe.
Ich will es dann jetzt erstmal so machen, dass ich das CLientSocket in einer eigenen Unit habe. Leider kommt da schon der Fehler, denn wenn ich auf Werte zugreifen will, bekomme ich eine AV. Zitat:
Delphi-Quellcode:
Vielleicht keine schöne Lösung, aber wenn es klappt, reicht es erstmal. Wisst ihr was ich falsch gemacht habe?
unit dClientSock;
interface uses ScktComp, Windows, Sysutils; type TCLSocket = class tClientSck: TClientSocket; procedure ConnectClient(lpHost: String; iPort: Integer); procedure Send(lpTextMsg: String); function ReturnValue:String; procedure SetValue(lpNewValue: String); function ReturnConnect:Boolean; procedure tClientSckConnecting(Sender: TObject; Socket: TCustomWinSocket); procedure tClientSckConnect(Sender: TObject; Socket: TCustomWinSocket); procedure tClientSckDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure tClientSckRead(Sender: TObject; Socket: TCustomWinSocket); private { Privat } public { Publik } end; implementation var gCurrentVal: String; bIsConnected: Boolean; gCurrentHost: String; function TCLSocket.ReturnValue:String; begin result := gCurrentVal; end; procedure TCLSocket.SetValue(lpNewValue: String); begin gCurrentVal := ''; end; function TCLSocket.ReturnConnect:Boolean; begin result := bIsConnected; end; procedure TCLSocket.tClientSckConnecting(Sender: TObject; Socket: TCustomWinSocket); begin bIsConnected := false; gCurrentVal := 'Connecting to ' + gCurrentHost; end; procedure TCLSocket.tClientSckConnect(Sender: TObject; Socket: TCustomWinSocket); begin bIsConnected := true; gCurrentVal := 'Connected to ' + gCurrentHost; end; procedure TCLSocket.tClientSckDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin bIsConnected := false; gCurrentVal := 'Connection lost from ' + gCurrentHost; end; procedure TCLSocket.tClientSckRead(Sender: TObject; Socket: TCustomWinSocket); var gServerText: String; begin gServerText := Socket.ReceiveText; end; procedure TCLSocket.ConnectClient(lpHost: String; iPort: Integer); begin gCurrentHost := lpHost; tClientSck.Port := iPort; //Access Violation //tClientSck.Host := lpHost; //tClientSck.Active := true; end; procedure TCLSocket.Send(lpTextMsg: String); begin tClientSck.Socket.SendText(lpTextMsg); end; end. Danke schon mal! |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Du kapselst eine Komponente TClientSocket, statt davon abzuleiten. Okay, aber du musst die gekapselte Komponente auch instanzieren.
Freundliche Grüße |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Ok, es scheint nun zu funktionieren, indem ich es einfach instanziiere. Danke für eure Hilfe.
|
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Hallo, ich brauche doch noch mal eure Hilfe.!!
Ich habe es so versucht wie SirThornberry gesagt hat. In der Form1 verbinde ich mich mit dem Server. Wenn ich aber dann in Form2 oder Form3 etwas senden will bekommen ich einen AV: Zitat:
|
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Die Adresse verrät das du entweder wieder etwas nicht instanziert hast oder du bei fForm2 den Socket gar nicht zugewiesen
|
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Naja, eigentlich habe ich das (habe auf der Form1 nicht selbst Instanziiert, sondern von der Komponentenleiste
auf die Form1 plaziert)..
Delphi-Quellcode:
//Form1
uses [...], clMessages, [...]; //clMessages ist die .pas Datei von der Form2. type TForm1 = class(TForm) ClientSock: TClientSocket; procedure FormDestroy(Sender: TObject); procedure ClientSockConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSockConnecting(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSockDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSockRead(Sender: TObject; Socket: TCustomWinSocket); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; fForm2: TForm2; fForm3: TForm3; fForm4: TForm4; fForm5: TForm5; fForm6: TForm6; fForm7: TForm7; fForm8: TForm8; fForm9: TForm9; fForm10: TForm10; fForm11: TForm11; procedure TForm1.FormCreate(Sender: TObject); begin Form2.Show; fForm2 := TForm2.Create(Self); fForm2.Clientsocket := Self.ClientSock; fForm3 := TForm3.Create(Self); fForm3.Clientsocket := Self.ClientSock; fForm4 := TForm4.Create(Self); fForm4.Clientsocket := Self.ClientSock; fForm5 := TForm5.Create(Self); fForm5.Clientsocket := Self.ClientSock; fForm6 := TForm6.Create(Self); fForm6.Clientsocket := Self.ClientSock; fForm7 := TForm7.Create(Self); fForm7.Clientsocket := Self.ClientSock; fForm8 := TForm8.Create(Self); fForm8.Clientsocket := Self.ClientSock; fForm9 := TForm9.Create(Self); fForm9.Clientsocket := Self.ClientSock; fForm10 := TForm10.Create(Self); fForm10.Clientsocket := Self.ClientSock; fForm11 := TForm11.Create(Self); fForm11.Clientsocket := Self.ClientSock; ClientSock.Port := 7000; ClientSock.Host := gHostAddr; currentHost := gHostAddr; ClientSock.Active := true; end; //Form2 type TForm2 = class(TForm) procedure cmdSendClick(Sender: TObject); procedure cmdCloseClick(Sender: TObject); private fSocket: TClientSocket; { Private-Deklarationen } public property Clientsocket: TClientSocket read fSocket write fSocket; { Public-Deklarationen } end; procedure TForm2.FormCreate(Sender: TObject); begin fSocket.Socket.SendText('Hallo Server'); end; |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Naja, das Problem ist, wo muss ich sie denn instanziieren? In der Form2 selber doch nicht, oder?
Delphi-Quellcode:
So funktioniert es leider nicht.
fForm2 := TForm2.Create(Self);
fForm2.Clientsocket := TSocket.Create(Form1); fForm2.Clientsocket := Self.ClientSock; |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
weißt du überhaupt was du machst :shock: Du instanzierst zur Zeit einen Socket und weißt dann einen anderen zu. Somit ist die erste Instanz im Nirvana und du kannst nicht mehr drauf zugreifen. Es ist nicht böse gemeint aber du solltest dir erstmal die Grundlagen zur Objectorientierten Programmierung anschauen
|
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Hallo,
ich habe den Eindruck, dass du die in diesem Thread gemachten Lösungsvorschläge gar nicht bewerten kannst. Es besteht jetzt die Gefahr, dass wir dir ein Detailproblem lösen und dich damit auf einem Holzweg begleiten. Wenn du eine Komponente aus der Palette auf eine Form (Form1) ziehst, dann werden ihre wesentlichen Eigenschaften in der DFM-Datei (letzten Endes ein resource file) gespeichert und beim Erzeugen der Form wird die Komponente zusammen mit dieser instanziert. Die Form ist dabei der Eigentümer dieser Komponente und der Lebenszyklus der Komponente ist an den Lebenszyklus der Form gebunden. Wird die Form zerstört, dann wird auch die Komponente zerstört. Übergibst du eine solche Komponente an eine andere Form (Form2), so wird dort eine Referenz gespeichert. Eigentümer bleibt die andere Form (Form1) und es ergeben sich Zugriffsprobleme, wenn Form1 zerstört wird, denn dann wird auch die Komponente zerstört und die Referenz in Form2 wird ungültig. Es ist deine Aufgabe dann dafür zu sorgen, dass die Referenz auf nil gesetzt wird. Solange du also den Vorschlag von Jens aus Beitrag #3 umsetzt, hast du in Form2 eine Referenz und kein eigenständiges Objekt. Also musst du dort auch keine Instanzierung durchführen, das geschieht ja schon in Form1 - wie oben erläutert. Dein Fehler hat eine andere Ursache. Deiner Klasse in Beitrag #4 fehlt übrigens ein Konstruktor, der die Objektvariable vom Typ TClientSocket instanziert - und eine entsprechender Destruktor, der sie wieder zerstört. Gute Nacht. |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Ich habe es auch ohne von der komponenteleiste zu ziehen versucht. klappt auch nicht.
ich weiß jetzt gar net ob mein code richtig ist oder net. naja jedenfalls wüsste ich halt gerne wie ich an die ursache komme. tutorials dazu gibts afaik auch nicht hab auf dsdt schon gesucht aber da gibts nur einzelne bröckelige sachen. |
Re: Form2 soll auf das ClientSocket von Form1 zugreifen
Hallo,
du solltest dein Projekt etwas zurückfahren, damit es klein und überschaubar wird. Es nützt nichts, dass du bereits ein Dutzend Forms entworfen und eingebunden hast, wenn die Basisfunktionalität noch nicht implementiert und ausgetestet ist. Ein kleines Projekt, befreit von unnützem Ballast und hier eingestellt, am Besten mit einer groben Beschreibung der Projektidee - du wirst sehen, dann bekommst du auch zielführende Lösungsvorschläge. Freundliche Grüße |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:15 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