É comum fazermos uso do evento OnExit quando  queremos validar o conteúdo de um Edit. E essa pode ser uma boa prática quando  necessitamos verificar o que foi digitado apenas quando o usuário terminar de  fazer a entrada de dados, como, por exemplo, um Edit que vai receber o CPF ou  CNPJ.
Ao colocarmos um código qualquer no evento  OnExit ele sempre será executado quando o usuário sair do Edit, o que acontece  quando ele pressiona a tecla TAB, clica com o mouse em um outro Edit ou  pressiona um botão OK, por exemplo.
No entanto, existem algumas situações especiais  em que o evento OnExit não é gerado. Quer um exemplo? Você está no Edit e, ao  invés de clicar no botão OK, você pressiona as teclas ALT + O (considerando que  o botão OK tem a tecla O como atalho). É como se você tivesse pressionado o  botão OK, porém, sem perder o foco que está no Edit. Só mais um exemplo: Os  botões do tipo SpeedButton não recebem foco, então, mesmo que clique com o mouse  sobre um SpeedButton, o foco continuará no Edit e, conseqüentemente, o evento  OnExit não será gerado.
E a solução?
A solução para esse pequeno inconveniente é  simples. Basta você colocar o seguinte código no evento OnClick do  botão.
procedure TForm1.Button1Click(Sender:  TObject);
begin
ActiveControl := nil;
...
end;
Suponhamos que você possua 2 Edits em um  formulário. Supondo também que você queira dar alguma informação ao usuário da  aplicação logo depois que ele sair do Edit1 você faz:
procedure TForm1.Edit1Exit(Sender:  TObject);
begin
MessageDlg('Mensagem...', mtInformation, [mbOk],  0);
end;
A princípio está tudo ok, ou melhor, parece  estar tudo ok.
Se você altera o foco para o outro Edit através  do pressionamento da tecla TAB, tudo bem. Mas experimente alterar o foco  clicando com o mouse sobre o Edit2. Neste segundo caso a mensagem será exibida  normalmente. Mas ao fechar o dialogo onde aparece a mensagem, o foco  simplesmente se perde. Para setar o foco no Edit2 é necessário clicar novamente  sobre ele.
Isso poderia não problema nenhum até que seu  usuário experimente esta situação. Nada que ele digitar será acatado.
Mas existe uma maneira fácil de resolver o  problema. Basta você cancelar o foco e forçar uma reentrada no componente Edit2.  Como fazer isso? Veja o código:
procedure TForm1.Edit1Exit(Sender:  TObject);
begin
MessageDlg('Mensagem...', mtInformation, [mbOk],  0);
// cancela o foco e força novamente a  entrada
ActiveControl := nil;
PostMessage(Edit2.Handle, WM_SETFOCUS, 0,  0);
Edit2.SetFocus;
end;
Porém, você nunca terá certeza se o usuário  clicou foi no Edit2. Então temos que criar uma rotina genérica que leva o foco  para qualquer outro controle:
procedure TForm1.Edit1Exit(Sender:  TObject);
var
Ctrl: TWinControl;
begin
MessageDlg('Mensagem...', mtInformation, [mbOk],  0);
// cancela o foco e força novamente a  entrada
Ctrl := ActiveControl;
ActiveControl := nil;
PostMessage(TWinControl(Ctrl).Handle,  WM_SETFOCUS, 0, 0);
TWinControl(Ctrl).SetFocus;
end;
Observe que antes de cancelar o foco com  ActiveControl := nil, salvamos qual é o controle que detém o foco fazendo Ctrl  := ActiveControl.
Depois enviamos uma mensagem ao controle que  detinha o foco, forçando-o a receber o foco novamente.
Nenhum comentário:
Postar um comentário