No artigo de hoje, vamos demonstrar em como bloquear o botão Refresh na tela de Monitoramento de Notas.
Imagina o seguinte cenário, onde os usuários do Faturamento ao clicarem na opção de Monitorar Notas, na segunda tela que é exibida, eles ficarem clicando sem parar no botão Refresh.
Isso pode acabar acarretando na mensagem “Rejeição 656 – Consumo Indevido”.
Para tentar sanar essa questão, desenvolvemos um paliativo, que na verdade impede que o usuário fique clicando nesse botão, sendo que a partir da segunda vez que ele clica, é exibido uma mensagem de aguardar 10 segundos.
O primeiro passo então, foi encontrar o ponto de entrada necessário para fazer esse ajuste, sendo que o utilizado foi o FISMNTNFE.
O segundo passo, foi ao construir o ponto de entrada, colocar um breakpoint logo no começo para ver a pilha de chamadas quando é disparado pelo botão, sendo que foi identificado que vem de um bloco de código, conforme print abaixo:
Então foi montado a seguinte lógica:
- Criação de uma variável que guarda a última vez que foi clicada no botão
- É feito um laço de repetição na pilha de chamadas (buscando o ProcName de cada posição)
- Se encontrar o bloco de códigos conforme o print acima, marca a variável lVeioBotao como true
- Ao sair do laço de repetição, se veio do botão e não tiver tempo ainda, atualiza a variável
- Do contrário, aciona a função zDlgEspera aguardando 10 segundos com uma mensagem personalizada (print abaixo)
E abaixo o código fonte conforme a lógica acima:
//Bibliotecas
#Include "TOTVS.ch"
//Último tempo executado
Static cUltTempo := ""
/*/{Protheus.doc} User Function FISMNTNFE
Ponto de Entrada acionado na tela de Monitoramento de NFe
@type Function
@author Atilio
@since 11/07/2024
@see https://tdn.totvs.com/display/public/TSS/FISMNTNFE+-+Monitor+Faixa+da+NF-e
/*/
User Function FISMNTNFE()
Local aArea := FWGetArea()
Local cMensagem := "Já foi clicado no <strong>Refresh</strong> nos últimos 10 segundos!<br>Aguarde mais <font color='red'>10 segundos</font> para tentar novamente!"
Local cTitulo := "Aguarde"
Local nSegundos := 10
Local cHoraAtual := Time()
Local lVeioBotao := .F.
Local nAtual := 0
//Enquanto for verdadeiro
While .T.
//Busca o nome do processo atual
cProcAtu := Alltrim(Upper(ProcName(nAtual)))
//Se tem processo
If ! Empty(cProcAtu)
//Se veio do listbox pra atualizar a tela
If "ALISTBOX:=GETLISTBOX(" $ cProcAtu
lVeioBotao := .T.
EndIf
//Senão, encerra o laço
Else
Exit
EndIf
//Incrementa o contador dos processos
nAtual++
EndDo
//Somente se veio do botão de Refresh
If lVeioBotao
//Se o tempo tiver vazio ou for maior que 10 segundos
If Empty(cUltTempo) .Or. ElapTime(cUltTempo, cHoraAtual) > "00:00:10"
cUltTempo := Time()
//Senão, mostra mensagem para esperar
ElseIf ! cHoraAtual == cUltTempo
u_zDlgEspera(cMensagem, cTitulo, nSegundos)
EndIf
EndIf
FWRestArea(aArea)
Return
/*/{Protheus.doc} User Function zDlgEspera
Função que abre uma dialog sem opção de fechar e sem o -ESC- por um curto período de tempo
@type Function
@author Atilio
@since 11/07/2024
@param cMensagem, Caractere, Mensagem que aparecerá na tela
@param cTitulo, Caractere, Título da tela da mensagem
@param nSegundos, Numérico, Número de segundos
/*/
User Function zDlgEspera(cMensagem, cTitulo, nSegundos)
Local aArea := FWGetArea()
Local bTimer := {|| oDialog:DeActivate()}
Local oDialog
Local oPanel
Local oSayMsg
Default cMensagem := "Aguarde 3 segundos"
Default cTitulo := "Atenção"
Default nSegundos := 3
//Configura a Dialog
oDialog := FWDialogModal():New()
oDialog:SetBackground(.F.)
oDialog:SetTitle(cTitulo)
oDialog:SetEscClose(.F.)
oDialog:SetSize(80, 150)
oDialog:SetCloseButton(.F.)
oDialog:CreateDialog()
oDialog:SetTimer(nSegundos, bTimer)
//Pega o painel e insere uma mensagem nele
oPanel := TPanel():New(/*nRow*/, /*nCol*/, /*cText*/, oDialog:GetPanelMain())
oPanel:Align := CONTROL_ALIGN_ALLCLIENT
oSayMsg := TSay():New(1, 1, {|| cMensagem}, oPanel, /*cPicture*/, /*oFont*/, /*uParam7*/, /*uParam8*/, /*uParam9*/, .T., /*nClrText*/, /*nClrBack*/, (oPanel:nWidth)/2 - 1, (oPanel:nHeight)/2 - 1, /*uParam15*/, /*uParam16*/, /*uParam17*/, /*uParam18*/, /*uParam19*/, .T.)
//Abre a Dialog
oDialog:Activate()
FWRestArea(aArea)
Return
Referências:
Bom pessoal, por hoje é só.
Abraços e até a próxima.

