Componente XpMenu - quot;Bugquot;
Boa tarde pessoal!!!
Alguém de vcs utilizam ou ja utilizou o componente XpMenu?
Estou ultilizando ele e me apareceu um problema q não estou conseguindo solucionar.
Qdo monto uma tela e nesta tela coloco um panel e sobre o panel coloco alguns edits, ai ao abrir a tela o foco vai para o primeiro edit, defini isso no ActiveControl, o problema ocorre c tenho algum evento programado no evento OnExit deste edit q recebe o foco inicial, assim q abre a tela ele aciona o evento OnExit, abre a tela e posiciona o cursor nesse edit porem qdo saio, ai q era pra realmente acionar o evento OnExit não aciona.
Alguém ja passou por isso?
Saberia me dizer como solucionar?
Desde ja agradeço a todos.
[]´s
Renato
Alguém de vcs utilizam ou ja utilizou o componente XpMenu?
Estou ultilizando ele e me apareceu um problema q não estou conseguindo solucionar.
Qdo monto uma tela e nesta tela coloco um panel e sobre o panel coloco alguns edits, ai ao abrir a tela o foco vai para o primeiro edit, defini isso no ActiveControl, o problema ocorre c tenho algum evento programado no evento OnExit deste edit q recebe o foco inicial, assim q abre a tela ele aciona o evento OnExit, abre a tela e posiciona o cursor nesse edit porem qdo saio, ai q era pra realmente acionar o evento OnExit não aciona.
Alguém ja passou por isso?
Saberia me dizer como solucionar?
Desde ja agradeço a todos.
[]´s
Renato
Renato.pavan
Curtidas 0
Respostas
Renato.pavan
02/03/2006
Up...
GOSTEI 0
Paullsoftware
02/03/2006
até onde eu sei, quando vc acdiona um menu ele não tira o focu do componente, tipo: ´Não será executado os comandos do OnExit de nenhum componente´..
o texto abaixo peguei num site a um tempo quando tive um problema semelhante! :lol:
[b:7b012187ed]Cuidados ao usar o OnExit:[/b:7b012187ed]
É 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;
Com isso você força a saída de qualquer Edit ou outro componente que esteja com o foco, gerando assim o evento OnExit.
Dando continuidade aos problemas enfrentados quando se usa o evento OnExit, vamos ver outro caso onde pode acontecer um pequeno problema:
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.
.....
procure verificar se o XpMenu recebe o foco, pois, senão receber o evento OnExit não esta sendo chamando! :wink:
o texto abaixo peguei num site a um tempo quando tive um problema semelhante! :lol:
[b:7b012187ed]Cuidados ao usar o OnExit:[/b:7b012187ed]
É 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;
Com isso você força a saída de qualquer Edit ou outro componente que esteja com o foco, gerando assim o evento OnExit.
Dando continuidade aos problemas enfrentados quando se usa o evento OnExit, vamos ver outro caso onde pode acontecer um pequeno problema:
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.
.....
procure verificar se o XpMenu recebe o foco, pois, senão receber o evento OnExit não esta sendo chamando! :wink:
GOSTEI 0
Renato.pavan
02/03/2006
Bom dia!!!
Resolvi o problema colocando na propriedade ActiveControl do form o Panel1 e no evento OnActivate coloquei o codigo:
Estava fazendo desta forma mas colocando o codigo no evento OnShow ai exibia a mensagem do OnExit do edit antes de aparecer o form na tela e qdo o form aparecia o foco se perdia, tentei no OnCreate tambem só q tava dando a mensagem de erro ´Cannot focus a disabled or invisible window´.
Resolvi o problema colocando na propriedade ActiveControl do form o Panel1 e no evento OnActivate coloquei o codigo:
Edit1.SetFocus
Estava fazendo desta forma mas colocando o codigo no evento OnShow ai exibia a mensagem do OnExit do edit antes de aparecer o form na tela e qdo o form aparecia o foco se perdia, tentei no OnCreate tambem só q tava dando a mensagem de erro ´Cannot focus a disabled or invisible window´.
GOSTEI 0