Hoje à tarde andei lendo as páginas deste tópico e percebí que sempre faltava alguma coisa. Testei o código do Spencer aqui e observei 2 coisas:
- Dava erro quando usava máscara de números britânicos/brasileiros "@E"
Não mostrava o cursor
Peguei a idéia do Spencer de mudar só o read no caso de números para não mudar o GETSYS inteiro sem ver o que estava mudando, então no caso eu uso o argumento CALCULATOR ou só CALC.
Vejamos:
Conteúdo do cabeçalho GETCALC.CH (coloque na pasta INCLUDE)
/***
* Getcalc.ch
*
* Definition of GET CALCULATOR command.
*/
#command @ <row>, <col> GET <var> ;
[<clauses,...>] ;
CALCULATOR ;
[<moreClauses,...>] ;
;
=> @ <row>, <col> GET <var> ;
[<clauses>] ;
SEND reader := {|oGet| ;
GetCalc(oGet) } ;
[<moreClauses>]
Daí colocou CALCULATOR ou basta CALC que ativa o READER GetCalc().
Vejamos agora o READER (compile com o seu sistema):
#include "Getexit.ch"
#include "Inkey.ch"
#include "Getcalc.ch"
proc GetCalc( oGet )
nCURSOR := SETCURSOR()
// read the GET if the WHEN condition is satisfied
IF ( GetPreValidate(oGet) )
// activate the GET for reading
oGet:SetFocus()
// RS added this
// Start at last position
oGet:end()
// Just to here
// MOSTRA O CURSOR
SETPOS(oGET:ROW, oGET:COL + oGET:POS - 1)
SETCURSOR(1) // ATIVA CURSOR MODO SUBLINHADO
DO WHILE ( oGet:exitState == GE_NOEXIT )
// check for initial typeout (no editable positions)
IF ( oGet:typeOut )
oGet:exitState := GE_ENTER
ENDIF
// apply keystrokes until exit
DO WHILE ( oGet:exitState == GE_NOEXIT )
GetCalcApplyKey(oGet, HOTInKey(0))
ENDDO
// disallow exit if the VALID condition is not satisfied
IF ( !GetPostValidate(oGet) )
oGet:exitState := GE_NOEXIT
ENDIF
ENDDO
// de-activate the GET
oGet:KillFocus()
ENDIF
SETCURSOR(nCURSOR)
RETURN
/***
* GetCalcApplyKey()
* Apply a single Inkey() keystroke to a GET.
*
* NOTE: GET must have focus.
* Standard stuff. RS changed only BS and otherwise
*/
#define K_UNDO K_CTRL_U
proc GetCalcApplyKey(oGet, nKey)
local cKey
local bKeyBlock
local cTemp
local nTemp
// check for SET KEY first
IF (bKeyBlock := SetKey(nKey)) <> NIL
GetDoSetKey(bKeyBlock, oGet)
RETURN // NOTE
ENDIF
DO CASE
CASE nKey == K_UP
oGet:exitState := GE_UP
CASE nKey == K_SH_TAB
oGet:exitState := GE_UP
CASE nKey == K_DOWN
oGet:exitState := GE_DOWN
CASE nKey == K_TAB
oGet:exitState := GE_DOWN
CASE nKey == K_ENTER
oGet:exitState := GE_ENTER
CASE nKey == K_ESC
IF Set(_SET_ESCAPE)
oGet:undo()
oGet:exitState := GE_ESCAPE
ENDIF
CASE nKey == K_PGUP
oGet:exitState := GE_WRITE
CASE nKey == K_PGDN
oGet:exitState := GE_WRITE
CASE nKey == K_CTRL_HOME
oGet:exitState := GE_TOP
// both ^W and ^End terminate the READ (the default)
CASE nKey == K_CTRL_W
oGet:exitState := GE_WRITE
CASE nKey == K_UNDO
oGet:Undo()
CASE nKey == K_BS .OR. nKey == K_DEL
oGet:delete()
IF oGet:type == "C"
cTemp := oGet:unTransform()
cTemp := " " + Substr(cTemp, 1, Len(cTemp) - 1)
oGet:buffer := Transform(cTemp, oGet:picture)
ELSE
nTemp := oGet:unTransform()
cDEC := "."
IF AT("@E", UPPER(oGET:picture) ) > 0
// NESSE CASO É A VÍRGULA PARA CASAS DECIMAIS!
cDEC := ","
ENDIF
IF At(cDEC, oGet:buffer) != 0
// There is a decimal point
nTemp := nTemp / 10
ELSE
// No decimal point, division already taken place
// by deleting last character
ENDIF
oGet:buffer := Transform(nTemp, oGet:picture)
ENDIF
oGet:display()
OTHERWISE
IF (nKey >= Asc('0') .AND. nKey <= Asc('9')) .OR. ;
(nKey == Asc('.') .AND. ;
oGet:type == "C" .AND. At(".", oGet:buffer) == 0)
cKey := Chr(nKey)
IF oGet:type == "C"
cTemp := oGet:unTransform()
cTemp := SubStr(cTemp, 2) + " "
oGet:buffer := Transform(cTemp, oGet:picture)
ELSE
nTemp := oGet:unTransform()
nTemp := nTemp * 10
oGet:buffer := Transform(nTemp, oGet:picture)
ENDIF
// NOTE - important to use OverStrike here to set changed
// Alternative is to stuff key yourself. However, that does
// not set changed, therefore var is not updated.
oGet:overStrike(cKey)
oGet:end()
oGet:display()
ENDIF
ENDCASE
RETURN
Disseram que o GETSYS do Harbour foi todo refeito e que estava melhor do que o xHarbour. Aí a gente desenterrar o GETSYS do velho Clipper cansado de guerra ou outro... vamos acabar não acompanhando a evolução do Harbour. Enfim, usando só o reader personalizado quando for necessário eu acho melhor, salvo melhor juízo. O que vocês acham?
Fiz uma matéria falando melhor dessa solução do Spencer aqui: https://linguagemclipper.com.br/blogs/dicas/alinhar-get-numerico-a-direita