Cancelar Operação

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Avatar do usuário
Netavin
Usuário Nível 3
Usuário Nível 3
Mensagens: 306
Registrado em: 28 Fev 2007 08:37
Localização: Cacoal-RO

Cancelar Operação

Mensagem 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
TK90 / TK95 / APPLE IIe / 286 / 386 / 486 / 586 / AMD Atlhon
" Sem saber que era impossível, foi lá e fez !! "
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: CANCELAR OPERAÇÃO

Mensagem 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.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Re: CANCELAR OPERAÇÃO

Mensagem 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
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Re: CANCELAR OPERAÇÃO

Mensagem 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
microvolution
Usuário Nível 5
Usuário Nível 5
Mensagens: 1231
Registrado em: 02 Set 2011 22:17
Contato:

Cancelar Operação

Mensagem 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!
Grato,
MICROVOLUTION - 16 anos Evoluindo Com Você!


Você já leu a Bíblia hoje?
João 3:16 - Porque Deus amou ao mundo de tal maneira que deu seu Único Filho para que todo aquele que nEle crê não pereça mas tenha a Vida Eterna!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Cancelar Operação

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Cancelar Operação

Mensagem 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 := {}   
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
microvolution
Usuário Nível 5
Usuário Nível 5
Mensagens: 1231
Registrado em: 02 Set 2011 22:17
Contato:

Cancelar Operação

Mensagem 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!
Grato,
MICROVOLUTION - 16 anos Evoluindo Com Você!


Você já leu a Bíblia hoje?
João 3:16 - Porque Deus amou ao mundo de tal maneira que deu seu Único Filho para que todo aquele que nEle crê não pereça mas tenha a Vida Eterna!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Cancelar Operação

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
microvolution
Usuário Nível 5
Usuário Nível 5
Mensagens: 1231
Registrado em: 02 Set 2011 22:17
Contato:

Cancelar Operação

Mensagem por microvolution »

falou tudo grego ... rsrs
Grato,
MICROVOLUTION - 16 anos Evoluindo Com Você!


Você já leu a Bíblia hoje?
João 3:16 - Porque Deus amou ao mundo de tal maneira que deu seu Único Filho para que todo aquele que nEle crê não pereça mas tenha a Vida Eterna!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Cancelar Operação

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Cancelar Operação

Mensagem 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
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Cancelar Operação

Mensagem 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
//------------------------------------------------------------------------------
[]´s
Alexandre Santos (AlxSts)
microvolution
Usuário Nível 5
Usuário Nível 5
Mensagens: 1231
Registrado em: 02 Set 2011 22:17
Contato:

Cancelar Operação

Mensagem 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!
Grato,
MICROVOLUTION - 16 anos Evoluindo Com Você!


Você já leu a Bíblia hoje?
João 3:16 - Porque Deus amou ao mundo de tal maneira que deu seu Único Filho para que todo aquele que nEle crê não pereça mas tenha a Vida Eterna!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Cancelar Operação

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder