Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-10-2005
Avatar de DarkByte
DarkByte DarkByte is offline
Miembro
 
Registrado: sep 2003
Ubicación: Desconocido
Posts: 1.322
Poder: 22
DarkByte Va por buen camino
Otro típico List Index Out Of Bounds

Wops!

Acudo a vosotros para pediros otra vez ayuda

Estoy intentando que el servidor me enumere las conexiones clientes... he creado un ListBox llamado "lbClients", una clase llamada Client, y un objeto TList llamado Clients donde guardo la lista de Client.

Código Delphi [-]

type
  TSimpleClient = class(TObject)
    DNS,
    Name        : String;
    ListLink    : Integer;
    Thread      : Pointer;
  end;

  TfrmLambda = class(TForm)
    IdTCPServer1: TIdTCPServer;
    lbClients: TListBox;
    //[...]
  private
    { Private declarations }
  public
    { Public declarations }
    Clients  : TList;
    procedure BroadcastMsg(Codigo,Mensaje:string);
    procedure UpdateClientList;
  end;

Bien. El TList se crea en el evento OnCreate del form... y se rellena de la siguiente manera:

Código Delphi [-]
procedure TfrmLambda.IdTCPServer1Connect(AContext: TIdContext);
var
  Client : TSimpleClient;
begin
  Client := TSimpleClient.Create;
  Client.DNS  := AContext.Connection.Socket.Binding.PeerIP;
  Client.Name := 'Registrandose';
  Client.ListLink := lbClients.Items.Count;
  Client.Thread := AContext;
  lbClients.Items.Add(Client.Name);
  AContext.Data := Client;
  Clients.Add(Client);
  AContext.Connection.IOHandler.Write('Nick: ');
end;

Cuando el cliente se desconecta, evidentemente, hay que quitarlo de en medio...

Código Delphi [-]
procedure TfrmLambda.IdTCPServer1Disconnect(AContext: TIdContext);
var
  Client : TSimpleClient;
begin
  Client := Pointer(AContext.Data);
  BroadCastMsg('004', '*** '+Client.Name+' se ha salido');
  Clients.Delete(Client.ListLink);
  lbClients.Items.Delete(lbClients.Items.IndexOf(Client.Name));
  Client.Free;
  AContext.Data := nil;
  UpdateClientList;
end;

Y nos falta el método por el cual actualizo la lista de clientes...
Código Delphi [-]
procedure TfrmLambda.UpdateClientList;
var
  Count : Integer;
begin
{ Loop through all the clients connected to the system and set their names }
  for Count := 0 to lbClients.Items.Count -1 do
    if Count < Clients.Count then
      lbClients.Items.Strings[Count] := TSimpleClient(Clients.Items[Count]).Name;
end;

Pues bien, gran parte de este código por no decir que prácticamente todo está cojido de un ejemplo de las indy que tenía por ahí y portado a Indy 10.

El programa me falla específicamente cuando un cliente se desconecta y hago clic en uno que esté por debajo (se ha conectado posteriormente). En el OnClic del ListBox tengo el siguiente código:

Código Delphi [-]
procedure TfrmLambda.lbClientsClick(Sender: TObject);
var
  Client : TSimpleClient;
begin
  if lbClients.ItemIndex = -1 then
    exit;
  Client := Clients.Items[lbClients.ItemIndex];
  lbNombre.Caption := Client.Name;
  lbIp.Caption  := Client.DNS;
end;

Muchísimas gracias a todos... y un abrazo
__________________
:)
Responder Con Cita
  #2  
Antiguo 10-10-2005
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 0
rounin Va por buen camino
Exprecion
Clients.Delete(Client.ListLink);
hace "ListLink" de todos los otros objetos "Client" invalidos
(si ListLink <> Clients.Count-1).

Usa
Clients.Remove(Client);

(o usa lbClients.Items.Objects)

Última edición por rounin fecha: 10-10-2005 a las 19:39:53.
Responder Con Cita
  #3  
Antiguo 10-10-2005
Avatar de DarkByte
DarkByte DarkByte is offline
Miembro
 
Registrado: sep 2003
Ubicación: Desconocido
Posts: 1.322
Poder: 22
DarkByte Va por buen camino
Aja, tengo claro que el fallo está en la parte Disconnect... pero supongo que no sé lo suficiente como para comprender tu post anterior. ¿Podría ser explicado de nuevo? Muchísimas gracias
__________________
:)
Responder Con Cita
  #4  
Antiguo 10-10-2005
Avatar de vtdeleon
vtdeleon vtdeleon is offline
Miembro
 
Registrado: abr 2004
Ubicación: RD & USA
Posts: 3.236
Poder: 24
vtdeleon Va por buen camino
Saludos

Tratando de entender un poco, creo que rounin trta de decirte que cambie esta parte Clients.Delete(Client.ListLink); por Clients.Remove(Client);

Haz la prueba, ya que nuestro amigo rouni tiene un poco de problema con el español.

No comprendo bien el codigo(nunca he tratabajo con indy)
__________________
Van Troi De León
(Not) Guía, Code vB:=Delphi-SQL, ¿Cómo?
Viajar en el tiempo no es teóricamente posible, pues si lo fuera, ya estarían aqui contándonos al respecto!
Responder Con Cita
  #5  
Antiguo 10-10-2005
Avatar de DarkByte
DarkByte DarkByte is offline
Miembro
 
Registrado: sep 2003
Ubicación: Desconocido
Posts: 1.322
Poder: 22
DarkByte Va por buen camino
Funciona de maravillas!!!

MUUUUAKS!!! :P
__________________
:)
Responder Con Cita
  #6  
Antiguo 10-10-2005
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 0
rounin Va por buen camino
Saludos,

Perdoname por mi mal español.

Trato explicar mas completo.
Ahora usas dos listas para guardar TClient
(lbClients.Items y Clients)
y tratas sincronizarlas en varios lugares.
En principle eso es possible, pero mejor
o usar una lista,
o sincronizar en solo una lugar (cada vez borrar una
y rellenar).
En cualquier caso no es buena idea guardar
indices en lista (como ListLink), porque las operaciones
Add, Remove, Insert cambian orden de objetos en lista.

El mas simplemente manera en tu case es usar
solo una lista (lbClientes.Items.Objects)
y no sincronizar nada:

Código Delphi [-]
 
{...}
//ListLink : Integer; // no necesita
{...}
//Clients : TList; // no necesita
{...}
 
procedure TfrmLambda.IdTCPServer1Connect(AContext: TIdContext);
var
  Client : TSimpleClient;
begin
  Client := TSimpleClient.Create;
  Client.DNS := AContext.Connection.Socket.Binding.PeerIP;
  Client.Name := 'Registrandose';
 
  //Client.ListLink := lbClients.Items.Count;
 
  Client.Thread := AContext;
 
  //lbClients.Items.Add(Client.Name);
  lbClients.Items.AddObject(Client.Name, Client);
 
  AContext.Data := Client;
 
  //Clients.Add(Client);
 
  AContext.Connection.IOHandler.Write('Nick: ');
end;
 
procedure TfrmLambda.IdTCPServer1Disconnect(AContext: TIdContext);
var
  Client : TSimpleClient;
begin
  Client := Pointer(AContext.Data);
  BroadCastMsg('004', '*** '+Client.Name+' se ha salido');
 
  //Clients.Delete(Client.ListLink);
 
  //lbClients.Items.Delete(lbClients.Items.IndexOf(Client.Name));
 
  lbClients.Items.Delete(lbClients.Items.IndexOf(Client.Name));
  Client.Free;
  AContext.Data := nil;
  UpdateClientList;
end;
 
//procedure TfrmLambda.UpdateClientList; // no necesita
 
procedure TfrmLambda.lbClientsClick(Sender: TObject);
var
  Client : TSimpleClient;
begin
  if lbClients.ItemIndex = -1 then
    exit;
 
  //Client := Clients.Items[lbClients.ItemIndex];
  Client := lbClients.Items.Objects[lbClients.ItemIndex];
 
  lbNombre.Caption := Client.Name;
  lbIp.Caption := Client.DNS;
end;

Última edición por rounin fecha: 10-10-2005 a las 21:35:57.
Responder Con Cita
  #7  
Antiguo 10-10-2005
Avatar de DarkByte
DarkByte DarkByte is offline
Miembro
 
Registrado: sep 2003
Ubicación: Desconocido
Posts: 1.322
Poder: 22
DarkByte Va por buen camino
Muchísimas gracias por la explicacion.

Veo que ha puesto todo el foco sobre el TListBox en vez de el TList... podría funcionar. Muchísimas gracias, voy a probarlo

De cualquier forma, si puede decirme su lenguaje nativo o uno que domine mejor que el castellano, podemos intentar cambiar a ese para ahorrar molestias
__________________
:)
Responder Con Cita
  #8  
Antiguo 10-10-2005
Avatar de vtdeleon
vtdeleon vtdeleon is offline
Miembro
 
Registrado: abr 2004
Ubicación: RD & USA
Posts: 3.236
Poder: 24
vtdeleon Va por buen camino
Saludos
Cita:
Empezado por DarkByte
De cualquier forma, si puede decirme su lenguaje nativo o uno que domine mejor que el castellano, podemos intentar cambiar a ese para ahorrar molestias
Lamentablemente, aquí la guía de estilo dice esto....
__________________
Van Troi De León
(Not) Guía, Code vB:=Delphi-SQL, ¿Cómo?
Viajar en el tiempo no es teóricamente posible, pues si lo fuera, ya estarían aqui contándonos al respecto!
Responder Con Cita
  #9  
Antiguo 10-10-2005
Avatar de DarkByte
DarkByte DarkByte is offline
Miembro
 
Registrado: sep 2003
Ubicación: Desconocido
Posts: 1.322
Poder: 22
DarkByte Va por buen camino
Claro, hace tiempo que estoy en el foro...

Por eso tenía pensado poner mis mensajes en ambos lenguajes, así no falto a ella y obtengo una respuesta más precisa.

Gracias por el toque, vtdeleon
__________________
:)
Responder Con Cita
  #10  
Antiguo 11-10-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Vamos a hacer una pequeña aclaración en cuanto al lenguaje a utilizar en los foros.

Primeramente, es cierto que la guía de estilo implica que el lenguaje oficial de los foros es el español, y no creo que esto vaya a cambiar.

Sin embargo, no será ésta la primera vez que se haga una excepción. Ya en ocasiones anteriores se han entablado hilos en portugués.

Al forista rounin me gustaría expresarle dos cosas:

1. Siéntete bienvenido en estos foros, agradecemos toda la colaboración que has prestado desde tu ingreso.

2. De ser posible, trata de escribir tus mensajes en español. Pero si te enfrentas con situaciones que te sea difícil expresar, siéntete en libertad de hacerlo en inglés; varios moderadores estamos en la disposición, de ser necesario, de llevar a cabo una traducción de aquello que pueda no entenderse.

// Saludos

Última edición por roman fecha: 11-10-2005 a las 02:15:18.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 10:44:32.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi