Ir al contenido


Foto

¿Cómo saber si un TPanel está al frente o atrás?


  • Por favor identifícate para responder
12 respuestas en este tema

#1 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 29 enero 2013 - 02:15

Jóvenes Delphi-ner@s, buen día/tarde/noche...

Resulta que tengo una serie de TPanel, uno y solamente uno de ellos está al frente con BringToFront, y SUPUESTAMENTE los demás están atrás con SendToBack.

¿Cómo puedo saber el nombre del TPanel que está en éste preciso momento al frente? Pregunta simple, pero sospecho fuertemente que tendrá repercusiones...
  • 0

#2 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 29 enero 2013 - 05:16

Pues no se me ocurre más que si el SendToBack o el BringToFront lo haces en tiempo de ejecución, controles mediante una variable qué panel fue el último en hacer ese movimiento... a lo mejor si nos regalas un poco más de contexto de lo que quieres hacer o lograr tal vez podamos pensar en algo alternativo pero útil...

Saludox ! :)
  • 0

#3 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 30 enero 2013 - 04:18

Puedes usar TForm.ControlAtPos(x,y) -de memoria- ese te dira que control es el visible en el centro de tu zona de paneles, y si no es un panel, sera algo que tienes encima del panel, así que solo salta a su parent hasta encontrar el panel al que pertenece... ese panel es el que está visible.
  • 0

#4 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 30 enero 2013 - 08:38

...a lo mejor si nos regalas un poco más de contexto de lo que quieres hacer o lograr tal vez podamos pensar en algo alternativo pero útil...


A petición de la señorita, va el código. Con éste código se esconden/muestran los paneles:



delphi
  1. procedure TMiForma.EvaluaPanel(iNumero: Integer);
  2. var
  3.   sNombrePanel: string;
  4.   iIndice: Integer;
  5. begin
  6.   sNombrePanel := 'pnlCap'+Trim(IntToStr(iNumero+1));
  7.   with pnlCaptura do
  8.   begin
  9.       for iIndice :=  0 to ControlCount-1 do
  10.       begin
  11.         if LeftStr((Controls[iIndice] as TPanel).Name,6) = 'pnlCap' then
  12.         begin
  13.             if (Controls[iIndice] as TPanel).Name <> sNombrePanel then
  14.             begin
  15.               with (Controls[iIndice] as TPanel) do
  16.               begin
  17.                   SendToBack;
  18.                   Height := 40;
  19.                   Width := 185;
  20.                   Visible := False;
  21.               end;
  22.             end else begin
  23.               with (Controls[iIndice] as TPanel) do
  24.               begin
  25.                   BringToFront;
  26.                   Visible := True;
  27.                   Width := pnlCaptura.ClientWidth -1;
  28.                   Height := pnlCaptura.ClientHeight -1;
  29.                   Align := alClient;
  30.                   Tag := iNumero+1;
  31.               end;
  32.               pnlCapturaResize(Self);
  33.             end;
  34.         end;
  35.       end;
  36.   end;
  37. end;



Y en algún otro evento de mi código, realizo ésta evaluación:

     

delphi
  1. if (pnlCap1.Align = alClient) then
  2.       begin
  3.         if Trim(redtMotivoConsulta.Text) > '' then
  4.             PalomeaNavegador;
  5.       end;



Mi idea es que en ésta evaluación, complementando la pregunta de si el panel en cuestión está alineado "al cliente", también saber que está AL FRENTE de todos los demás páneles, para "amarrar" cualquier posible error.

Gracias por su colaboración.

Puedes usar TForm.ControlAtPos(x,y) -de memoria- ese te dira que control es el visible en el centro de tu zona de paneles, y si no es un panel, sera algo que tienes encima del panel, así que solo salta a su parent hasta encontrar el panel al que pertenece... ese panel es el que está visible.


Lo hice de ésta manera ayer mismo, Sergio, antes de postear ésta pregunta. Y no, no me ayuda puesto que no es cuestión de posicionamiento del cursor, sino de evaluar ANTES que se mueva el ratón siquiera...
  • 0

#5 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 30 enero 2013 - 08:43

......... Lo hice de ésta manera ayer mismo, Sergio, antes de postear ésta pregunta. Y no, no me ayuda puesto que no es cuestión de posicionamiento del cursor, sino de evaluar ANTES que se mueva el ratón siquiera...


Me parece que ésto es un problema de concepto, en que evento quieres que se dispare esa acción, desde mi humilde punto de vista debería ser cuando la forma tiene el foco; por lo que yo ejecutaría lo que Sergio comenta en el evento OnShow que es cuando la forma tiene el foco de la aplicación.

Saludos
  • 0

#6 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 30 enero 2013 - 11:15

Y digo yo..... no te serviría usar un componente como el PageControl? Te sería muy sencillo saber qué página del control está mostrándose, gestionarlo,...... Si lo que no quieres son las tabs, siempre puedes darles la propiedad TabVisible a false

Nos leemos
  • 0

#7 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 30 enero 2013 - 12:19

...en que evento quieres que se dispare esa acción...


En un humildísimo TButton.OnClick. Realmente, nada del otro mundo... (aparentemente)


Y digo yo..... no te serviría usar un componente como el PageControl? Te sería muy sencillo saber qué página del control está mostrándose, gestionarlo,...... Si lo que no quieres son las tabs, siempre puedes darles la propiedad TabVisible a false...


No, desafortunadamente. Estoy haciendo una pantalla con algo así como 40 secciones (que estoy manejando una sección por panel), y algunas de éstas secciones contienen subsecciones (que sí estoy manejando con TPageControl)..., ¿por qué lo estoy haciendo con TPanel's? Por la sencillísima razón que cualquier otro control haría que la pantalla se pareciera a un enorme plato de spaghetti a la boloñesa con muchas albóndigas y bañado en abundante salsa. O sea, un ENORME batidillo.
  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 30 enero 2013 - 12:24

En un humildísimo TButton.OnClick. Realmente, nada del otro mundo... (aparentemente)


Ah caray, como habías dicho que antes incluso de mover el ratón....

.......sino de evaluar ANTES que se mueva el ratón siquiera...


pues esto que dices es totalmente diferente. Debería de funcionar si es que la forma que contiene los paneles tiene el foco de la aplicación.

Saludos
  • 0

#9 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 30 enero 2013 - 05:13

Observa que en tu procedimiento EvaluaPanel, estás volviendo invisibles todos los TPanel diferentes al número que le pasas en el parámetro INumero, por lo tanto solo debería quedar uno visible, si estoy en lo correcto, establecer el panel que está al frente es tan fácil como recorrer lo paneles y encontrar el visible.

Podrías crear una función que te devuelva el nombre del panel



delphi
  1. function TForm1.PanelVisible: TPanel;
  2. var
  3.   k: integer;
  4. begin
  5.   for k := 0 to self.ControlCount - 1 do
  6.     if self.Controls[k].ClassType = TPanel then
  7.       if (self.Controls[k] as TPanel).Visible then
  8.       begin
  9.         result := self.Controls[k] as TPanel;
  10.         break;
  11.       end;
  12. end;



Si estoy en lo correcto, en el procedimiento EValuaPanel te sobrarían varias líneas de código, ya que con hacer invisibles los panels es suficiente:


delphi
  1.             if (Controls[iIndice] as TPanel).Name <> sNombrePanel then
  2.             begin
  3.               with (Controls[iIndice] as TPanel) do
  4.               begin
  5.                   SendToBack; //sobra
  6.                   Height := 40; //sobra
  7.                   Width := 185; //sobra
  8.                   Visible := False;
  9.               end;



Saludos
  • 0

#10 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 31 enero 2013 - 01:57

No, desafortunadamente. Estoy haciendo una pantalla con algo así como 40 secciones (que estoy manejando una sección por panel), y algunas de éstas secciones contienen subsecciones (que sí estoy manejando con TPageControl)..., ¿por qué lo estoy haciendo con TPanel's? Por la sencillísima razón que cualquier otro control haría que la pantalla se pareciera a un enorme plato de spaghetti a la boloñesa con muchas albóndigas y bañado en abundante salsa. O sea, un ENORME batidillo.


Cada uno puede programar como quiera pero, hacer un PageControl con TabVisible a false te da el mismo aspecto visual que sobreponer TPanels.

No obstante, una solución si lo quieres hacer con TPanels es, en lugar de "moverlos al frente", es hacerlos visibles o invisibles. Con ésto, simplemente recorriendo los TPanels y consultando su visibilidad sabrás cuál está con efecto "OnTop" (el visible).

Un comentario, aunque no sé exactamente qué hace la pantalla en cuestión. Para pantallas de este tipo, quizás te resultaría mejor usar TFrames en lugar de TPanels, por eso de organizar un poco más el código y tal.

Nos leemos
  • 0

#11 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 01 febrero 2013 - 09:39


Puedes usar TForm.ControlAtPos(x,y) -de memoria- ese te dira que control es el visible en el centro de tu zona de paneles, y si no es un panel, sera algo que tienes encima del panel, así que solo salta a su parent hasta encontrar el panel al que pertenece... ese panel es el que está visible.


Lo hice de ésta manera ayer mismo, Sergio, antes de postear ésta pregunta. Y no, no me ayuda puesto que no es cuestión de posicionamiento del cursor, sino de evaluar ANTES que se mueva el ratón siquiera...


No veo la conexión con el mouse, puedes usar esto en tu evento onclick, las coordenadas x,y puedes ser, digamos, el centro de tu panel contenerdor, así no fallas el tiro!

En pseudocodigo (no probado):



delphi
  1. MyControl:= pnlCaptura.ControlAtPos( pnlCaptura.Width div 2, pnlCaptura.Height div 2);
  2. while not (MyControl is TPanel) and Assigned(MyControl) do
  3.   MyControl:= MyControl.parent;
  4. if Assigned(MyControl) then
  5.   MyPanel:= TPanel(MyControl)
  6. else
  7.   MyPanel:= null;



Mi única duda es la linea 1, creo que las coordenadas "locales" al panel han de convertirse a coordenadas globales de pantalla antes de usarlas en el controlatpos(), o quizás no, igual eso era a la inversa, para pasar de mouse a local dentro del control... en cualquier caso, pnlCaptura tiene una función para ello (y su inversa, por cierto), solo que de memoria no la recuerdo... ClientToScreen() creo que era.

Tendrás que mirar la documentación y ver si tienes o no que hacer esa conversión, poca cosa.

Por cierto, yo lo haría así desde un principio:

-Creas una variable en el form tipo TPanel, por ejemplo, PanelActivo.
-Inicializas a null en el FormCreate.
-Justo tras el BringToFront haces PanelActivo:= Controls[iIndice];

Ya está, lo usas luego en el onclick o donde quieras, siempre lo tienes localizado!

  • 0

#12 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 01 febrero 2013 - 09:59

......

Por cierto, yo lo haría así desde un principio:

-Creas una variable en el form tipo TPanel, por ejemplo, PanelActivo.
-Inicializas a null en el FormCreate.
-Justo tras el BringToFront haces PanelActivo:= Controls[iIndice];


Ya está, lo usas luego en el onclick o donde quieras, siempre lo tienes localizado!


Pues no se me ocurre más que si el SendToBack o el BringToFront lo haces en tiempo de ejecución, controles mediante una variable qué panel fue el último en hacer ese movimiento...


Ya somos dos que lo proponemos  8-|  (y)

Saludox ! :)
  • 0

#13 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 01 febrero 2013 - 11:44

Hola,
Yo también apoyo la idea y uso de TFrame, es una muy buena herramienta pero lamentablemente poco utilizada; y más que nada por el propio desconocimiento del desarrollador y otro tanto por cierto menospecio. Es como si fuera la tierna muchacha calladita a la que nunca la invitan al baile.  :(

La alternativa que comenta Gaby es quizá la más simple y directa de llevar a puesta. Lo de utilizar PageControl me parece una opción a considerar y no para despreciar; y me parece que jugar con los paneles a como estás encarando (y viendo en como está adquiriendo complejidad el asunto) es una práctica que a largo plazo es para más problemas que soluciones.

Recuerdo vagamente que hay una manera de detectar el nombre clase y objeto desde un Handle, e incluso también está la posibilidad de obtener la coordenada Z, que mide la "profundidad" de las ventanas. Básicamente a medida que se van mostrando ventanas o Handles para ser más precisos, el valor de Z para dicha ventana aumenta. De modo que si por ejemplo, tenemos 5 ventanas, en 0 estará la del fondo y en 4 la del frente. Si logro hacer memoria o si tengo algo en mi biblioteca sobre el tema aviso. Podría ser otra alternativa.

Saludos,
  • 0




IP.Board spam blocked by CleanTalk.