Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > Lazarus, FreePascal, Kylix, etc.
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-03-2017
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
almacenar forms abiertos en un listbox

Buenas,

quizá sea una pregunta de "perogrullo" pero me estoy matando la cabeza con este tema.

Tengo una aplicacion en la que los forms se abren como show en un panel principal sin problema. Puedo maximizar, minimizar, cerrar etc.
Gracias a este maravilloso foro y su ayuda.

Viendo otros post que preguntan sobre saber que forms estan abiertos, intente implementar eso mismo y cargarlos en un listbox, asi, cuando tuviera algun form "oculto" podria mostrarlo en primer plano.

Pues bien, seguro que es una tonteria pero no hay forma.

Tengo esto

Código Delphi [-]
procedure TPrincipal.tbutton_inventariosClick(Sender: TObject);
begin
  if not assigned(finventarios) then
  begin
  finventarios:=tfinventarios.Create(application);
  finventarios.Parent:=CONTENEDOR;
  finventarios.Show;
   formularios_abiertos;
  end
  else
  begin
   end;
end;

Ahi, lo que hago es preguntar si el formulario ha sido asignado y sino crea uno. Ya cuando lo cierro se libera (para no abrir el mismo 2 veces).
CONTENEDOR es un panel donde lo abro.
formularios_abiertos es donde hago lo siguiente:

Código Delphi [-]
procedure tprincipal.formularios_abiertos;
var
 i:integer;
begin
  listbox1.Clear;
  for i:= Screen.FormCount -1 downto 0 do
    if screen.Forms[i].Showing then
       if (screen.forms[i].Caption<>'Principal') and (screen.forms[i].caption<>'acceso') then
    listbox1.Items.Add(screen.Forms[i].Caption);

Funcionar funciona, porque, si hago click en una de las lineas del listbox me muestra el form, lo unico malo es que los forms estan guardados de forma inversa en el listbox y me muestra el ultimo.
Si, es porque la i va en descendente y el listbox lo guarda en ascendente. Eso lo entiendo

El chiste es que si lo pongo al reves, al seleccionar el ultimo formulario del listbox me acaba tirando un error y no precisamente de index -1.

Tambien intente usar un array para guardar los forms y luego pasarlos al listbox pero es el mismo resultado.

No debe ser complicado pero ....

Gracias.
Responder Con Cita
  #2  
Antiguo 01-03-2017
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.
Cita:
Empezado por anubis Ver Mensaje
...
El chiste es que si lo pongo al reves, al seleccionar el ultimo formulario del listbox me acaba tirando un error y no precisamente de index -1.
Usando,
Código Delphi [-]
...
  for i := Screen.FormCount-1 downto 0 do
    if Screen.Forms[i].Showing and ( Screen.Forms[i] <> Self ) then
      ListBox1.Items.Add( Screen.Forms[i].Caption );
...
muestra el título de los formularios por el órden de aparición que previamente se les dé.

¿ Cuál es el código asignado al evento OnClick del ListBox y que mensaje de error te muestra exáctamente ?

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 01-03-2017
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Gracias por responder.

El problema viene en el listbox, que los recoge en orden inverso.

Creo el formulario, los recojo en un listbox y ya tengo la lista.

si le doy click a uno de los elementos, lo que hago es:

Código Delphi [-]
showmessage(screen.Forms[listbox1.ItemIndex].caption+' '+inttostr(listbox1.ItemIndex));
 screen.Forms[listbox1.ItemIndex].Show;

Y no corresponde el numero del screen.forms con el nombre almacenado.
Responder Con Cita
  #4  
Antiguo 01-03-2017
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
Cita:
Empezado por anubis Ver Mensaje
Y no corresponde el numero del screen.forms con el nombre almacenado.
No tendría porqué corresponder. Tu ListBox tiene (por lo menos) dos formularios menos que ScreenForms. Los índices de una lista y la otra van a diferir.

LineComment Saludos
Responder Con Cita
  #5  
Antiguo 01-03-2017
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Efectivamente amigo roman, por eso se los quite después.
Perdón si los deje en el código, pero estuve haciendo un montón de pruebas sin resultado.
Como comentaba, el recorrido de los forms se hace de mas a menos y en el listbox se añaden de menos a mas, creo que va por ahi la cosa.

Lo que no entiendo es el porqué se hace así con los forms, si lo hago al revés, si funciona relativamente, pero me da un error si elijo la última opción del listbox.

edito: en una de las veces, al pulsar una de las opciones del listbox, me sale frProgressForm en una ventanita y despues mensaje que pone violación de acceso.
Imagino que, el recorrer los forms de ascendente a descendente tenga alguna explicación, porque ahí no hay error, solo que el orden no es el correcto en el listbox

Última edición por anubis fecha: 01-03-2017 a las 18:46:14.
Responder Con Cita
  #6  
Antiguo 01-03-2017
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
Y ¿cuál es el error? Creo que aún no lo has dicho.

LineComment Saludos
Responder Con Cita
  #7  
Antiguo 01-03-2017
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Si, perdón, lo edité después.

Cita:
Edito: en una de las veces, al pulsar una de las opciones del listbox, me sale frProgressForm en una ventanita y despues mensaje que pone violación de acceso.
Imagino que, el recorrer los forms de ascendente a descendente tenga alguna explicación, porque ahí no hay error, solo que el orden no es el correcto en el listbox
Responder Con Cita
  #8  
Antiguo 01-03-2017
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Creo que el cargar los punteros a formularios dentro del ListBox te va a simplificar el asunto, te pongo un ejemplo :
Código Delphi [-]
....
uses Unit2, Unit3, Unit4, Unit5;

procedure TForm1.LoadForms;
var
  i : Integer;
begin
  ListBox1.Clear;
  for i := Screen.FormCount-1 downto 0 do
    if Screen.Forms[i] <> Self then
    begin
      Screen.Forms[i].Parent := Panel1;
      Screen.Forms[i].Show;
    end;
  for i := Screen.FormCount-1 downto 0 do
    if Screen.Forms[i].Showing and ( Screen.Forms[i] <> Self ) then
      ListBox1.AddItem( Screen.Forms[i].Caption, Pointer(Screen.Forms[i]) );
  // ListBox1.Sorted := True;  //(opcional)
  Randomize;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  LoadForms;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
const
  COLORS: array[0..3] of TColor = (clRed, clLime, clYellow, clBlue);
var
  i, ix: Integer;
begin
  ix := ListBox1.ItemIndex;    // selección actual
  if ListBox1.ItemIndex <> -1 then
  begin
    // restaurar color en todos los form.
    for i := 0 to ListBox1.Count-1 do
      TForm(ListBox1.Items.Objects[i]).Color := clBtnFace;
   // pintar form seleccionado con su color
    if ix <> -1 then
      TForm(ListBox1.Items.Objects[ix]).Color := Colors[ix];
  end;
end;

procedure TForm1.btnMergeClick(Sender: TObject);
var
  i, x: Integer;
begin
  for i := 0 to ListBox1.Items.Count-1 do
  begin
    x := Random(ListBox1.Items.Count);
    ListBox1.Items.Move(i, x);
  end;
end;

Salida del ejemplo:


De este modo simpre habrá correspondencia entre el nombre mostrado en el ListBox y el objeto sobre el que accionar, espero te sirva.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 01-03-2017 a las 21:02:50.
Responder Con Cita
  #9  
Antiguo 01-03-2017
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Me olvidaba... para completar el ejemplo, liberar form al azar
Código Delphi [-]
...
procedure TForm1.btnLiberaClick(Sender: TObject);
begin
  TForm(ListBox1.Items.Objects[Random(Screen.FormCount)]).Free;
  LoadForms; // actualizar ListBox
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #10  
Antiguo 02-03-2017
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
gracias por el detalle .

Estaba intentando probar la unit que posteaste y me sale, a la hora de compilar:
Código Delphi [-]
 ListBox1.AddItem( Screen.Forms[i].Caption, Pointer(Screen.Forms[i]));

Cita:
uprincipal.pas(182,75) Error: Incompatible type for arg no. 2: Got "Pointer", expected "TObject"
algo le falta o sobra
Responder Con Cita
  #11  
Antiguo 02-03-2017
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
Cita:
Empezado por anubis Ver Mensaje
uprincipal.pas(182,75) Error: Incompatible type for arg no. 2: Got "Pointer", expected "TObject"
Le sobra el Pointer.

LineComment Saludos
Responder Con Cita
  #12  
Antiguo 02-03-2017
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.
Cita:
Empezado por anubis Ver Mensaje
Cita:
uprincipal.pas(182,75) Error: Incompatible type for arg no. 2: Got "Pointer", expected "TObject"
Rehice la prueba en Lazarus y efectivamente no tolera ese moldeo, Delphi (donde hice el ejemplo) no tiene inconveniente.

Para evitar el error en Lazarus podrías cambiar "Pointer" por "TObject" o, como correctamente apunta roman, quitar directamente el moldeo.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #13  
Antiguo 02-03-2017
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
Cita:
Empezado por ecfisa Ver Mensaje
Rehice la prueba en Lazarus y efectivamente no tolera ese moldeo, Delphi (donde hice el ejemplo) no tiene inconveniente.
De todas formas, el moldeo es innecesario ya que el segundo parámetro de AddItem está declarado como TObject.

LineComment Saludos
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
como almacenar datos de un listbox rufo Varios 1 08-01-2010 11:00:43
agregar y/o eliminar items de un listbox a partir de otro listbox Goyo PHP 2 27-09-2007 17:46:30
Almacenar en una variable de session el contenido de un ListBox (Items)! JuanErasmo .NET 2 16-01-2007 22:13:32
Acceder a los forms abiertos de tu aplicacion Neftali [Germán.Estévez] Trucos 0 07-06-2006 10:55:15
Almacenar datos en una listbox pepelu1975 Varios 5 13-02-2004 12:51:21


La franja horaria es GMT +2. Ahora son las 18:37:11.


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