Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi "Ungültiges Fensterhandle (Code 1400)" wegen indy ftp (https://www.delphipraxis.net/79676-ungueltiges-fensterhandle-code-1400-wegen-indy-ftp.html)

Nogge 26. Okt 2006 11:58


"Ungültiges Fensterhandle (Code 1400)" wegen indy
 
Hallo Community,
Ich erhalte die o.g. reproduzierbare Fehlermeldung, wenn ich meinen FTP-Server aus der TNA heraus wieder anzeigen lasse. ABER der Fehler tritt nur dann auf, wenn ich meinen FTP-Server sofort beim Programmstart minimiere (Autostart-Feature) und ein Client eine Verbindung zum FTP-Server aufgebaut hat.

Delphi-Quellcode:
[OnFormCreate]
begin
  if CB_Autostart.Checked then
  begin
    Application.ShowMainForm := false;
    AddTNAIcon('NoobFTP - Server');
    Open_FTP_Server;
  end;
end;

Procedure TF_Server.AddTNAIcon(const TNA_String: String);
begin
  with NIM do begin
    cbSize := SizeOf(NIM);                      
    Wnd   := self.Handle;                    
    uID   := 0;                                
    uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
    hIcon := Application.Icon.Handle;      
    uCallbackMessage := WM_TASKBAREVENT;        
    StrPCopy(szTip, TNA_String);
  end;
  Shell_NotifyIcon(NIM_ADD, @NIM);
end;

[Open_FTP_Server]
begin
  IdFTPServer1.Active := not IdFTPServer1.Active;
  if IdFTPServer1.Active then
  begin
    IdFTPServer1.MaxConnections := StrToIntDef(E_maxC.Text, 2);
    L_status.Caption := 'Status: opened';
    B_create.Caption := 'Close FTP Server';
  end;
end;

Procedure TF_Server.WMSysCommand(var Msg: TWMSysCommand);
Begin
  if (Msg.CmdType and $FFF0) = SC_MINIMIZE then
  begin
    self.Hide;
    //windows.ShowWindow(Application.Handle, SW_HIDE);
    //windows.ShowWindow(self.Handle, SW_HIDE);
    AddTNAIcon('NoobFTP - Server');
  end
  else
    inherited;
end;

Procedure TF_Server.WMTaskBarEvent(var Msg: TMessage);
Begin
  case Msg.LParamLo of
    WM_LBUTTONDBLCLK:
      begin
        self.Show;
        //windows.ShowWindow(self.Handle, SW_SHOW);
        //windows.ShowWindow(Application.Handle, SW_SHOW);
        Application.BringToFront;
        RemoveTNAIcon;
      end;
  End;
End;
Kann mir jemand erklären, wie diese Fehlermeldung zustande kommt?

mfg Nogge

Nogge 28. Okt 2006 09:11

Re: "Ungültiges Fensterhandle (Code 1400)" wegen i
 
Ich habe jetzt alles mögliche versucht, jedoch finde ich leider diesmal nicht selbst die Lösung :cry: Wenn ich meinen FTP-Server nicht sofort aktivieren lassen (=Autostart), so dass die Form erst mal angezeigt wird, kommt während der gesamten Laufzeit keine Fehlermeldung mehr. Indy muss irgendwie in die Fensterverwaltung eingreifen, wenn der FTP-Server aktiviert wird. Das hört sich für mich auch total absurd an, aber ich finde leider keinen Bug in meinem Programm.
Oder bewirkt
Delphi-Quellcode:
Application.ShowMainForm := false;
mehr, als es soll?

Nogge 28. Okt 2006 19:47

Re: "Ungültiges Fensterhandle (Code 1400)" wegen i
 
Göttliche Eingebung! :angel:
In habe schon vor geraumer Zeit gelesen, dass Indy v10 pro Client mehr als nur einen Thread zum Empfangen von Daten verwendet (ACHTUNG: Die damaligen IdPeerThreads gibt es nicht mehr!). So stammen die Events (Hinweis: Events sind asynchron, obgleich sie eine Procedure der Mainform sind!) OnUserLogin und OnConnect aus 2 verschiedenen Threads, obwohl beide zu demselben Client gehören. Diese können also unabhängig voneinander und vom MainThread selbst aufgerufen werden.
In jedem Thread wurde diese Procedure ausgeführt:
Delphi-Quellcode:
procedure TF_Server.Log(const s: string);
begin
  LB_Log.Items.Add(s);
  SendMessage(LB_Log.Handle, WM_VSCROLL, SB_LINEDOWN, 0);
end;
Bevor die MainForm nicht mind. einmal vor dem Benutzen dieser Procedure angezeigt wurde, verursachten die beiden Zeilen sofort oder erst beim Beenden des gesamten Programms die o.g. Fehlermeldung.
Nachdem ich die beiden Zeilen mithilfe einer eigenen Message nun wirklich im MainThread ausführen lassen, d.h. synchronisiere, funktioniert alles ohne Fehlermeldung.
Delphi-Quellcode:
procedure TF_Server.proc_WM_LOG(var Msg: TMessage);
var
  StrP: PString;
begin
  StrP := PString(Msg.WParam);
  try
    LB_Log.Items.Add(StrP^);
    SendMessage(LB_Log.Handle, WM_VSCROLL, SB_LINEDOWN, 0);
  finally
    Dispose(StrP);
  end;
end;

procedure TF_Server.Log(const s: string);
var
  StrP: PString;
begin
  New(StrP);
  StrP^ := s;
  SendMessage(self.Handle, WM_LOG, Integer(StrP), 0); // Length(s)
end;
Wieso dieser Fehler nur dann auftritt, wenn ich die Form noch nie angezeigt habe, verstehe ich nicht so ganz. Vllt kann mir das ja noch mal jemand erklären, aber für's erste bin ich wieder glücklich :hello:

Gruß Nogge


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