Fórum Função q muda a cor quando muda o foco (p/ toda a aplicacao) #309162
14/01/2006
0
Estou tentando fazer uma função que mude a cor de fundo dos componentes quand eles recebem o foco, mas queria fazer uma vez para usar em toda a aplicação?
Outra dúvida é como tratar a mudancao de foco pelo application Events, usando as mensagens do windows. Tem como saber quais os tipos de mensagem existentes?
Daniel_mc
Curtir tópico
+ 0Posts
14/01/2006
Edilcimar
Gostei + 0
16/01/2006
Emerson Nascimento
não esqueça de atribuir um Screen.OnActiveControlChange := nil ao fechar a aplicação.
Gostei + 0
16/01/2006
Rafael Gomes
[]s
Gostei + 0
17/01/2006
Emerson Nascimento
aí vai um exemplo bem completo ilustrando o uso do evento OnActiveControlChange (coloque alguns componentes no form e veja o resultado):
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls, CheckLst, Mask, Grids;
type
TMeuComponente = class(TControl)
public
property Color;
end;
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Button1: TButton;
CheckBox1: TCheckBox;
Panel1: TPanel;
ListBox1: TListBox;
ComboBox1: TComboBox;
StringGrid1: TStringGrid;
MaskEdit1: TMaskEdit;
CheckListBox1: TCheckListBox;
TreeView1: TTreeView;
procedure FormCreate(Sender: TObject);
procedure FocoAlterado(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
Componente: TWinControl;
public
{ Public declarations }
end;
const
CorSemFoco = clWindow;
CorComFoco = clTeal;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FocoAlterado(Sender: TObject);
begin
if Componente <> nil then
TMeuComponente(Componente).Color := CorSemFoco;
if ActiveControl is TWinControl then
try
TMeuComponente(ActiveControl).Color := CorComFoco;
Componente := ActiveControl;
except
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.OnActiveControlChange := FocoAlterado;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Screen.OnActiveControlChange := nil;
end;
end.Gostei + 0
17/01/2006
Marco Salles
Mas eu acho que do jeito que esta declarado , se voce estiver em uma aplicação com mais de um formulário , voce tera um erro de acesso a mémoria ao chamar o segundo formulário por exemplo
P:S
No caso de Form que são declarados em [b:3dfec8cfc6]Available Forms [/b:3dfec8cfc6]no Projectos
Se o segundo form for declado No Auto Create Forms , não havera este erro , porem pelos teste s que eu fiz o código não funciona.. Teria talvez que rescreve-lo para cada formulário secundário...
Tem condiçoes de contornar isto :?: :?: :?: :?:
Muito obrigado e parabens...
Gostei + 0
17/01/2006
Titanius
Mas eu acho que do jeito que esta declarado , se voce estiver em uma aplicação com mais de um formulário , voce tera um erro de acesso a mémoria ao chamar o segundo formulário por exemplo
P:S
No caso de Form que são declarados em [b:29ccfdc0b1]Available Forms [/b:29ccfdc0b1]no Projectos
Se o segundo form for declado No Auto Create Forms , não havera este erro , porem pelos teste s que eu fiz o código não funciona.. Teria talvez que rescreve-lo para cada formulário secundário...
Tem condiçoes de contornar isto :?: :?: :?: :?:
Muito obrigado e parabens...[/quote:29ccfdc0b1]
Tenho uma parecida, que funciona com Forms MDI, talvez solucione o problema, e se alguem quiser melhorar, fique a vontade...
Type TControlAtivo = class(TControl); procedure TFrmPrincipal.ColorControl(Sender: TObject); var i, p, t, pp: integer; Panel_Ativo: TPanel; Page_Ativo: TPageControl; TabSheet_Ativo: TTabSheet; begin if (Screen.FormCount > 0) and (Screen.ActiveForm <> nil) then begin for i := 0 to Screen.ActiveForm.ControlCount - 1 do begin Application.ProcessMessages; if (Screen.ActiveForm.Components[i] is TDBEdit) then begin if not ((Screen.ActiveForm.Components[i] as TDBEdit).Enabled) then // ou use sem o not begin (Screen.ActiveForm.Components[i] as TDBEdit).Color := clBtnFace; (Screen.ActiveForm.Components[i] as TDBEdit).Font.Color := clBlack; end; end; if (Screen.ActiveForm.Components[i] is TEdit) then begin if not ((Screen.ActiveForm.Components[i] as TEdit).Enabled) then // ou use sem o not begin (Screen.ActiveForm.Components[i] as TEdit).Color := clBtnFace; (Screen.ActiveForm.Components[i] as TEdit).Font.Color := clBlack; end; end; //Verificar Tag 1 (Preenchimento Obrigatório) if ((Screen.ActiveForm.Controls[i]).Tag <> 2) and ((Screen.ActiveForm.Controls[i]).Tag <> -1) then begin // Somente Fora do Panel e sem alterar o DbGrid if (Screen.ActiveForm.Controls[i] is TWinControl) and not (Screen.ActiveForm.Controls[i] is TPanel) and not (Screen.ActiveForm.Controls[i] is TDbGrid) and not (Screen.ActiveForm.Controls[i] is TDbRadioGroup) and not (Screen.ActiveForm.Controls[i] is TRadioGroup) and not (Screen.ActiveForm.Controls[i] is TTabbedNotebook) and not (Screen.ActiveForm.Controls[i] is TToolBar) and not (Screen.ActiveForm.Controls[i] is TJvSpeedBar) and not (Screen.ActiveForm.Controls[i] is TStatusBar) and not (Screen.ActiveForm.Controls[i] is TGroupBox) and not (Screen.ActiveForm.Controls[i] is TPageControl) and not (Screen.ActiveForm.Controls[i] is TwwDBGrid) then begin if (Screen.ActiveForm.Controls[i] as TWinControl).Focused then TControlAtivo(Screen.ActiveForm.Controls[i]).Color := StringToColor(´$00F0FFFF´) else TControlAtivo(Screen.ActiveForm.Controls[i]).Color := clWindow; end; // Somente Dentro do Panel e sem alterar o DbGrid if (Screen.ActiveForm.Controls[i] is TWinControl) and (Screen.ActiveForm.Controls[i] is TPanel) then begin Panel_Ativo := Screen.ActiveForm.Controls[i] as TPanel; for p := 0 to Panel_Ativo.ControlCount - 1 do begin if ((Panel_Ativo.Controls[p]).Tag <> 2) and ((Panel_Ativo.Controls[p]).Tag <> -1) then begin if (Panel_Ativo.Controls[p] is TWinControl) and not (Panel_Ativo.Controls[p] is TDbGrid) and not (Panel_Ativo.Controls[p] is TDbRadioGroup) and not (Screen.ActiveForm.Controls[i] is TToolBar) and not (Screen.ActiveForm.Controls[i] is TJvSpeedBar) and not (Screen.ActiveForm.Controls[i] is TRadioGroup) then begin if (Panel_Ativo.Controls[p] as TWinControl).Focused then TControlAtivo(Panel_Ativo.Controls[p]).Color := StringToColor(´$00F0FFFF´) else TControlAtivo(Panel_Ativo.Controls[p]).Color := clWindow; end; end; end; end; // Somente Dentro do PageControl e sem alterar o DbGrid if (Screen.ActiveForm.Controls[i] is TWinControl) and (Screen.ActiveForm.Controls[i] is TPageControl) then begin Page_Ativo := Screen.ActiveForm.Controls[i] as TPageControl; for p := 0 to Page_Ativo.ControlCount - 1 do begin Application.ProcessMessages; if (Page_Ativo.Controls[p] is TTabSheet) then begin TabSheet_Ativo := Page_Ativo.Controls[p] as TTabSheet; for t := 0 to TabSheet_Ativo.ControlCount - 1 do begin Application.ProcessMessages; if ((TabSheet_Ativo.Controls[t]).Tag <> 2) and ((TabSheet_Ativo.Controls[t]).Tag <> -1) then begin if (TabSheet_Ativo.Controls[t] is TWinControl) and not (TabSheet_Ativo.Controls[t] is TPanel) and not (TabSheet_Ativo.Controls[t] is TDbGrid) and not (Screen.ActiveForm.Controls[i] is TwwDBGrid) then begin if ((TabSheet_Ativo.Controls[t] as TWinControl).Focused) and ((TabSheet_Ativo.Controls[t] as TWinControl).Tag = -1) then TControlAtivo(TabSheet_Ativo.Controls[t]).Color := clWindow else TControlAtivo(TabSheet_Ativo.Controls[t]).Color := StringToColor(´$00F0FFFF´); end; end; if (TabSheet_Ativo.Controls[t] is TPanel) then begin Panel_Ativo := TabSheet_Ativo.Controls[t] as TPanel; for pp := 0 to Panel_Ativo.ControlCount - 1 do begin Application.ProcessMessages; if ((Panel_Ativo.Controls[pp]).Tag <> 2) and ((Panel_Ativo.Controls[pp]).Tag <> -1) then begin if (Panel_Ativo.Controls[pp] is TWinControl) then begin if (Panel_Ativo.Controls[pp] as TWinControl).Focused then TControlAtivo(Panel_Ativo.Controls[pp]).Color := StringToColor(´$00F0FFFF´) else TControlAtivo(Panel_Ativo.Controls[pp]).Color := clWindow; end; end; end; end; end; end; end; end; end; end; end; end; procedure TFrmPrincipal.FormActivate(Sender: TObject); begin Screen.OnActiveControlChange := ColorControl; end;
Ele verifica o Tag, se o Tag for maior que 2 ele nao pinta...
[]s
Gostei + 0
17/01/2006
Marco Salles
Em outras palavras gostaria de entender porque se tem um erro de acesso Violado na situação onde : :arrow: :arrow: :arrow: :arrow:
teria como definir emerson.en esta procedure [b:7c05416611]FocoAlterado[/b:7c05416611] no form Principal para que ela pude-sse ser vista ao longo de todo o aplicativo , sem te-la que reescreve-la nos formularios subjacentes.
[b:7c05416611]Note que não estou falando de form MDI como colocou o Titanius[/b:7c05416611]
Gostei + 0
17/01/2006
Emerson Nascimento
a diferença está na procedure FocoAlterado. onde antes era ActiveControl, agora é Screen.ActiveForm.ActiveControl.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls, CheckLst, Mask, Grids;
type
TMeuComponente = class(TControl)
public
property Color;
end;
TForm1 = class(TForm)
Edit1: TEdit;
Memo1: TMemo;
CheckBox1: TCheckBox;
ComboBox1: TComboBox;
RadioButton1: TRadioButton;
MaskEdit1: TMaskEdit;
RichEdit1: TRichEdit;
Button1: TButton;
procedure FocoAlterado(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
CorSemFoco = clWindow;
CorComFoco = clTeal;
var
Form1: TForm1;
Componente: TWinControl;
implementation
uses unit2;
{$R *.dfm}
procedure TForm1.FocoAlterado(Sender: TObject);
begin
if Componente <> nil then
try
TMeuComponente(Componente).Color := CorSemFoco;
except
end;
if Screen.ActiveForm.ActiveControl is TWinControl then
try
TMeuComponente(Screen.ActiveForm.ActiveControl).Color := CorComFoco;
Componente := Screen.ActiveForm.ActiveControl;
except
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.OnActiveControlChange := FocoAlterado;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Screen.OnActiveControlChange := nil;
end;
end.Gostei + 0
17/01/2006
Emerson Nascimento
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls, CheckLst, Mask, Grids;
type
TMeuComponente = class(TControl)
public
property Color;
end;
TForm1 = class(TForm)
Edit1: TEdit;
Memo1: TMemo;
CheckBox1: TCheckBox;
ComboBox1: TComboBox;
RadioButton1: TRadioButton;
MaskEdit1: TMaskEdit;
RichEdit1: TRichEdit;
Button1: TButton;
procedure FocoAlterado(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
Componente: TWinControl;
CorAnterior: TColor;
public
{ Public declarations }
end;
const
CorSemFoco = clWindow;
CorComFoco = clBlue;
var
Form1: TForm1;
implementation
uses unit2;
{$R *.dfm}
procedure TForm1.FocoAlterado(Sender: TObject);
begin
if Componente <> nil then
try
// TMeuComponente(Componente).Color := CorSemFoco;
TMeuComponente(Componente).Color := CorAnterior;
except
end;
if Screen.ActiveForm.ActiveControl is TWinControl then
try
CorAnterior := TMeuComponente(Screen.ActiveForm.ActiveControl).Color;
TMeuComponente(Screen.ActiveForm.ActiveControl).Color := CorComFoco;
Componente := Screen.ActiveForm.ActiveControl;
except
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Screen.OnActiveControlChange := nil;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.CreateForm(TForm2,Form2);
Form2.Show;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.OnActiveControlChange := FocoAlterado;
end;
end.Gostei + 0
17/01/2006
Rafael Mattos
E depois eu uso a procedure ColorControl no Formulario Principal.
Gostei + 0
17/01/2006
Marco Salles
Eu rasgo esse elogio porque acho que o minimo que a gente pode fazer quando alguem se compromete cordialmente a responder algumas questoes...So resta agradecer... Muito obrigado.
Mas deixa eu explicar melhor.. O Erro de acesso violado que obtive , foi porque ao colocar o Form2 Na secção Avalaible Forms eu tentei dar um ShowModal sem criar o Formulário... Descuido meu e peço desculpas :oops: :oops: :oops: :oops: :oops:
ActiveControl se refere ao Formulario e Screen.ActiveForm.ActiveControl se refere ao objeto global application . Com isto realmente temos um método para todos os formulários secundários..
Valeu...
Gostei + 0
20/01/2006
Daniel_mc
Gostei + 0
27/01/2006
Daniel_mc
Iniciei o programa e abri a tela de cadastro de clientes por exemplo e a função ta funcionando direitinho, mas quando eu fecho o form e abro de novo, a função já não funciona mais.
E se eu tentar colocar na onCreate do Form de Clientes a chamada:
procedure T_CadClientes.FormCreate(Sender: TObject); begin Screen.OnActiveControlChange := _Login.FocoAlterado; end;
e no onClose:
procedure T_CadClientes.FormClose(Sender: TObject; var Action: TCloseAction); begin Screen.OnActiveControlChange := nil; end;
Gostei + 0
28/01/2006
Daniel_mc
Quando o form era destruido so era atribuido [b:05f0419e8e]nil[/b:05f0419e8e] ao [b:05f0419e8e]Screen.OnActiveControlChange[/b:05f0419e8e]. O problema é que...
private
{ Private declarations }
Componente: TWinControl;o ´Componete´ criado na seão private continuava apontando para o ultimo controle do form
Componente := Screen.ActiveForm.ActiveControl;
ai quando eu reabria o form o ´Componente´ estava apontando para um endereço perdido.
o que eu fiz foi:
procedure TForm1.destroi; begin Screen.OnActiveControlChange := nil; componente:=nil; end;
criei este metodo que atribui [b:05f0419e8e]nil[/b:05f0419e8e] ao ´Componente´ e ao inves de usar no onDestroy o:
Screen.OnActiveControlChange := nil;
eu uso
destroi;
Agradeco a atencao de todos que responderam este tópico.
Gostei + 0
10/03/2006
Titanius
Aqui está dando erro de memoria... já tentei fazer o q o amigo fez e nada... alguem sabe o q pode ser?
[]s
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)