SetFocus em Loop

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

SetFocus em Loop

Mensagem por rubens »

Olá bom dia...

Estou com um problema com o setfocus...
Tenho um fechamento de venda que quando clica no botao gravar faz uma verificação nos dados do cliente, caso seja vazio mostra uma mensagem de erro e deveria focar o nome do campo vazio. Só que quando clica no ok do msgexclamation ele volta para o msgexclamation novamente, como se tivesse pressionado enter no campo vazio.

Essa é a tela do fechamento.
Erro loop2.png
Esse é o código que faz a verificação quando pressiona o botão gravarvenda, daí ele verifica se o campo tá vazio, se tiver mostra a mensagem e vai para o campo através do setfocus. Mas aí entra em loop, como se tivesse ido para o campo vazio, pressionado enter e feito a verificação novamente. Para fechar o programa só pressionando ctrl+alt+del.

Código: Selecionar todos

*-------------------------------------------------------------------------------
STATIC FUNCTION VERVAZIO()

IF FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO NOME !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_ENDERECO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO ENDERECO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_ENDERECO.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_NUMERO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO NUMERO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_NUMERO.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_BAIRRO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO BAIRRO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_BAIRRO.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_CIDADE.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DA CIDADE !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_CIDADE.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_CEP.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO CEP !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_CEP.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_UF.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO UF !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_UF.SETFOCUS
ENDIF 

RETURN(NIL)
Código do botão gravar.

Código: Selecionar todos

	@ 465,620 BUTTONEX BTN_GRAVAR;
	  		CAPTION '&GRAVAR VENDA';
	  		PICTURE 'IMG_GRAVAR';
	  		FLAT;
	  		WIDTH 250;
	  		HEIGHT 50;
	  		FONT 'VERDANA';
	  		SIZE 16;
	  		FONTCOLOR BLUE;
	  		BOLD;
	  		BACKCOLOR {255,255,255};
	  		ACTION GRAVA_VENDA();
	  		ON GOTFOCUS VERVAZIO()
Se alguém souber como resolver ou sugerir algom agradeço...

Obrigado
Rubens
"Eu e minha casa servimos ao Senhor e você ???"
luiz antonio da silva
Usuário Nível 3
Usuário Nível 3
Mensagens: 161
Registrado em: 21 Nov 2006 22:12
Localização: serrana-sp

SetFocus em Loop

Mensagem por luiz antonio da silva »

Olá !

Tente tirar o "ON GOTFOCUS" do botão BTN_GRAVAR, o que entendi foi, "quando clicar executa e quando receber o foco executa também.."

espero que ajude.

Luiz.
HMG 3.4.4 - SQL SERVER - ORACLE
Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

SetFocus em Loop

Mensagem por rubens »

Luiz são duas ações diferentes eu acho... No On GotFocus vervazio(), quando o botão recebe o foco ele faz a verificação dos campos e quando existe uma ação no botão ele teria que executar a função grava_venda(), duas funções distintas e mesmo que estivesse executando duas vezes a rotina não ficaria em loop, me corrijam se eu estiver errado.
Bom de qualquer forma o comando FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.SETFOCUS não está executando a ação desejada que é colocar o foco no TBOX_NOME_CLIENTE. Ainda está no mesmo form, então não creio que seja direitos de acesso também. Como não sei debugar linha a linha não sei o que acontece mas achei uma forma de contornar a situação. Aproveitei a dica do Luiz e coloquei a chamada da função vervazio() no início da função grava_venda(). Usei um flag na função vervazio() que retorna verdadeiro quando os campos estão preenchidos ou falso quando está os campos estão vazios. E uma condição para dar um return caso vervazio() retorne verdadeiro.

Ficou dessa forma:

Código: Selecionar todos

STATIC FUNCTION GRAVA_VENDA()
// SE O CPF NAO E VAZIO 
IF lTEMCPF .AND. !VERVAZIO()
	RETURN NIL
ENDIF

...
...
RETURN NIL	 	
e a função vervazio() ficou assim

Código: Selecionar todos

*-------------------------------------------------------------------------------
STATIC FUNCTION VERVAZIO()
LOCAL lRETORNO := .T. 
// SE ALGUM CAMPO OBRIGATORIO ESTIVER VAZIO RETORNA FALSO
IF FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO NOME !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.SETFOCUS
	lRETORNO := .F. 
ELSEIF FORM_FECHA_VENDA.TBOX_ENDERECO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO ENDERECO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_ENDERECO.SETFOCUS
	lRETORNO := .F. 
ELSEIF FORM_FECHA_VENDA.TBOX_NUMERO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO NUMERO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_NUMERO.SETFOCUS
	lRETORNO := .F. 
ELSEIF FORM_FECHA_VENDA.TBOX_BAIRRO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO BAIRRO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_BAIRRO.SETFOCUS
	lRETORNO := .F. 
ELSEIF FORM_FECHA_VENDA.TBOX_CIDADE.VALUE='' 
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DA CIDADE !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_CIDADE.SETFOCUS
	lRETORNO := .F. 
ELSEIF FORM_FECHA_VENDA.TBOX_CEP.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO CEP !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_CEP.SETFOCUS
	lRETORNO := .F. 
ELSEIF FORM_FECHA_VENDA.TBOX_ESTADO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO UF !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_ESTADO.SETFOCUS
	lRETORNO := .F. 
ENDIF 

RETURN lRETORNO
Bom funcionou para o que preciso mas o que me intriga é o fato de que:
o comando FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.SETFOCUS deveria colocar o foco no objeto tbox;
porque houve a necessidade de um return?
Será que tem uma qtde de níveis para o FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.SETFOCUS funcionar... ?
Isso me deixa preocupado. Foi necessário tencologia gambiarrechion para funcionar uma coisa que parece ser simples...
Ou eu estou com o conceito errado do negócio... Se for isso, ufa... porque estou até gostando de programar na minigui... um visual bancana e muito rápida..

Vlw..

Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Claudio Soto
Colaborador
Colaborador
Mensagens: 568
Registrado em: 27 Ago 2012 12:31
Localização: Uruguay
Contato:

SetFocus em Loop

Mensagem por Claudio Soto »

rubens escreveu:Olá bom dia...

Estou com um problema com o setfocus...
Tenho um fechamento de venda que quando clica no botao gravar faz uma verificação nos dados do cliente, caso seja vazio mostra uma mensagem de erro e deveria focar o nome do campo vazio. Só que quando clica no ok do msgexclamation ele volta para o msgexclamation novamente, como se tivesse pressionado enter no campo vazio.

Essa é a tela do fechamento.
Erro loop2.png
Esse é o código que faz a verificação quando pressiona o botão gravarvenda, daí ele verifica se o campo tá vazio, se tiver mostra a mensagem e vai para o campo através do setfocus. Mas aí entra em loop, como se tivesse ido para o campo vazio, pressionado enter e feito a verificação novamente. Para fechar o programa só pressionando ctrl+alt+del.

Código: Selecionar todos

*-------------------------------------------------------------------------------
STATIC FUNCTION VERVAZIO()

IF FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO NOME !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_NOME_CLIENTE.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_ENDERECO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO ENDERECO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_ENDERECO.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_NUMERO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO NUMERO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_NUMERO.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_BAIRRO.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO BAIRRO !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_BAIRRO.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_CIDADE.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DA CIDADE !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_CIDADE.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_CEP.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO CEP !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_CEP.SETFOCUS
ELSEIF FORM_FECHA_VENDA.TBOX_UF.VALUE=''
	MSGEXCLAMATION( 'E OBRIGATORIO O PREENCHIMENTO DO UF !!!','ERRO')
	FORM_FECHA_VENDA.TBOX_UF.SETFOCUS
ENDIF 

RETURN(NIL)
Código do botão gravar.

Código: Selecionar todos

	@ 465,620 BUTTONEX BTN_GRAVAR;
	  		CAPTION '&GRAVAR VENDA';
	  		PICTURE 'IMG_GRAVAR';
	  		FLAT;
	  		WIDTH 250;
	  		HEIGHT 50;
	  		FONT 'VERDANA';
	  		SIZE 16;
	  		FONTCOLOR BLUE;
	  		BOLD;
	  		BACKCOLOR {255,255,255};
	  		ACTION GRAVA_VENDA();
	  		ON GOTFOCUS VERVAZIO()
Se alguém souber como resolver ou sugerir algom agradeço...

Obrigado
Rubens
Hola Rubens,
tu teoría es correcta, el problema es la implementación interna en C de los MsgXXX tanto en HMG como en MiniGUI.
Normalmente se implementan así:

HB_FUNC( C_MSGEXCLAMATION )
{
MessageBox ( GetActiveWindow() , hb_parc(1), hb_parc(2), MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL );
}

el problema es el primer parámetro de la función en C MessageBox, este parámetro es handle de la ventana a la que windows devuelve el foco cuando se cierra la caja de dialogo.

Como la funcion en C GetActiveWindow() retorna el handle de la ventana activa, que en tu ejemplo es el boton BTN_GRAVAR, cuando este gana el foco ejecuta la función VERVAZIO(), que le devuelve el foco boton BTN_GRAVAR, y este a su vez ejecuta nuevamente el ON GOTFOCUS VERVAZIO() entrando en un loop continuo.

La forma de solucionarlo es definir como:

HB_FUNC( C_MSGEXCLAMATION )
{
MessageBox ( NULL , hb_parc(1), hb_parc(2), MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL );
}

el NULL hace que no se devuelva el foco a ninguna ventana y por lo tanto escapa del loop.

Espero no haber sido tan enredado y aburrido en la explicación. #-)
Saludos,
Claudio.
Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
Claudio Soto
Colaborador
Colaborador
Mensagens: 568
Registrado em: 27 Ago 2012 12:31
Localização: Uruguay
Contato:

SetFocus em Loop

Mensagem por Claudio Soto »

En MiniGUI extended podes usar esta función:

Código: Selecionar todos

#include "minigui.ch"
#include "i_winuser.ch"

#xtranslate Mi_MsgExclamation (<cMessage>, <cTitle>) ;
            => ;
            MessageBoxIndirect ( 0, <cMessage>, <cTitle>, MB_OK + MB_ICONEXCLAMATION + MB_SYSTEMMODAL + MB_TOPMOST )

Function Main

   Mi_MsgExclamation ("Hola", "MiniGUI")

Return Nil
Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

SetFocus em Loop

Mensagem por rubens »

Muitissimo Claro, Sr. Claudio Soto...

Eu consegui "resolver/contornar" a situação validando a saída de cada textbox.
Vou estudar as suas observações e tentar fazer as modificações indicadas...

Muito obrigado.

Muchas Gracias...

Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Responder