Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-11-2006
Avatar de pborges36
pborges36 pborges36 is offline
Miembro
 
Registrado: oct 2004
Ubicación: Argentina
Posts: 192
Poder: 20
pborges36 Va por buen camino
Detectar evento cambio de foco

Hola a todos. Necesito una guia. Quiero hacer un componente que al soltarlo sobre el form, me tome todos los componentes del form y que el mismo componente cambie de color a los otros componentes al cambiar el foco. La cosa es que ya pude tomar todos los componentes, y tambien se como cambiarle el color a los componentes. Ahora bien, como hago para saber que hubo un cambio de foco entre componentes? Habra algun evento del form?.
Responder Con Cita
  #2  
Antiguo 07-11-2006
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
No acabo de ver en TForm ningun evento que puedas utilizar para eso.
Seguramente si utilizaras un derivado de éste (TForm) podrías capturar algun mensaje o sobreescribir algun procedimiento.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 10-11-2006
Avatar de pborges36
pborges36 pborges36 is offline
Miembro
 
Registrado: oct 2004
Ubicación: Argentina
Posts: 192
Poder: 20
pborges36 Va por buen camino
Gracias Neftali, sigo buscando y nada todavia, por el momento cada componente cambia el color a si mismo cuando recibe o pierde el foco. Pero creo que lo ideal seria un solo componente que administre todo eso. En fin, seguire buscando. Saludos.
Responder Con Cita
  #4  
Antiguo 10-11-2006
oscarnoe oscarnoe is offline
Miembro
 
Registrado: jul 2006
Posts: 60
Poder: 18
oscarnoe Va por buen camino
Hola pborges36,

recorde haber visto algo similar, y puede que este link te ayude, no es un componente, pero creo que te servira de guia para hacer uno:

http://delphi.about.com/od/vclusing/...ingfocused.htm

La solucion para por usar Tscreen y la RTTI.

Espero que te sea de ayuda...

Oscar Noe
__________________
No dejes camino viejo por sendero nuevo

Última edición por oscarnoe fecha: 10-11-2006 a las 20:29:35.
Responder Con Cita
  #5  
Antiguo 14-11-2006
Avatar de pborges36
pborges36 pborges36 is offline
Miembro
 
Registrado: oct 2004
Ubicación: Argentina
Posts: 192
Poder: 20
pborges36 Va por buen camino
gracias Oscrnoe, lo voy a revisar y de paso practico mi ingles que esta un poco abandonado. jeje. Cualquier novedad te aviso y Gracias de nuevo.
Responder Con Cita
  #6  
Antiguo 15-11-2006
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
oscarnoe te paso el link justo, te estaba a punto de recomendar justamente la primera opcion del articulo.

Pero en el articulo te da una exelente solucion que es justo lo que necesitas.

despues nos mostras como te quedo el componente
__________________
[Crandel]
Responder Con Cita
  #7  
Antiguo 23-11-2006
Avatar de pborges36
pborges36 pborges36 is offline
Miembro
 
Registrado: oct 2004
Ubicación: Argentina
Posts: 192
Poder: 20
pborges36 Va por buen camino
Ya esta listo!!

Hola a todos. Quiero agradecerles enormemente porque finalmente, Con la ayuda de Uds. porsupuesto, termine el componente que me propuse. Y aqui les dejo el codigo, espero su opinion, comentarios y sugerencias para que vayamos mejorandolo. Gracias.

Código Delphi [-]
unit BRGFocusAdmin;
interface
uses
  SysUtils, Classes, Graphics, StdCtrls, ComCtrls, Controls, Forms;
type
  TBRGFocusAdmin = class(TComponent)
  private
    { Private declarations }
    FColorconFoco:TColor;
    FColorsinFoco:TColor;
    FTomaFoco, FPierdeFoco, FTieneFoco:TComponent;
    procedure ScreenActiveControlChange(Sender : TObject);
  protected
    { Protected declarations }
  public
    { Public declarations }
    Procedure AplicarColor(colorf:TColor;Componente:TComponent);
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property Tag2:integer read FTag2 write FTag2;
    property TagStr:string read FTagStr write FTagStr;
    property ColorconFoco:TColor read FColorconFoco write FColorconFoco;
    property ColorsinFoco:TColor read FColorsinFoco write FColorsinFoco;    
  end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('BRG', [TBRGFocusAdmin]);
end;
destructor TBRGFocusAdmin.Destroy;
begin
    Screen.OnActiveControlChange := nil;
    inherited;
end;
procedure TBRGFocusAdmin.ScreenActiveControlChange(Sender: TObject);
begin
    if Screen.ActiveControl<>nil then
      begin
          Fpierdefoco:=FTieneFoco;
          FtieneFoco:=Screen.ActiveControl;
          if Fpierdefoco<>nil then
            self.AplicarColor(FColorsinFoco, FPierdeFoco);
          if FTieneFoco<>nil then
            self.AplicarColor(FColorconFoco, FTieneFoco);
      end;
end;
constructor TBRGFocusAdmin.Create(AOwner : TComponent);
begin
    Screen.OnActiveControlChange := ScreenActiveControlChange;
    inherited Create(AOwner);
end;
Procedure TBRGFocusAdmin.AplicarColor(colorf:TColor;Componente:TComponent);
begin
    try
      if (Componente is TEdit) then
        (Componente as TEdit).Color:=colorf;
      if (Componente is TComboBox) then
        (Componente as TComboBox).Color:=colorf;
      if (Componente is TDateTimePicker) then
        (Componente as TDateTimePicker).Color:=colorf;
      if (Componente is TMemo) then
        (Componente as TMemo).Color:=colorf;
      (Componente as TWinControl).Repaint;
    except
    end;
end;
end.

Solo tienen que soltarlo sobre su formulario principal y listo!!
Responder Con Cita
  #8  
Antiguo 23-11-2006
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
muy bien !!!

Te quedo muy bien. Aprovechando que tengo un poco de tiempo libre (mi mujer y mi hijo no estan por un dia ) te hice unos cuantos retoques, espero que no te moleste.

Agregue colores por defecto, un evento cuando se produce el cambio de foco y reescribi el metodo ScreenActiveControlChange.

Código Delphi [-]
unit BRGFocusAdmin;

interface

uses
  SysUtils, Classes, Graphics, StdCtrls, ComCtrls, Controls, Forms;

type
  TBRGFocusAdmin = class(TComponent)
  private
    { Private declarations }
    FTag: integer;
    FColorConFoco: TColor;
    FColorSinFoco: TColor;
    FPierdeFoco, FTieneFoco: TWinControl; // a partir de WinControl pueden recibir el foco
    FOnFocusChange: TNotifyEvent;
    procedure ScreenActiveControlChange(Sender: TObject);
  protected
    { Protected declarations }
  public
    { Public declarations }
    Procedure AplicarColor(Color: TColor; Componente: TWinControl);
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property Tag: integer read FTag write FTag;
    property ColorConFoco: TColor read FColorConFoco write FColorConFoco;
    property ColorSinFoco: TColor read FColorSinFoco write FColorSinFoco;
    property OnFocusChange: TNotifyEvent read FOnFocusChange write FOnFocusChange;
  end;

procedure Register;


implementation


procedure Register;
begin
  RegisterComponents('BRG', [TBRGFocusAdmin]);
end;

constructor TBRGFocusAdmin.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  Screen.OnActiveControlChange := ScreenActiveControlChange;
  FColorConFoco := clSkyBlue;
  FColorSinFoco := clWindow;
end;

destructor TBRGFocusAdmin.Destroy;
begin
  Screen.OnActiveControlChange := nil;
  inherited;
end;

procedure TBRGFocusAdmin.ScreenActiveControlChange(Sender: TObject);
begin
  FPierdeFoco := FTieneFoco;
  FTieneFoco  := Screen.ActiveControl;

  if FPierdeFoco <> nil then
    Self.AplicarColor(FColorSinFoco, FPierdeFoco);

  if FTieneFoco <> nil then
  begin
    self.AplicarColor(FColorconFoco, FTieneFoco);
    FTag := self.Tag;
  end else
    FTag := 0;

  if Assigned(FOnFocusChange) then FOnFocusChange(Self);
end;

Procedure TBRGFocusAdmin.AplicarColor(Color :TColor; Componente: TWinControl);
begin
  try
    if (Componente is TCustomEdit)     then (Componente as TEdit).Color := Color;
    if (Componente is TDateTimePicker) then (Componente as TDateTimePicker).Color:= Color;
    if (Componente is TCustomMemo)     then (Componente as TMemo).Color:= Color;
    if (Componente is TCustomComboBox) then (Componente as TComboBox).Color:= Color;

    (Componente as TWinControl).Repaint;
  except
  end;
end;

end.
__________________
[Crandel]
Responder Con Cita
  #9  
Antiguo 24-11-2006
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por pborges36
...espero su opinion, comentarios y sugerencias para que vayamos mejorandolo.
Código Delphi [-]
Procedure TBRGFocusAdmin.AplicarColor(Color :TColor; Componente: TWinControl);
begin
  try
    if (Componente is TCustomEdit)     then (Componente as TEdit).Color := Color;
    if (Componente is TDateTimePicker) then (Componente as TDateTimePicker).Color:= Color;
    if (Componente is TCustomMemo)     then (Componente as TMemo).Color:= Color;
    if (Componente is TCustomComboBox) then (Componente as TComboBox).Color:= Color;

    (Componente as TWinControl).Repaint;
  except
  end;
end;

Creo que esto se puede optimizar (para cualquier componente que tenga esa propiedad) utilizando RTTI. Lo bueno de esto es que generalizando un poco la siguiente función se puede hacer para cualquier propiedad.

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var
  i:Integer;

  //·······················································································
  // Comprueba si existe una propiedad con ese nombre
  function ExistProp(Instance: TObject; const PropName: string):Boolean;
  var
    PropInfo: PPropInfo;
  begin
    // Busca la propiedad y deviuelve la estructura nil
    PropInfo := GetPropInfo(Instance, PropName);
    Result := not (PropInfo = nil);
  end;
  //·······················································································
  // Cambia el valor de la propiedad
  function SetPropAsString(AObj: TObject; const PropName, Value: String):Boolean;
  var
    PInfo: PPropInfo;
  Begin
    // Intentamos acceder (con un puntero) a la info. de la propiedad
    PInfo := GetPropInfo(AObj.ClassInfo, PropName);
    Result := PInfo <> nil;

    // Se ha obtenido la información...
    if (Result) then begin
      // Se ha encontrado la propiedad con éste nombre; Chequear el tipo...
      if (PInfo^.Proptype^.Kind = tkString) or
         (PInfo^.Proptype^.Kind = tkLString) then begin
        // Asignar el valor de tipo String
        SetStrProp(AObj, PInfo, Value);
      end
      else if (PInfo^.Proptype^.Kind = tkInteger) then begin
        // Asignar el valor...
        if (PInfo^.PropType^.Name = 'TColor') then begin
          SetOrdProp(AObj, PInfo, StringToColor(Value));
        end
        else begin
          SetOrdProp(AObj, PInfo, StrToInt(Value));
        end;
      end
      else begin
        Result := False;
        MessageDlg('''La propiedad '' + PropName + '' no es de tipo String (o un tipo implementado)', mtWarning, [mbOK], 0);
      end;
    end
    else begin
      // No se ha encontrado la propiedad con ese nombre
      Result := False;
    end;
  end;
  //·······················································································


begin
  // recorrer los componentes
  for i := 0 to (Self.ComponentCount - 1) do begin
    // existe esa propiedad
    if ExistProp(Self.Components[i], 'Color') then begin
      // Asignar valor
      SetPropAsString(Self.Components[i], 'Color', 'clInfoBk');
    end;
  end;
end;
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #10  
Antiguo 24-11-2006
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
Cita:
Empezado por Neftali
Creo que esto se puede optimizar (para cualquier componente que tenga esa propiedad) utilizando RTTI. Lo bueno de esto es que generalizando un poco la siguiente función se puede hacer para cualquier propiedad.
Ya lo habia probado, el tema que no todos los componentes quedan lindos cuando se les cambia la propiedad color (como el TListBox).

Este es el codigo que use:
Código Delphi [-]
  if not (csDesigning in Self.ComponentState) then
    if Sender <> nil then
       if IsPublishedProp(Sender,'Color') then
         SetOrdProp(Sender,'Color', Color) ;
__________________
[Crandel]
Responder Con Cita
  #11  
Antiguo 24-11-2006
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Crandel
...no todos los componentes quedan lindos cuando se les cambia la propiedad color (como el TListBox).
¿Y que le pasa al TListBox cuando le cambias el color? ¿Queda como debe quedar no?

De todas formas creo que sería mejor programarlo así y en todos caso aplicar código espacial para las exceciones y no al revés.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #12  
Antiguo 24-11-2006
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
Cita:
Empezado por Neftali
¿Y que le pasa al TListBox cuando le cambias el color? ¿Queda como debe quedar no?
no me gusta como queda. Para ver como queda, es suficiente con poner un ListBox en un formulario y cambiar la propiedad color.

Cita:
Empezado por Neftali
De todas formas creo que sería mejor programarlo así y en todos caso aplicar código espacial para las exceciones y no al revés.
Si es cierto.
El problema del TListBox es que no se redibuja correctamente completo, solo la parte de los items.

Estuve probando recien para que se redibuje correctamente pero no logro que se redibuje el fondo.

Para que se redibuje correctamente, tengo minimar y maximizar la aplicacion. Esto quiere decir que debe existir algun metodo que me lo repinte completo, pero no lo encuentro.
__________________
[Crandel]

Última edición por Crandel fecha: 24-11-2006 a las 15:57:07.
Responder Con Cita
  #13  
Antiguo 24-11-2006
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
¿No se están complicando mucho?

A quien se quiere cambiar de color es a un TWinControl y la propiedad Color aparece desde TControl. Sólo hay que desprotegerla:

Código Delphi [-]
type THackControl = class(TWinControl);

...

procedure TBRGFocusAdmin.AplicarColor(Color :TColor; Componente: TWinControl);
begin
  THackControl(Componente).Color := Color;
  Componente.Repaint;
end;

// Saludos
Responder Con Cita
  #14  
Antiguo 24-11-2006
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
Cita:
Empezado por roman
¿No se están complicando mucho?

A quien se quiere cambiar de color es a un TWinControl y la propiedad Color aparece desde TControl. Sólo hay que desprotegerla:

Código Delphi [-]
type THackControl = class(TWinControl);
Se puede, pero no me parece buena practica hacer publica toda la clase por solo necesitar la propiedad Color. Ahora que conoci los métodos RTTI, prefiero hacerlo asi.

Igualmente sigue el problema del TListBox, que el tonto no se sabe repintar
__________________
[Crandel]
Responder Con Cita
  #15  
Antiguo 24-11-2006
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 quién dice que estás haciendo pública toda la clase?

Fuera del código de AplicarColor, nadie podrá acceder a esas propiedades.

// Saludos
Responder Con Cita
  #16  
Antiguo 25-11-2006
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
Obviamente fuera del componente no, pero dentro si, pero .... que buena idea me dio

Código Delphi [-]
THackControl(Sender).RecreateWnd;
__________________
[Crandel]
Responder Con Cita
  #17  
Antiguo 28-04-2010
Hugo Hugo is offline
Miembro
 
Registrado: may 2003
Ubicación: Córdoba (España)
Posts: 38
Poder: 0
Hugo Va por buen camino
Me da error al salir de la aplicación

Al terminar la aplicación me da error "Access Violation, read of address...", me imagino que tendré que destruir algo o intento acceder a algún objeto que ya no existe.

De todas formas, me imagino que habrá algún componente ya existente que haga esto mismo, yo tengo la Jedi VCL pero si lo hay no se localizarlo.
Responder Con Cita
  #18  
Antiguo 28-09-2010
Avatar de jafera
jafera jafera is offline
Miembro
 
Registrado: may 2007
Ubicación: Llagostera (Girona)
Posts: 582
Poder: 17
jafera Va por buen camino
Hola a todos.

Ya se que este hilo es viejo pero es el que creo que va a hacer lo que necesito, cambiar el fondo de los controles a medida que van recibiendo el foco.

He creado la unit y la he puesto en uses del form, pero no se pinta nada.

He usado el código que retocó Crandel.

Tambien probé el tema de las RTTI y funciona bien, cambia de color al recibir foco, pero al salir de un form Child, me deja una sombra negra en el form Padre.

Gracias por adelantado

Josep
Responder Con Cita
  #19  
Antiguo 28-09-2010
Avatar de pborges36
pborges36 pborges36 is offline
Miembro
 
Registrado: oct 2004
Ubicación: Argentina
Posts: 192
Poder: 20
pborges36 Va por buen camino
Holas. Lo que hice fue poner la unit que retoco crandel en un dpk y luego instalarlo. Con esto me aparece en la paleta de componentes. De ahi solo lo solte en el formulario pricipal y listo, funciona muy bien.

Saludos.
Responder Con Cita
  #20  
Antiguo 28-09-2010
Avatar de jafera
jafera jafera is offline
Miembro
 
Registrado: may 2007
Ubicación: Llagostera (Girona)
Posts: 582
Poder: 17
jafera Va por buen camino
Gracias, no lo habia entendido.

He creado y compilado el dpk, correcto; lo suelto en el for, correcto pero al hacer F9 el resultado es este:

Project xxx.exe raised exception class EInvalidCast with message 'Invalid class Typecast' Process stoped Press Step or Run to continue.

Alguna pistilla?

Josep
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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Detectar cambio de ItemIndex en ComboBox ixMike OOP 5 19-10-2006 20:39:03
F9 - cambio de foco en pestaña roman La Taberna 15 04-10-2006 08:46:03
Cambio al hacer foco con el mouse c748a OOP 14 08-08-2005 17:31:35
Detectar el cambio de un directorio NeWNeO API de Windows 2 03-01-2005 09:36:48
Capturar El Evento Del Cambio De Foco En Un Form murci API de Windows 11 21-01-2004 09:39:13


La franja horaria es GMT +2. Ahora son las 13:14:43.


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