Página 1 de 5
Cancelar Operação
Enviado: 27 Jan 2009 13:35
por Netavin
Bom dia pessoal !
Gostaria de um parecer/opinião.
Em minhas rotinas, para cancelar uma operação, tenho empregado o seguinte:
@ 10,10 Say "Informe o código: " get nvar Valid ....
read
If lastkey() = 27
... aviso
use
exit
endif
Porém eu uso isto tambem após os demais Get´s ( de uma inclusão por exemplo ou alteração ).
Haveria a necessidade disto ? ... ou bastaria apenas após o primeiro Read ?
Obrigado !!
[]´s
Netavin
Re: CANCELAR OPERAÇÃO
Enviado: 27 Jan 2009 14:16
por Maligno
Não entendi muito bem. Haveria necessidade de que? Você fala do teste da tecla ESC? Se for, eu uso sempre. E coloco o READ dentro de um WHILE, pois se a resposta for não para cancelar, o comando volta ao topo dos GETs. Mas os GETs ficam fora da malha.
Re: CANCELAR OPERAÇÃO
Enviado: 27 Jan 2009 14:41
por Eolo
Se você tem diversos GETs e o READ, quando vc tecla ESC de qualquer GET, o READ é terminado e o programa continua depois dele.
Uma função que ajuda é a UPDATED(), que retorna .T. se algum GET sofreu alteração e .F. ao contrário. Então, se o usuário saiu com ESC e UPDATED()=.T., é sinal que ele alterou alguma coisa em algum GET e está saindo sem gravar a alteração. Neste caso, eu apresento uma mensagem pedindo que ele confirme se quer mesmo abandonar as alterações.
Um exemplo:
Código: Selecionar todos
set key -9 to F_GRAVA
set confirm on
vcampo1:=campo1
vcampo2:=campo2
do whil .t.
@10,10 get vcampo1
@12,10 get vcampo2
read
altera=updated()
lk:=lastkey()
if lk=-9 .and. altera=.t. // GRAVAR
repl campo1 with vcampo1
repl campo2 with vcampo2
exit
endi
elseif lk=27 .and. altera=.f.
exit
elseif lk=27 .and. altera=.t.
do whil .t.
* mensagem: Sai sem gravar ALTERAÇÕES?
inkey(0)
lk2:=upper(chr(lastkey()))
if lk2$"SN"
exit
endi
endd
if lk2="S"
exit
endi
endi
endd
function F_GRAVA
clea gets
Re: CANCELAR OPERAÇÃO
Enviado: 27 Jan 2009 14:58
por Eolo
Esqueci de uma coisa: não sei porque, mas a função UPDATED() só é atualizada se vc sair do GET com ENTER. Se vc por ex alterar algo em VCAMPO1 e teclar ESC, a função UPDATED() não é atualizada.
A saída que eu encontrei (não sei se a melhor...) foi vincular a tecla ESC a uma função. Veja o mesmo código acima, complementado com isso.
Código: Selecionar todos
set key -9 to F10
public altera:=.f.
set confirm on
vcampo1:=campo1
vcampo2:=campo2
set key 27 to EXCAPE
do whil .t.
@10,10 get vcampo1
@12,10 get vcampo2
read
altera=updated()
lk:=lastkey()
if lk=-9 .and. altera=.t. // GRAVAR
repl campo1 with vcampo1
repl campo2 with vcampo2
exit
endi
elseif lk=27 .and. altera=.f.
exit
elseif lk=27 .and. altera=.t.
do whil .t.
* mensagem: Sai sem gravar ALTERAÇÕES?
inkey(0)
lk2:=upper(chr(lastkey()))
if lk2$"SN"
exit
endi
endd
if lk2="S"
exit
endi
endi
endd
altera:=.f.
set key 27 to
function F10
clea gets
function EXCAPE
if updated()
altera=.t.
endi
clea gets
Cancelar Operação
Enviado: 19 Dez 2015 18:51
por microvolution
olá pessoal, no meu caso, eu tô querendo quase a mesma coisa...
só que no lugar de voltar ao topo da lista de gets, tem como voltar no mesmo get?
exemplo:
-----
CLIENTE COD:
NOME:
ENDEREÇO:
----
neste momento é pressionado a tecla ESC, aí vem a pergunta:
"deseja sair sem gravar?"
se sim:
exit
se não: RETORNA AO GET onde foi acionado o ESC.
========
É possível isso em clipper ou agora em harbour com suas libs?
vlw!
Cancelar Operação
Enviado: 19 Dez 2015 21:05
por JoséQuintas
O READ é pra receber a digitação de informações.
Se durante esta digitação o usuário teclar ESC, significa que abandonou isto.
Um próximo READ será uma nova digitação.
E na nova digitação, o usuário também poderá optar por teclar ESC.
São digitações distintas, em cada uma delas o usuário pode ou não digitar ESC.
O que o seu programa vai fazer quando o usuário teclar ESC, é decisão sua, e vai ter que colocar no fonte.
Cancelar Operação
Enviado: 19 Dez 2015 21:13
por JoséQuintas
Sobre a outra pergunta do ESC.
É difícil, porque ESC já abandona o que for digitado, e reseta a posição dos GETs.
Talvez alterar dentro da GETSYS, aonde analisa o ESC, assim nem sai dos GETs.
Em todo caso, teste com READ SAVE, que não destrói os GETs
Apenas exemplo, vai ter que testar
Código: Selecionar todos
@ 1, 0 GET ALGUMACOISA
DO WHILE .T.
READ SAVE
IF Lastkey() == K_ESC
IF .NOT. MsgYesNo( "Abandona"? )
LOOP
ENDIF
ENDIF
EXIT
ENDDO
GetList := {}
Cancelar Operação
Enviado: 20 Dez 2015 13:22
por microvolution
isso eu já faço há muitos anos, mas, não dá o resultado esperado!
eu descobri (mexendo no harbourdoc.com.br) as seguintes funções/classes que são mais do que um simples comando GET:
menu:UserInterface/GetSys:
Código: Selecionar todos
EraseGetMsg()
Get()
GetActive()
GetApplyKey()
GetClrBack()
GetClrFore()
GetClrPair()
GetDoSetKey()
GetNew()
GetPairLen()
GetPairPos()
GetPostValidate()
GetPreValidate()
GetReader()
e dentro da sub-pasta API:
Código: Selecionar todos
__Get()
__GetA()
__GetListActive()
__GetListLast()
__GetListSetActive()
__GetMessage()
__GetMsgPrf()
Infelizmente no harbourdoc e em nenhum lugar achei alguma referência (user guide) dessas funções, que podem ser a solução não só pra mim, mas, pra todos que sabem dessa limitação antiga do clipper, que talvez no harbour os desenvolvedores já tenham resolvido.
vlw e abraços!
Cancelar Operação
Enviado: 20 Dez 2015 14:26
por JoséQuintas
Talvez alterar dentro da GETSYS, aonde analisa o ESC, assim nem sai dos GETs.
A GETSYS é a rotina que processa os GETS.
Desde os tempos do Clipper, pode ser substituída.
Lá tem todo funcionamento dos GETS, inclusive o que está perguntando.
Fazendo sua própria getsys, talvez baste alterar esta parte:
Código: Selecionar todos
CASE ( nKey == K_ESC )
IF ( SET( _SET_ESCAPE ) )
oGet:undo()
oGet:EXITState := GE_ESCAPE
ENDIF
Usar INKEYFILTER também poderia ser uma opção, mas vai ter uso mais limitado.
Cancelar Operação
Enviado: 20 Dez 2015 16:32
por microvolution
falou tudo grego ... rsrs
Cancelar Operação
Enviado: 20 Dez 2015 16:59
por JoséQuintas
No Clipper ou no Harbour existe um fonte com o nome GETSYS.PRG
Tem todo funcionamento do GET.
O fonte é disponível justamente pra poder alterar do jeito que quiser, fazendo os GETs funcionarem do jeito que quiser.
Cancelar Operação
Enviado: 21 Dez 2015 14:28
por Jairo Maia
Olá Pessoal,
Veja também uma opção usando BEGIN/END SEQUENCE e permutando a tecla ESC na seção do READ onde isso se faz necessário:
Código: Selecionar todos
#include "inkey.ch"
//Function Main() // descomente se for compilar em Harbour
Local cTeste := Space(10)
Local k_esc := SetKey( K_ESC, { || PodeSair() } )
Clear Screen
Begin Sequence
@ 12, 20 Say "Digite algo ou ESC para sair " GET cTeste Pict "@!"
READ
End Sequence
SetKey( K_ESC, k_esc ) // restaura ESC antes de sair
Return Nil
Function PodeSair()
If Hb_Alert( "Deseja Sair?", { "Nao", "Sim" } ) = 2
Break
EndIf
Return Nil // tem que ser Nil
Cancelar Operação
Enviado: 21 Dez 2015 19:26
por alxsts
Olá!
Segue outra sugestão:
Código: Selecionar todos
#include "inkey.ch"
FUNCTION Main()
LOCAL aGets
LOCAL GetList := {}
LOCAL oGet
LOCAL nPos
LOCAL nLen
LOCAL lLastExit := READEXIT(.T.)
RELEASE GetList
SetMode( 25,80)
CLS
aGets := AFill( Array( 5 ), Space(20) )
@ 10,10 Say "Campo 1" Get aGets[ 1 ]
@ 12,10 Say "Campo 2" Get aGets[ 2 ]
@ 14,10 Say "Campo 3" Get aGets[ 3 ]
@ 16,10 Say "Campo 4" Get aGets[ 4 ]
@ 18,10 Say "Campo 5" Get aGets[ 5 ]
nLen := Len( GetList )
nPos := 1
WHILE ( nPos <= nLen )
oGet := GetList[ nPos ]
ReadModal( { oGet } )
nKey := Lastkey()
DO CASE
CASE nKey == K_ESC
IF Alert( " Cancelar ? ", {" Nao ", " Sim " }, "W+/B" ) == 2
EXIT
ELSE
LOOP
ENDIF
CASE nKey == K_DOWN .OR. nKey == K_TAB .OR. nKey == K_ENTER
nPos++
CASE nKey == K_UP
nPos := Max( --nPos, 1 )
END CASE
ENDDO
GetList := {}
READEXIT(lLastExit)
RETURN NIL
//------------------------------------------------------------------------------
Cancelar Operação
Enviado: 22 Dez 2015 20:51
por microvolution
olá pessoal!
Diante de todos os comentários aqui (testes e exemplos) e durante vários dias de pesquisas...
juntei tudo e comecei a fazer o meu CANCELAR ESC dessa forma:
Código: Selecionar todos
Local escape
...
sequencia de @say GETs
...
escape := hb_SetKey( K_ESC, {|| escapar_ou_continuar () } )
readexit (.t.)
read
readexit (.f.)
hb_SetKey( K_ESC, escape )
Código: Selecionar todos
FUNC escapar_ou_continuar ()
LOCAL lRetorna := .f.
if .not. CONFIRMA ('Deseja realmente cancelar sem concluir', 6 ,'SiCCA v3.6 - Tecla <ESC> foi pressionada ???') == 1
lRetorna := .t.
endif
RETU lRetorna
Espero que funcione pra todos!
pra mim já está funcionado...
só tem um desconforto:
por exemplo no meu ACHOICE, já existia uma rotina que pra confirmar todos os produtos cadastrados, eu usava o LastKey() ESC... agora ele não mais funciona, pois cai é na mensagem de CONFIRMA (acima mencionada).
Então, estou tendo que adaptar para uma tecla de FUNÇÃO QUALQUER...
vlw!
Cancelar Operação
Enviado: 24 Dez 2015 21:52
por JoséQuintas
Não entendi como o lRetorna faz sair dos gets.
Em todo caso, testei isto e funciona.
Bastaria trocar READ por MyRead()
Código: Selecionar todos
#include "inkey.ch"
PROCEDURE Main
SetMode( 25, 80 )
CLS
mNome := Space(10)
@ 5, 5 GET mNome
MyRead()
RETURN
FUNCTION MyRead()
SET ESCAPE OFF
SET KEY K_ESC TO ExitFromRead
READ
SET KEY K_ESC TO
SET ESCAPE ON
RETURN NIL
FUNCTION ExitFromRead()
LOCAL nKey
@ 22, 0 SAY "Sair?"
nKey := 0
DO WHILE .NOT. Upper( Chr( nKey ) ) $ "SN"
nKey := Inkey(0)
ENDDO
@ 22, 0 SAY " "
IF Upper( Chr( nKey ) ) == "S"
SET ESCAPE ON
SET KEY K_ESC TO
KEYBOARD Chr( K_ESC )
ENDIF
RETURN NIL
Explicando o funcionamento:
MyRead) chama uma rotina que mexe com a configuração do ESC, faz o READ, e retorna à configuração original.
Com SET ESCAPE OFF, o ESC não sai do GET
Com SET KEY K_ESC, teclar o ESC chama a função
A função chamada por K_ESC reativa a saída com ESC e simula teclar ESC caso responda sim.
Na rotina de GETs normal, só testar se a última tecla pressionada foi ESC.
Pelo menos nessa parte fica igual todo mundo.