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 Problem bei TForm (https://www.delphipraxis.net/55767-problem-bei-tform.html)

Bloodfire 26. Okt 2005 16:43


Problem bei TForm
 
Hi!

Das Programm soll ein Netzwerkspiel werden. Die Hauptform (TMainForm) ist ein kleines Chatfenster mit Userliste. Über Kontextmenü der Userliste kann man einen Spieler zu einem Spiel auffordern - es wird eine (halbtransparente) Form darübergelegt, um die Einladung zu schicken (TInvitationForm) (beispiel: "Sie wurden von Spieler XY eingeladen. Möchten Sie annehmen?") Nachdem der User auf annehmen geklickt hat soll sich bei diesem das eigentliche Spielfenster (TBoardForm) öffnen, bzw. auch bei seinem Gegenüber, sobald der die Message ('accept') bekommen hat.

Soweit so gut. Funktioniert eigentlich, nur:
Bei dem Spieler, der auf 'Annehmen' klickt, macht sich das Spielfenster reibungsfrei auf. Bei dem jedoch, der die Message erhält und bei dem sich darauf hin das Fenster öffnen soll, hängt sich das gesamte Programm auf. Man sieht den Umriss der Form und ein paar Umrisse der Komponenten, aber alles inaktiv / defekt. Ich kann als User nichts mehr machen, außer die Andwendung mit Hilfe des Taskmanagers zu beenden.


Chronologisch:

Delphi-Quellcode:
procedure TInvitationForm.BtnAcceptClick(Sender: TObject);
begin
   MainForm.SendStatus('Accept');
   SuddenClose:=False;
   Close;
end;
Delphi-Quellcode:
procedure TMainForm.SendStatus(FStatus: String);
var
  SendText: String;
begin
   try
    if TcpClient.Connect then
      begin
         SendText:='Status'+'#'+FStatus;
         TcpClient.Sendln(SendText);
      end;
   finally
     TcpClient.Disconnect;
   end;

   if (FStatus = 'Accept') then
     begin
        Board:=TBoardForm.Create(nil);
        Board.SetProperties(Paths,UserData,Opponent.Nick,Opponent.IP,5200,
          Language);
        Board.Show;
        // FUNKTIONIERT!! 
     end;
end;
Delphi-Quellcode:
procedure TMainForm.TcpServerAccept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
  i,j: Integer;
  RecievedLn: String;
  RecievedKind: String;
  RecievedStatus: String;
begin
   RecievedLn:=ClientSocket.Receiveln;

   i:=0;
   while not(RecievedLn[i]='#')
     do inc(i);
   RecievedKind:=Copy(RecievedLn,0,i-1);

   if not(RecievedKind='Status')
     then exit;

   inc(i);
   j:=i;
   while not(length(RecievedLn)=i)
     do inc(i);
   RecievedStatus:=Copy(RecievedLn,j,i-j+1);

   CheckRecievedStatus(RecievedStatus);
end;
Delphi-Quellcode:
procedure TMainForm.CheckRecievedStatus(FStatus: String);
var
  BBoard: TBoardForm;
begin
   (...)
   else
   if (FStatus='Accept') then
     begin
        Invitation.SuddenClose:=False;
        Invitation.Close;

        Board:=TBoardForm.Create(nil);
        Board.SetProperties(Paths,UserData,Opponent.Nick,Opponent.IP,5200,
          Language);
        Board.Show;
        //FUNKTIONIERT NICHT!!!
     end
   else
   (...)
end;
Delphi-Quellcode:
procedure TBoardForm.FormCreate(Sender: TObject);
begin
   FirstStart:=True;
end;

procedure TBoardForm.FormActivate(Sender: TObject);
begin
   if not(FirstStart)
     then exit;

   FirstStart:=False;
   LoadImages;
   SetButtons;
   SetForm;
end;
Delphi-Quellcode:
procedure TBoardForm.SetProperties(FPaths: RPaths; FUserData: RUserData;
  FOppNick,FOppIP: String; FPort: Integer; FLanguage: String);
begin
   Paths:=FPaths;
   UserData:=FUserData;

   OppData.Nick:=FOppNick;
   OppData.IP:=FOppIP;

   UsedPort:=FPort;

   Language:=FLanguage;

   SetNetwork;
end;
Ich hoffe, mir kann jemand weiterhelfen, ich hab keinen Plan, wo ich da nach Fehlern suchen soll, bin die einzelnen Befehle schon x-mal step-by-step durchgegangen und funktioniert auch alles ohne fehlermeldungen. Es hängt sich eben nur immer auf. Ein dritter hat da oft mehr Durchblick ...

Danke!

jim_raynor 26. Okt 2005 16:46

Re: Problem bei TForm
 
Ich kann mir vorstellen, dass hier Probleme gibt:

Delphi-Quellcode:
while not(RecievedLn[i]='#')
     do inc(i);
führt schnell zu einer Endlosschleife. Kleiner Tipp. Du kannst in Delphi auch den Programmlauf unterbrechen (Funktion: Pause) und dann per Aufruf-Stack (Strg+F3) schauen, wo er festhängt. Auf jeden Fall deutet alles auf eine Endlosschleife hin.

P.S: ClientSocket.Receiveln liefert nicht immer den kompletten String zurück (je nach dem wieviel Zeit vergangen ist). Dadurch könnte diese Endlosschleife entstehen.

Bloodfire 26. Okt 2005 17:50

Re: Problem bei TForm
 
Zitat:

Auf jeden Fall deutet alles auf eine Endlosschleife hin.
Endlosschleife ist es definitiv nicht, bin's auch gerade nochmal durchgegangen. Alle Werte werden richtig gesetzt. Und er kommt auch in die CheckRecievedStatus-Prozedur.

Zitat:

Kleiner Tipp. Du kannst in Delphi auch den Programmlauf unterbrechen (Funktion: Pause) und dann per Aufruf-Stack (Strg+F3) schauen, wo er festhängt.
Bei Strg+F3 tut sich bei mir gar nichts, Aufruf-Stack is bei mir auf Strg+Alt+S, aber egal.
In dem steht lediglich der Name der Exefile, sonst nichts.

Jedenfalls wenn ich auf Pause Klicke, öffnet sich mal automatisch das CPU-Fenster, da steht er bei:

ntdll.KiFastSystemCallRet:
7C91EB94 C3 ret

sagt das etwas aus?
(so intern, muss ich gestehen, kenn ich mich überhaupt nicht aus)

Bloodfire 26. Okt 2005 17:59

Re: Problem bei TForm
 
Ok, ich hab nun versucht, die Zwischenform (TInvitationForm), also die Anfrage, ob man die Einladung annehmen will, einfach wegzulassen, und es funktioniert! ??

jim_raynor 27. Okt 2005 07:10

Re: Problem bei TForm
 
Zitat:

Zitat von Bloodfire
Jedenfalls wenn ich auf Pause Klicke, öffnet sich mal automatisch das CPU-Fenster, da steht er bei:

Wenn du da stehst, dann geh einfach in den Quellcode-Editor und drücke einmal F8. Dann solltest du an die richtige Stelle kommen. Und dann solltest du auch den Aufruf-Stack sehen.

Bloodfire 27. Okt 2005 20:47

Re: Problem bei TForm
 
Das mit dem Aufruf-Stack hab ich zwar noch nicht gemacht, jedoch habe ich, denk ich mal, das Problem gefunden (& gelöst): Und zwar habe ich vorher immer von TInvitationForm auf TMainForm 'zurückgegriffen' und hab auch TInvitationForm im ShowModal-Zustand von außen (also von TMainForm weg) ändern wollen. Irgendwie war das alles etwas zu verstrickt und auch nicht wirklich 'schön' programmiert.

Was ich vorher weglassen wollte, hab ich jetzt eingebaut: Tcp-Komponenten auf TInvitationForm, damit die zwei kommunizieren können (und nicht TMainForm dazwischen funken muss). Der ShowModal-Aufruf der TInvitationForm befindet sich zusätzlich in einer Public-Funktion vin TInvitationForm, welche von TMainForm aufgerufen wird. So bekomme ich dann den Wert zurück.


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