AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TForm innerhalb eines TThread-Objektes

Ein Thema von sirius · begonnen am 15. Okt 2007 · letzter Beitrag vom 18. Okt 2007
Antwort Antwort
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#1

TForm innerhalb eines TThread-Objektes

  Alt 15. Okt 2007, 20:43
Vorwort:
Dies ist nur ein Testprogramm, in welchem man zur Laufzeit mehrere Threads erstellen kann. Diese Threads unterhalten sich dann mittels TCP/IP. Ich wollte das nur einmal ausprobieren. Das Problem befindet sich in keinem Projekt was jetzt irgendwie gelöst werden muss. Deswegen will ich das Problem auch nicht umgehen, sondern einfach nur wissen: Warum bzw. wo hängts?

Problem:
Damit die Threads sich nicht sinnlos unterhalten gibt es zu jedem Thread eine kleine Eingabemaske über ein Formular (ein paar Buttons, 2 Edits, 1 Label, 1 Memo und 1 Shape).
Das sieht dann in der ExecuteMethode so aus (Das Formular wird also direkt im Thread erstellt):
Delphi-Quellcode:
begin
  handle:=allocatehwnd(wndproc); //Windowhandle um Messages aus dem Socket und von der Clientform zu sammeln
  Clientform:=TClientform.Create(nil);
  Clientform.owner:=handle; //damit die clientform mir auch sagen kann, was sie grad macht
  Clientform.Caption:=clientform.Caption+' #'+inttostr(nummer);
  aktshape; //füllt das Shape auf dem Formular clientform mit rot
  Clientform.Show;
  ClientSocket:=0; //winsock.TSocket
  run; //beinhaltet ausschließlich die Messageschleife (getmessage + translatemessage + dispatchmessage) incl. der Abfrage nach terminated
  clientform.Close;
  clientform.Free;
  deallocatehwnd(handle);
end;
Die Clientform habe ich über die IDE und mit dem OI usw. usf. erstellt. Also ganz normal über "Neues Formular" und die Komponenten schön da drauf platziert.

Das Formular unterhält sich auch nur mit dem Thread. (Und unter den Projekt-Optionen wird es natürlich als nicht "automatsich erzeugen" eingestellt) Es hat also mit dem MainThread nix zu tun.

Auftrentender "Fehler":
Das Programm funktioniert hervorragend, also alles was ich testen wollte klappt. Aber: Die Komponenten auf dem Formular, die ich so schön platziert habe, sind alle ca. 1,5 mal so groß und wurden auch entsprechend verschoben. Also alle Größen (left,top,widht,height) sind etwa um den Faktor 1,5 größer. Da interessiert mich nur das Warum? Ich weis ja, dass VCL-Komponenten und Threads sich beißen. Aber dass die das so machen?
Es kommt kein Fehler und keine Exception. InternalReadComponentRes tut doch nur kurz in den Ressourcen lesen und baut dafür eigens einen Stream auf. Da dürfte doch nix passieren.

Vielleicht liegts auch an meinem Delphi. Hab die Formulare aber schonmal testweise komplett neu gemacht. Und wenn ich das Formular im MainThread initialisiere, sieht auch alles richtig aus.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von RavenIV
RavenIV

Registriert seit: 12. Jan 2005
Ort: Waldshut-Tiengen
2.875 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: TForm innerhalb eines TThread-Objektes

  Alt 16. Okt 2007, 09:07
Was macht denn deine Funktion aktshape?
Liegt die vielleicht im MainForm?
Dann weisst Du ja warum das sich "komisch" verhält.
Klaus E.
Linux - das längste Text-Adventure aller Zeiten...
Wer nie Linux mit dem vi konfiguriert hat, der hat am Leben vorbei geklickt.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: TForm innerhalb eines TThread-Objektes

  Alt 16. Okt 2007, 09:57
Danke Dir!
Aber: Nee, alles im Thread. Der Mainthread hat nahezu nix zu tun. Ist nur ein Formular mit 3 Buttons drauf (ServerThread starten, Clientthread starten und Programm beenden). Das torpediert zwar die Idee von Threads, aber es ist wie gesagt nur ein "Experiment". Einfach mal zum Testen und Rumspielen mit WinApi-Sockets. (Ist jetzt zum Testen von VCL-Forms innerhalb Threads mutiert )
Vielleicht kann ja jemand noch ein eindeutiges Statement abgeben wie "Forms in einem Thread gehen niemals", oder andersrum: "Mach ich doch immer so".

Ich hab mal nen Screenshot angehängt. (Ich kann auch das Programm anhängen.)

Ich habe noch gesehen, dass beim Einrichten der WndProc-Funktion auf globale Variablen zugegriffen wird (von MakeObjectInstance über TWinControls). Und dann dieses "Screen.add", dass sieht auch etwas globaler aus. Vielleicht hab ich bisher auch nur Glück gehabt, dass es nicht noch woanders geknallt hat?


Edit:
Delphi-Quellcode:
procedure TclientThread.aktshape;
begin
  if clientsocket=0 then clientform.Shape.Brush.Color:=clred
                    else clientform.Shape.Brush.Color:=clgreen;

end;
Edit2: Ich hba grad noch ein bisschen gespielt - noch zwei weitere kleine Sachen treten auf.
Manchmal ist das Fenster auch winzig klein. Man schließt es halt einfach und dann kommt der "normale Fehler" wie gehabt, also Fenster ist ein wenig zu groß. Und das Fesnter war auch schon mal richtig angezeigt wurden. Schließen und neu öffnen bringt den selben Fehler wieder.
Und dann habe ich noch ein array-Fehler (Listen-Index überschreitet Maximum) drinn. Aber der kann von mir sein.
Miniaturansicht angehängter Grafiken
psocket_143.jpg  
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: TForm innerhalb eines TThread-Objektes

  Alt 18. Okt 2007, 12:10
Ich habs mal in einer VM getestet. Die startet die Threads anscheinend nicht, oder zeigt die Formulare eben erst gar nicht an. Und der Debugger von Turbo Delphi ist in der VM sogar abgestürzt.

Wenn ich das ganze Konzept von hinten aufrolle, klappt alles erwartungsgemäß.
Also nicht wie bisher: Mainform startet Thread, Thread startet und verwaltet Threadform, sondern Mainform startet ThreadForm und ThreadForm startet Thread. Dadurch sind alle Formulare im Mainthread, so wie man es konzeptionell wahrscheinlich auch immer machen würde. Aber beim experimentieren probiert man auch mal anderes

==> Also ein VCL-Formular (wahrscheinlich alle TWinControls) kann nicht in einem Thread existieren (auch nicht, wenn es von außen komplett abgekapselt ist / zu sein scheint).
Begründung meinerseits fällt mir leider noch zu schwach aus. Aber es gibt globale Variablen auf die ein TWinControl ungesichert zugreift (was eher eine globale Liste aller TWincrontrol.WndProc ist).



(diser Post beinhaltet ein verstecktes *push* )
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz