Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 19-12-2005
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 21
gluglu Va por buen camino
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 !
__________________
Piensa siempre en positivo !
Responder Con Cita
  #2  
Antiguo 19-12-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
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
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #3  
Antiguo 19-12-2005
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 21
gluglu Va por buen camino
Perfecto !! ... muchas gracias.
__________________
Piensa siempre en positivo !
Responder Con Cita
  #4  
Antiguo 19-12-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
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.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #5  
Antiguo 19-12-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
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?

// Saludos
Responder Con Cita
  #6  
Antiguo 19-12-2005
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Solo para molestar un poco:
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!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #7  
Antiguo 19-12-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
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.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #8  
Antiguo 19-12-2005
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 23
maeyanes Va por buen camino
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...

Última edición por maeyanes fecha: 19-12-2005 a las 19:41:05.
Responder Con Cita
  #9  
Antiguo 19-12-2005
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
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?
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

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

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #10  
Antiguo 20-12-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
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 .

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.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #11  
Antiguo 20-12-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
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.

// Saludos
Responder Con Cita
  #12  
Antiguo 20-12-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
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.

// Saludos
Pues si

saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
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 15:15:23.


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