
¿Cómo saber si un TPanel está al frente o atrás?
#1
Posted 29 January 2013 - 02:15 PM
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...
#2
Posted 29 January 2013 - 05:16 PM
Saludox !

#3
Posted 30 January 2013 - 04:18 AM
#4
Posted 30 January 2013 - 08:38 AM
...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:
procedure TMiForma.EvaluaPanel(iNumero: Integer); var sNombrePanel: string; iIndice: Integer; begin sNombrePanel := 'pnlCap'+Trim(IntToStr(iNumero+1)); with pnlCaptura do begin for iIndice := 0 to ControlCount-1 do begin if LeftStr((Controls[iIndice] as TPanel).Name,6) = 'pnlCap' then begin if (Controls[iIndice] as TPanel).Name <> sNombrePanel then begin with (Controls[iIndice] as TPanel) do begin SendToBack; Height := 40; Width := 185; Visible := False; end; end else begin with (Controls[iIndice] as TPanel) do begin BringToFront; Visible := True; Width := pnlCaptura.ClientWidth -1; Height := pnlCaptura.ClientHeight -1; Align := alClient; Tag := iNumero+1; end; pnlCapturaResize(Self); end; end; end; end; end;
Y en algún otro evento de mi código, realizo ésta evaluación:
if (pnlCap1.Align = alClient) then begin if Trim(redtMotivoConsulta.Text) > '' then PalomeaNavegador; 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...
#5
Posted 30 January 2013 - 08:43 AM
......... 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
#6
Posted 30 January 2013 - 11:15 AM
Nos leemos
#7
Posted 30 January 2013 - 12:19 PM
...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.
#8
Posted 30 January 2013 - 12:24 PM
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
#9
Posted 30 January 2013 - 05:13 PM
Podrías crear una función que te devuelva el nombre del panel
function TForm1.PanelVisible: TPanel; var k: integer; begin for k := 0 to self.ControlCount - 1 do if self.Controls[k].ClassType = TPanel then if (self.Controls[k] as TPanel).Visible then begin result := self.Controls[k] as TPanel; break; end; 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:
if (Controls[iIndice] as TPanel).Name <> sNombrePanel then begin with (Controls[iIndice] as TPanel) do begin SendToBack; //sobra Height := 40; //sobra Width := 185; //sobra Visible := False; end;
Saludos
#10
Posted 31 January 2013 - 01:57 AM
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
#11
Posted 01 February 2013 - 09:39 AM
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):
MyControl:= pnlCaptura.ControlAtPos( pnlCaptura.Width div 2, pnlCaptura.Height div 2); while not (MyControl is TPanel) and Assigned(MyControl) do MyControl:= MyControl.parent; if Assigned(MyControl) then MyPanel:= TPanel(MyControl) else 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!
#12
Posted 01 February 2013 - 09:59 AM
......
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


Saludox !

#13
Posted 01 February 2013 - 11:44 AM
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,