Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Propiedad FocusControl (https://www.clubdelphi.com/foros/showthread.php?t=28415)

gluglu 19-12-2005 15:13:09

Propiedad FocusControl
 
Hola Amigos !

Se puede hacer algo así ?
Código Delphi [-]
procedure TForm.LabelClick(Sender: TObject);
begin
  Sender.FocusControl.SetFocus;
end;
utilizando la propiedad FocusControl del TLabel (o si fuera necesario TStaticText).

No sé en otras versiones de Delphi, pero en D2005 la propiedad FocusControl es 'protegida'.

Un saludo a todos !

jachguate 19-12-2005 16:26:12

La propiedad FocusControl de un TLabel no puede ser protegida, puesto que aparece en el inspector de objetos, por lo tanto es publicada (published).

Lo que ocurre es que no estás moldeando el Sender como un TLabel, y dudo mucho que un TObject tenga propiedad FocusControl (ni protegida ni nada).

Lo que corresponde hacer, ya que sabes que dicho sender es un TLabel, es aplicar un molde a este. Yo aconsejo aplicar un moldeo seguro siempre que sea posible (usando el operador as para prevenir problemas de acceso a memoria con moldes inadecuados en el futuro.

Código Delphi [-]
procedure TForm.LabelClick(Sender: TObject);
begin
  (Sender as TLabel).FocusControl.SetFocus;
end;

Saludos

gluglu 19-12-2005 17:34:37

Perfecto !! ... muchas gracias.

Lepe 19-12-2005 18:28:00

Cita:

Empezado por jachguate
(usando el operador as para prevenir problemas de acceso a memoria con moldes inadecuados en el futuro.

Cuando lo has dicho explicitamente, tus razones tendrás, y si es posible, me gustaría conocerlas.

Yo suelo usar:
Código Delphi [-]
    TLabel(Sender).Caption

saludos.

roman 19-12-2005 18:41:19

A reserva de lo que diga Juan Antonio, te doy mi opinión.

Usar TLabel(Sender) es una apuesta a la consistencia de tu código. Estás confiando ciegamente en que Sender es de tipo TLabel y lo será no importa cuántos cambios hagas en lo futuro a tu código.

Es más confiable protegerse uno mismo y verificar que el tipo de datos es realmente el esperado:

Código Delphi [-]
if Sender is TLabel then
  TLabel(Sender).Blablabla;

La forma que usa Juan Antonio, usando el operador as, también te protege ya que implícitamente, as comprueba el tipo de datos y si no coincide lanza una excepción.

¿Por qué protegerse? Bueno, razones puede haber muchas, pero yo lo veo similar a hacer:

Código:

puntero^.campo := valor
así sin más. La lógica de tu codigo te puede decir que siempre que llegues a esa asignación, puntero será distinto de nil así que no hay que comprobarlo previamente, pero, ¿dormirás tranquilo? :D

// Saludos

delphi.com.ar 19-12-2005 18:44:10

Solo para molestar un poco: :p
Código Delphi [-]
procedure TForm.LabelClick(Sender: TObject);
begin
  if Sender is TLabel then
    with Sender as TLabel do
      if Assigned(FocusControl) and FocusControl.CanFocus then
        FocusControl.SetFocus;
end;

Saludos!

jachguate 19-12-2005 19:27:20

Ya Roman ha explicado muy bien el porque usar el operador as/is en estos casos (recordá que el método Label1Click podrías asignarlo a componentes de diferentes clases en tiempo de ejecución, e incluso invocarlo desde código. Que pasa si a un futuro programador que está dando mantenimiento a tu código se le ocurre hacer esto:

Código Delphi [-]
  Label1Click(Button1);  //comportamiento aleatorio, pero seguramente erroneo
  Label1Click(nil); //EAccessViolation!

Solo para terminar de molestar un poco... he podido comprobar que el método CanFocus puede decirnos true, y de todas formas ocurrir un error al intentar establecer el foco, así que para terminar de "molestar" en terminos de Fede:

Código Delphi [-]
procedure TForm.LabelClick(Sender: TObject);
begin
  if assigned(Sender) and (Sender is TLabel) then
    with Sender as TLabel do
      if Assigned(FocusControl) and FocusControl.CanFocus then
        try
          FocusControl.SetFocus;
        except
          on EInvalidOp do
            ;  //no hacemos nada!
        end;
end;

Hasta luego.

;)

maeyanes 19-12-2005 19:34:10

Yo haría este pequeño cambio:

Código Delphi [-]
procedure TForm.LabelClick(Sender: TObject);
begin
  if assigned(Sender) and (Sender is TLabel) then
    with TLabel(Sender) do
      if Assigned(FocusControl) and FocusControl.CanFocus then
        try
          FocusControl.SetFocus;
        except
          on EInvalidOp do
            ;  //no hacemos nada!
        end;
end;
Ya que al hacer una comprobación previa con el operador is, al usar as se estaría haciendo de nuevo una comprobación is. Recuerden lo que puso roman:

Cita:

Empezado por roman
La forma que usa Juan Antonio, usando el operador as, también te protege ya que implícitamente, as comprueba el tipo de datos y si no coincide lanza una excepción.




Saludos...

delphi.com.ar 19-12-2005 22:01:04

Cita:

Empezado por jachguate
Ya Roman ha explicado muy bien el porque usar el operador as/is en estos casos (recordá que el método Label1Click podrías asignarlo a componentes de diferentes clases en tiempo de ejecución, e incluso invocarlo desde código. Que pasa si a un futuro programador que está dando mantenimiento a tu código se le ocurre hacer esto:

Código Delphi [-]
  Label1Click(Button1);  //comportamiento aleatorio, pero seguramente erroneo
  Label1Click(nil); //EAccessViolation!

El comparador is retornará False si el objeto es nil ;)... No se producirá un Access Violation!


Cita:

Empezado por jachguate
Solo para terminar de molestar un poco... he podido comprobar que el método CanFocus puede decirnos true, y de todas formas ocurrir un error al intentar establecer el foco, así que para terminar de "molestar" en terminos de Fede:

¿Y porque ocultar el error si tenemos un problema? :D
Lo he visto en mas de una ocasión, nunca me lo puse a investigar, pero la solución del momento no distó en nada de la tuya :D

Cita:

Empezado por maeyanes
Ya que al hacer una comprobación previa con el operador is, al usar as se estaría haciendo de nuevo una comprobación is...

No te entiendo, de todos modos tienes que hacer el cast :confused:

Saludos!

Lepe 20-12-2005 18:16:25

Cita:

Empezado por jachguate
Ya Roman ha explicado muy bien el porque usar el operador as/is en estos casos (recordá que el método Label1Click podrías asignarlo a componentes de diferentes clases en tiempo de ejecución, e incluso invocarlo desde código. Que pasa si a un futuro programador que está dando mantenimiento a tu código se le ocurre hacer esto:

Código Delphi [-]
  Label1Click(Button1);  //comportamiento aleatorio, pero seguramente erroneo
  Label1Click(nil); //EAccessViolation!

Pues pasa, que ese programador es un "soso" por decir algo :D.

Que conste, que realizo ese tipo de comprobaciones, y en este caso estoy con Maeyanes.

No estoy seguro, pero creo haber leido en este foro, que el operador "as" sobrecarga más la situación. Desde mi punto de vista, creo que bastaría con:
Código Delphi [-]
  if (Sender is Tlabel) then
    TLabel(Sender).blah
Una vez que estoy seguro que es un TLabel, accedo directamente haciendo el moldeo. Repito, es mi forma de trabajar, y ahora que ahondo en el problema, quizás fuese mejor simplemente:
Código Delphi [-]
    (Sender as Tlabel).blah
Ya que lanza una Excepción (que se verá en ejecución), desde mi forma de programar, simplemente notaré que "el programa no hace lo que debiera" (porque no entrará en el if si no es un TLabel), y tendría que hacer un traceo paso a paso hasta encontrar ese pequeño error. De la segunda forma, si el "soso" es muy soso, verá la excepción. No creo que tenga que arreglar los futuros problemas con mi código ;).

saludos

Saludos.

roman 20-12-2005 18:24:47

Cita:

Empezado por Lepe
Que conste, que realizo ese tipo de comprobaciones, y en este caso estoy con Maeyanes.

Claro, consta ahora, pero el punto es que en tu primer mensaje no decías nada acerca de la comprobación, sólo mencionaste el moldeo. :p

// Saludos

Lepe 20-12-2005 18:36:20

Cita:

Empezado por roman
Claro, consta ahora, pero el punto es que en tu primer mensaje no decías nada acerca de la comprobación, sólo mencionaste el moldeo. :p

// Saludos

Pues si :o :o :o

saludos


La franja horaria es GMT +2. Ahora son las 19:53:47.

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