Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Systemfehler. Code 1400. Ungültiges Fensterhandle. Und nu? (https://www.delphipraxis.net/45605-systemfehler-code-1400-ungueltiges-fensterhandle-und-nu.html)

Tyler 9. Mai 2005 11:29


Systemfehler. Code 1400. Ungültiges Fensterhandle. Und nu?
 
Salut :)

die o.g. Fehlermeldung der Klasse "EOSError"
Zitat:

Systemfehler. Code 1400. Ungültiges Fensterhandle. Und nu?
erhalte ich, wenn ich mein Programm schliesse.

Der Fehler tritt aber nur auf, wenn ich vorher im Programm folgendes "Feature" auslöse:
In einem Formular (MDIChild) wird folgende Proc aufgerufen:
Delphi-Quellcode:
procedure Tf_Vorgangsbuch.DOSUpdate1Click(Sender: TObject);
begin
{ Erstmal schauen, ob das Update ansich schon läuft (MySQL-Importer erstellt
die genannte Dummy-Datei, die nach Beendigung wieder entfernt wird - weiterhin
wird geprüft, ob nicht schon ein Update eines anderen Moduls läuft, und die TCPServer-Kompo
frei ist}
  if (NOT FileExists('y:\mysqlimporter\test\dummy_p_vorgangsbuch')) AND
     (NOT f_main.TcpServer.Active) then
  begin
    f_main.TcpServer.Active := True;

    ShellExecute(
      f_vorgangsbuch.handle,
      'open',
      PChar('psexec.exe'),
      PChar('\\testserver -i -w y:\mysqlimporter\test\ -d ' +
        ' y:\mysqlimporter\test\import.exe ' +
        ' J:\test\vorgbuch.dbf p_vorgangsbuch Ja ' +
        f_main.getIPs[0] ),
      PChar('y:\mysqlimporter\test\'),
      SW_SHOW);
  end else
    ShowMessage(' Update wird bereits ausgeführt! ');
end;
FYI: Auf dem Server existiert ein kleines Programm, welches DBF-Dateien ausliest und in eine MySQL-DB schreibt. Das Programm läuft einerseits per Taskmanager selbständig, um einige Datenbanken regelmäßig zu aktualisieren, anderersets, wenn es mit Parametern aufgerufen wird, kann es eine beliebige DBF-Datei auf meinen MySQL-Server schieben. Da das Programm aber auf den Clients sehr langsam läuft, wird es über PSEXEC "remote" auf dem Server ausgeführt.
Bisher ist das alles noch ganz einfach. Nun will man aber auch wissen, wie weit das Update ist. Zu dem Zweck hab ich mein Hauptprogramm und meinen MySQL-Importer mit den jeweiligen TCP-Komponenten ausgestattet, um miteinander zu kommunizieren:

Dazu läuft in der Hauptform meines "grossen" Progs folgendes ab:
Delphi-Quellcode:
procedure Tf_main.TcpServerAccept(Sender: TObject;
  ClientSocket: TCustomIpClient);
begin
  Progress.Visible := True;

  Progress.Max := StrToInt( ClientSocket.Receiveln );

  while ClientSocket.Receiveln <> 'EOF' do
  begin
    Progress.Position := StrToInt( ClientSocket.Receiveln )
  end;

  TcpServer.Active := False;
  Progress.Visible := False;

end;
FYI: Der MySQL-Importer schickt also an die IP des Hauptprogrammes zuerst die Anzahl der gesamten Datensätze und dann jeweils den aktuellen Stand der Dinge, um halt das ganze in einer Progressbar visuell dazustellen. Sieht man ja denke ich ganz einfach am Code... oder? :)
Der letzte String jedenfalls ist ein "EOF" damit das HAuptprogramm weiss: Hier ist SChluss. Fertig.

Nun, diese Skript läuft halt einmal durch, ohne Fehlermeldungen etc.pp. Und wenn ich dann das Programm schliesse, kommt eben die o.g. Fehlermeldung. Ich vermute mal, dass hier meine tolles "Update"-Feature irgendwo nicht ganz astrein ist, weil wenn ich das nicht ausgeführt habe, gibts die Fehlermeldung auch nicht!

Jemand ne Idee?


Danke!
Tyler :)

Kedariodakon 9. Mai 2005 11:59

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
hmm vielleicht vergisst du was freizugeben und es versucht sich selbst freizugeben, was aber fehlschlägt weil der Owner vielleicht schon lange zerstört ist?
Oder ka wie dieser Fehler zustande kommt ^^
Schon mal debuged?

Ich glaube das Problem liegt eher im Constructor / Destructor als in den zwei Funktionen ^^
den dort kann ich keine nennenswerten Fehler entdecken...

Aber!!!
Zitat:

Zitat von Active (Eigenschaft von TBaseSocket)
...Zur Entwurfszeit weisen Sie Active den Wert true zu, um den Socket beim Start der Anwendung für eine Verbindung zu öffnen (der Standardwert ist false). Zur Laufzeit verwenden Sie die Methoden Open und Close, um die Verbindung zu öffnen bzw. zu schließen.

bye

Tyler 9. Mai 2005 13:14

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
hm... also ich hab jetzt die Methode aus deinem Zitat verwendet, und den TCP Server mit "OPEN" aktiviert. Das führte zu keiner Lösung. Dafür aber das auskommentieren genau dieser Zeile in der Prozedur meiner MDI_Child-Formulars.

Scheint also daran zu liegen, das der Aufruf zwar vom Child aufgerufen, aber im Hauptformular wieder beendet wird, was dem TCPServer wohl missfählt.

Bleibt mir wohl nichts anderes übrig, als in jedem MDI-Child eine eigene TCPServer Komponente einzubauen, eine andere Möglichkeit sehe ich leider nicht, ohne z.B. mit einem Timer permanent irgendwelche Flags abzufragen... :(



tyler

//EDIT

doch... die Proc wird einfach in die Hauptunit ausgelagert, und die MDIChilds greifen per Verweis drauf zu... das müsste funktionieren.

Kedariodakon 9. Mai 2005 13:27

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
Zitat:

Zitat von Tyler
...
Scheint also daran zu liegen, das der Aufruf zwar vom Child aufgerufen, aber im Hauptformular wieder beendet wird, was dem TCPServer wohl missfählt.
...

hmm gut möglich vor allem wenns beendet wurde obwohl das Child noch was machen möchte mit ^^

Zitat:

Zitat von Tyler
...
doch... die Proc wird einfach in die Hauptunit ausgelagert, und die MDIChilds greifen per Verweis drauf zu... das müsste funktionieren.
...

Ist sogar eleganter, meiner Meinung nach :mrgreen:



Konntest du den die Fehlerstelle genau finden?



Bye

Tyler 9. Mai 2005 13:33

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
hm... leider war das auch nicht die optimale Lösung.

Die Fehlerstelle war btw. das "TCPServer.Close" in der Prozedure "OnAccept" siehe oben.

Jetzt wird, wie erwähnt, aus meinem MDIChild eine Action in der Hauptunit ausgelöst. Diese Action wiederum macht das, was vorher das MDIChild gemacht hat, es öffnet seinerseits den TCPServer.
Es kommt weiterhin zu der Fehlermeldung, offensichtlich deshalb, weil der TCPServer in 2 unterschiedlichen Proceduren geschlossen und geöffnet wird.... Dumme Falle.. Zwickmühle??
Also werd ich wohl doch einen Timer einbauen, der von ausserhalb wieder für ein Schliessen des TCP Servers sorgt... :(


tyler

Kedariodakon 9. Mai 2005 14:14

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
Zitat:

Zitat von Tyler
...
weil der TCPServer in 2 unterschiedlichen Proceduren geschlossen und geöffnet wird.
...

Das is doch weniger wild, eigendlich zumindest!

Schau doch einfach ob er connected ist, dann brauch er nicht mehr geöffnet werden, und beim schließen schau nach ob er schon geschlossen ist...

Dabei beachte aber, das der nicht geschlossen werden darf wenn er mit irgendwas noch nicht fertig ist, sprich setze nen Flag irgendwo ob er geschlossen werden darf...

Bye

Tyler 9. Mai 2005 14:56

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
Ich hab jetzt nochmal geschaut, und hier noch einmal zur Übersicht _alle_ Procs die mit TCPServer auch nur indirekt zu tun haben:

Im MDICHild wird die Action der Hauptunit aufgerufen:

Delphi-Quellcode:
  f_main.ac_UpdateExecute(Self);
Das wars von der Seite, jetzt die Action in der Hauptunit, die hier den TCPServer aktiviert, der eben auch in der Hautpunit liegt:

Delphi-Quellcode:
procedure Tf_main.ac_UpdateExecute(Sender: TObject);
begin
  if (NOT FileExists('y:\mysqlimporter\test\dummy_p_vorgangsbuch')) AND
     (NOT f_main.TcpServer.Active) then
  begin
    TcpServer.Open;

    ShellExecute(
      f_vorgangsbuch.handle,
      'open',
      PChar('psexec.exe'),
      PChar('\\testserver -i -w y:\mysqlimporter\test\ -d ' +
        ' y:\mysqlimporter\test\import.exe ' +
        ' J:\test\test\vorgbuch.dbf p_vorgangsbuch Ja ' +
        f_main.getIPs[0] ),
      PChar('y:\mysqlimporter\test\'),
      SW_SHOW);
  end else
    ShowMessage(' Update wird bereits ausgeführt! ');
end;
und das Ereignis "ONACCEPT" des TCPServer, in dem sich seit dem letzten siehe oben nichts geändert hat.

Heisst also im Klartext, in der Action wird der TCPServer aktiviert, und im TCPServer wird er wieder deaktiviert. Sonst gibts definitiv keine anderen Zugriffe von irgendwoher. Die Frage ist, warum das nicht so sein darf?

Ich hab jetzt wie gesagt mal folgendes probiert:
Delphi-Quellcode:
procedure Tf_main.ac_UpdateExecute(Sender: TObject);
begin
  if (NOT FileExists('y:\mysqlimporter\test\dummy_p_vorgangsbuch')) AND
     (NOT f_main.TcpServer.Active) then
  begin
    TcpServer.Open;

  (...)


  TCPServer.Close;

end;
was meine Theorie nur bekräftigt, dass schlicht und ergreifend nur aus einer und derselben prozedure der Server gesteuert werden darf.
DAs ist natürlich doof, denn wie soll ich nun meine Progressbar realisieren, die ja quasi übers Netzwerk "gesteuert" wird? :(


tyler

Tyler 9. Mai 2005 15:22

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
ich werd verrückt... das Ding [Anm.d.Verf.: TCPServer] steckt voller Überraschungen. Nun hab ich versucht ein wenig rum zu tricksen:
Folgendes steht jetzt in meiner Action:
Delphi-Quellcode:
  if (NOT FileExists('y:\mysqlimporter\pegel\dummy_p_vorgangsbuch')) AND
     (NOT f_main.TcpServer.Active) AND
     (NOT UpdateAktiv) then
  begin
    ...
    UpdateAktiv := True;

  end else begin
    ...
    TCPServer.Close;
    UpdateAktiv := False;
  end;
Heisst im Klartext, ich wollte einmal in der die Aktion auslösen, die den TCP Server zum Kommunizieren bringt. Im Event des TCP-Servers wiederum wird nun am Ende (nach der Schleife, siehe oben) wiederum die Action aufgerufen. (Zirkelverweis... eigentlich total unschön ^^)

Nun gibts die lustige Meldung:
"EInvalidOperation: Leinwand/Bild erlaubt kein Zeichen"

LoL? Welche Leinwand? Bild? Läuft im Hintergrund Photoshop? Nö, nicht wirklich... Hilfe :wacko:

Tyler 11. Mai 2005 10:08

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
*heul*

ich bin der Verzweiflung nahe.

Nun bin ich auf idTCPClient und Server von Indy umgestiegen, weil ja das Gerücht umgeht, die seien zuverlässiger. Hab mir auch mit Mühe und Not meine Proceduren zusammengebastelt, und bekomme nun 1. folgende Fehlermeldung:

"zeiüberschreitung beim beenden von thread"

wenn ich den idTCPServer in dessen Prozedure "TCPServerExecute" von Hand schliesse. Nehme ich das jedoch raus, erhalte ich, wie gehabt, die Fehlermeldung aus dem ThreadTitel. Hilfe! ICh weiss nicht mehr weiter - woran liegt das? Was mach ich falsch? :(


tyler

Tyler 20. Mai 2005 07:13

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
keiner ne Idee? Ich find sonst keinen Ausweg, ausser mit der Fehlermeldung zu leben *bibber*

shmia 20. Mai 2005 08:32

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
Zitat:

Zitat von Tyler
keiner ne Idee? Ich find sonst keinen Ausweg, ausser mit der Fehlermeldung zu leben *bibber*

Diesen Fehler habe ich z.B. schon mal gehabt, wenn am Rechner kein Standarddrucker installiert war.
(Dies kommt z.B. bei Laptops vor, die noch nie an einen Drucker angeschlossen waren.)

Du kannst den Fehler finden, wenn du in den Projektoptionen -> Debuggen -> Mit Debug DCU's aktivierst.
Dann muss noch das Häckchen in Tools -> Debugger-Optionen -> Sprach-Exceptions -> Bei Delphi-Exceptions stoppen aktiviert sein.

Wenn die Delphi IDE dann bei Auftreten des Fehlers stoppt, dann lässt du dir als erstes mal den Aufrufstack anzeigen.

marabu 20. Mai 2005 08:33

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
Hallo Tyler,

nach allem was ich in diesem thread lese, dreht sich dein Verdacht um die Art und Weise wie deine TCP-Server Komponente aktiviert und deaktiviert wird. Das kann nach meiner Einschätzung nicht die Fehlerursache sein. Als erstes solltest du in einem Minimal-Programm sicher stellen, dass du die TCP-Komponente richtig verwendest. Am besten auch den Code des Gegenstücks in einem Testprogramm isolieren. Das dürften zwei sehr kleine Programme werden. Wenn da etwas nicht klappt, stelle den Quelltext online und dann wird dir geholfen.

Was macht eigentlich deine Form f_Vorgangsbuch alles noch so - außer einen Buttonclick entgegennehmen? Warum übergibst du das Handle dieses Dialogfensters und nicht das Application Handle an ShellExecute()?

Grüße vom marabu

Tyler 23. Mai 2005 06:34

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
den Tip mit dem Aufruf-stack hab ich durch, wurde dadurch aber auch nicht schlauer, jedenfalls steht da nichts verdächtiges :)

Jetzt hab ich jedenfalls meine beiden Routinen in 2 kleine Programme gesteckt. Zu dem Fehler wie oben beschrieben kommt es jetzt zwar nicht, aber klappen tuts immer noch nicht.

Ist nicht viel Code, ich zeigs mal eben:

Client:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i : Integer;
begin
  ProgressBar1.Max := 9000;
  IdTCPClient1.Port := 5001;
  IdTCPClient1.Host := '127.0.0.1';
  IdTCPClient1.Connect;
  IdTCPClient1.WriteLn('1000');

  for i := 0 to 9000 do
  begin
    IdTCPClient1.WriteLn(IntToStr(i));
    ProgressBar1.Position := i;
  end;

 
end;
Server:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  IdTCPServer1.DefaultPort := 5001;
  IdTCPServer1.Active := True;
end;

procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
var
  s : String;
  i : Integer;
begin
  AThread.Connection.ReadLn(s);
  i := StrToInt(s);
  if i > ProgressBar1.Max then
    ProgressBar1.Max := i
  else
    ProgressBar1.Position := i;
end;
Das wars. Mehr nicht. Hier ersch eint zur Abwechslung die Fehlermeledung "Socketfehler 10053 - Die Software hat einen Abbruch der Verbindung verursacht." - das ungefähr bei einem Drittel.

Kruzifix, dabei will ich doch nur ein paar Zahlen übers TCProtokoll übertragen, kann doch nicht so schwer sein :(

Bitte um Hilfe :)


tyler

marabu 23. Mai 2005 07:55

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
Hallo Tyler,

beim Client setzt du ProgressBar.Max auf 9000, signalisierst dem Server 1000 und zählst 9001 vor. Im for-loop solltest du später die message pump mit Application.ProcessMessages am Laufen halten. Auf der Serverseite verwirfst du die empfangenen Daten einfach.

Probiere es mal so:
Delphi-Quellcode:
s := AThread.Connection.ReadLn();
Grüße vom marabu

Tyler 23. Mai 2005 09:39

Re: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und n
 
Mit der 1000 war nur n Tippfehler. ^^ :)

Gut, also das Application.ProcessMessage hab ich eingebaut, und den String "s" auch wie von dir empfohlen übergeben. Weiterhin wird beim Server die Procedure nicht mehr beim OnConnect ausgeeführt, sondern bei "OnExecute"

Nun klappts zwar erstmal ohne Fehlermeldung, nur, ganz komisch, zählt der Server erst die Progressbar hoch, dann werden anscheind die Daten gesendet, und der Client zählt danach die Progressbar hoch. Also ganz klar versetzt. :wacko:


tyler


//EDIT

ok, löppt. Ich muss den Send-Buffer nur ein bisser reduzieren, sonst sender der die "lines" in einem Schub. Ich versuch das jetzt mal eins zu eins in mein Hauptprogramm zu übernehmen...

DualCoreCpu 6. Okt 2019 09:51

AW: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und nu?
 
bei mir ist dieser Fehler heute um 10:20 unmittelbar nach Systemstart von Windows 10 aufgetreten als ich nach paar Mausbewegungen über meinen Bildschirm Delphi starten wollte. Der Start bricht mit ebendiesem Fehler ab. Fehlerbericht ist gespeichert. Habe nach Anweisung im Diagnosetool das Embarcadero Dashboard geöffnet, mich dort eingeloggt, weil ich den Fehlerbericht an Emba senden will. Wie mache ich das nun?

Nachdem ich meinen Browser gestartet habe, um diesen Beitrag hier zu posten, habe ich einen 2. Versuch unternommen, Delphi zu starten. Nun startet Delphi trotz Fehlermeldung, dass 2 Instanzen von Delphi gestartet wurden. Beide Instanzen sind nun aktiv, verhalten sich aber genau gleich. Das in der zuletzt gestarteten Instanz geöffnete Projekt ist auch in der anderen Instanz geladen. Also scheinen beide Instanzen dasselbe Fensterhandle zu benutzen

TurboMagic 7. Okt 2019 21:20

AW: Systemfehler. Code 1400. Ungültiges Fensterhandle. Und nu?
 
Ganz einfach: in quality.embarcadero.com com mit deinem EDN Login einloggen und dann gibt's oben einen großen roten "Vorgang erstellen" Button. Diesen ausfüllen. Nach dem du das Formular abgeschickt hast wird die URL des Bugreports oben kurz eingeblendet. Klicke darauf und dann findest du auf der dann erscheinenden Seite auch die Möglichkeit eine Datei anzuhängen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:39 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