
Imagine a situação em que é necessário apresentar uma informação para o usuário e essa informação tem que ser fechada automaticamente após X tempo, por exemplo em processos dentro de um controle de transação, onde se o usuário demorar para clicar em fechar a transação ficará travada e bloqueará outros usuários.
Como resolver isso?
Irei demonstrar abaixo como garantir que a tela/mensagem seja fechada em 10 segundos (você pode configurar o tempo) e ainda demonstrando para o usuário segundo a segundo quanto tempo falta para o fechamento automático.
O resultado final será esse:

O timer no “Fechamento automático em:” será atualizado segundo a segundo até chegar em 0 e fechar a mensagem automaticamente.
Essa solução resolveu, por exemplo, um enorme problema no balcão de vendas em que um vendedor bloqueava todos os outros deixando essa tela aberta enquanto encaminhava os produtos para a expedição.
Mão na Massa
No código abaixo estou criando uma dialog (tela) para informar ao usuário o número do DAV, igual na imagem acima.
User Function PONTIN001()
Local cNumDav := "0000042025"
Private nStop := 0
Private nTempo := 10
Private nLimite := nTempo
DEFINE MSDIALOG oDlg1 TITLE "augustopontin.github.io/blog" FROM 000, 000 TO 160, 365 COLORS 0, 16777215 PIXEL
oFontTit := TFont():New( "Cooper Black", 0, -19,, .F., 0,, 400, .F. ,.F. ,,,,,, )
oFontDav := TFont():New( "Cooper Black", 0, -32,, .F., 0,, 400, .F., .F.,,,,,, )
oGrp1 := TGroup():New( 004, 004, 055, 180, "", oDlg1, CLR_BLACK, CLR_WHITE, .T., .F. )
oSay1 := TSay():New( 012, 050,{||"CÓDIGO DO DAV"}, oGrp1,, oFontTit, .F., .F., .F., .T., CLR_BLUE, CLR_WHITE, 092, 012)
oSay2 := TSay():New( 026,045,{||cNumDav}, oGrp1,, oFontDav, .F., .F., .F., .T., CLR_HRED, CLR_WHITE, 100, 026)
oSay3 := TSay():New( 045, 050, {||"FECHAMENTO AUTOMATICO EM: "}, oDlg1,,, .F., .F., .F., .T., CLR_BLUE, CLR_WHITE, 092, 012)
oSay4 := TSay():New( 045,145,{||cValToChar(nTempo)}, oDlg1,,, .F., .F., .F., .T., CLR_HRED, CLR_WHITE, 100, 026)
oBtn1 := TButton():New( 060, 066,"OK",oDlg1,{||oDlg1:End()}, 056, 016,,,, .T.,,"",,,, .F. )
nMilissegundos := 1000 // Disparo será de 1 em 1 segundos
oTimer := TTimer():New(nMilissegundos, {|| IIf(nStop<>nLimite, Tempo(), oDlg1:End()) }, oDlg1 )
oTimer:Activate()
oDlg1:Activate(,,,.T.)
Return
O segredo está na função TTimer, ela irá disparar o bloco de códigos “{|| IIf(nStop<>10,Tempo(),oDlg1:End()) }” a cada 1000 milissegundos (1 segundo).
Em seguida, criamos uma Static Function com nome de Tempo() para atualizar a variável de controle dos segundos.
Static Function Tempo()
nTempo := nLimite - nStop
oSay4:Refresh()
nStop++
Return
Essa função é responsável por atualizar a variável de controle de parada nStop e atualizar a variável que demonstra segundo a segundo para o usuário quanto falta para fechar a tela nTempo.
E claro, antes de sair da função é realizado um refresh no objeto TSay oSay4.
Está ai, algo bem simples, porém interessante e com muita aplicação !!
Muito bom o artigo e o recurso Pontin!
Para quem quiser algo parecido, porém para as mensagens (MsgAlert, MsgStop, MsgYesNo, etc…) tenho um projeto bem bacana também: https://github.com/AlencarGabriel/advpl-MsgTimer
Fica a dica!
Fala doutor!!
Muito bom esse seu timer mesmo… já até utilizei ele em um projeto…rsrs