Página 1 de 4
problema com a keysec() no Harbour
Enviado: 27 Out 2012 10:50
por cjp
Pessoal, tenho notado, desde que migrei do xharbour para o harbour, que há um problema com a função keysec(). Às vezes ela não espera o tempo designado para executá-la.
Já havia enfrentado problema semelhante no xharbour, que foi resolvido com a seguinte função, que me foi enviada por alguém daqui do grupo:
Código: Selecionar todos
function keysec(nkey, ntime, ncounter, lmode)
return __keysec(nkey, ntime, ncounter, lmode)
Mas acho que esta função estava em alguma lib que não dá pra usar no harbour.
Alguém saberia me dizer como resolver isto no harbour?
problema com a keysec() no Harbour
Enviado: 27 Out 2012 13:37
por Imatech
Olá !
KeySec( ... ) é integrante da lib hbCT
Código: Selecionar todos
/*
* $Id: keysec.prg 18376 2012-10-19 13:23:11Z vszakats $
*/
/*
* Harbour Project source code:
* CT3 Miscellaneous functions: - KEYSEC()
*
* Copyright 2005 Pavel Tsarenko - <tpe2@mail.ru>
* www - http://harbour-project.org
*/
THREAD STATIC t_hIdle
FUNCTION KeySec( nKey, nTime, nCounter, lMode )
LOCAL nSeconds
IF t_hIdle != NIL
hb_idleDel( t_hIdle )
t_hIdle := NIL
ENDIF
IF HB_ISNUMERIC( nKey )
IF ! HB_ISNUMERIC( nTime )
nTime := 0
ELSEIF nTime < 0
nTime := -nTime / 18.2
ENDIF
nTime *= 1000
IF ! HB_ISNUMERIC( nCounter )
nCounter := 1
ENDIF
IF ! HB_ISLOGICAL( lMode )
lMode := .F.
ENDIF
nSeconds := hb_milliSeconds()
t_hIdle := hb_idleAdd( {|| doKeySec( nKey, nTime, lMode, ;
@nCounter, @nSeconds ) } )
RETURN .T.
ENDIF
RETURN .F.
STATIC PROCEDURE doKeySec( nKey, nTime, lMode, nCounter, nSeconds )
LOCAL nSec := hb_milliSeconds()
IF lMode .AND. ! Empty( NextKey() )
nSeconds := nSec
ELSEIF nCounter != 0 .AND. nSec - nSeconds >= nTime
hb_keyPut( nKey )
IF nCounter > 0
nCounter--
ENDIF
IF nCounter == 0
hb_idleDel( t_hIdle )
t_hIdle := NIL
ELSE
nSeconds := nSec
ENDIF
ENDIF
RETURN
problema com a keysec() no Harbour
Enviado: 27 Out 2012 23:30
por cjp
Mas eu já estou compilando com essa lib.
O problema é o erro de contagem que tem nessa função. O mesmo problema que existe no xharbour, só que neste, tem essa função que eu citei acima consertando o problema. No harbour não tem?
problema com a keysec() no Harbour
Enviado: 29 Out 2012 13:27
por Jairo Maia
Olá Inácio,
Tente usar esta função ao invés da KeySec(), veja se vai funcionar.
Você pode apenas para facilitar, renomeá-la para KeySec e compilar junto com seus fontes para ver se funciona, isso evitaria ter que renomear ou redirecionar para My_KeySec.
Se desejar fazer o teste e retornar, agradeço.
Código: Selecionar todos
/*
*
* My_KeySec() // Insere um código de tecla no Buffer do teclado
*
* nKey = Tecla a ser inserida no Buffer
* nTime = Tempo em segundos ( tempo mínimo 0.1 = 1/10 )
* para inserir nKey no Buffer
* nCounter = Número de vezes a inserir nKey no Buffer
* lMode = Se .T. reseta nTime para inserir nCounter * nKey
* lReturn = Retorna .T. se o tempo foi esgotado, e .F. se foi
* pressionado alguma tecla dentro do tempo
*
*/
Function My_KeySec( nKey, nTime, nCounter, lMode )
Local nVezes := 0
Local nTecla := 0
Local nEspera := Nil
nCounter := If( nCounter <= 0, 1, nCounter )
Clear Typeahead // limpa o buffer do teclado
If Hb_IsNumeric( nKey )
If !Hb_IsNumeric( nTime )
nTime := 0
EndIf
IF !Hb_IsNumeric( nCounter )
nCounter := 1
EndIf
If !Hb_IsLogical( lMode )
lMode := .F.
EndIf
nTecla := InKey( nTime )
If ( lMode .And. nTecla > 0 )
While ( nVezes < nCounter )
Hb_KeyPut( nKey )
Inkey()
nVezes++
EndDo
Else
While ( nVezes < nCounter )
Hb_KeyPut( nKey )
Inkey()
nVezes++
nTecla := InKey( nTime )
EndDo
EndIf
EndIf
Return ( nTecla = 0 )
problema com a keysec() no Harbour
Enviado: 30 Out 2012 00:54
por cjp
Valeu, meu caro. Já compilei no meu sistema e vou testar. Retornarei sim, com o resultado. Muito obrigado.
Num rápido teste que fiz, já constatei dois problemas:
Primeiro, deu um erro nessa função, assim descrito:
Código: Selecionar todos
Ocorreu o erro: Error BASE/1074 Erro nos parâmetros: <=
Data: 30/10/12; hora: 01:23:49
Programa......: C:\Agenda\agenda.exe
Na função.....: KEYSEC
Na linha......: 20284
Base em uso...: ATIVU
Pasta.........: tarefas
Usuário.......: I
Versão........: 31/03/12
Caminho Percorrido Antes do Erro:
Vindo de......: KEYSEC Linha: (20284)
Vindo de......: HORTAR Linha: (3701)
Vindo de......: AGCOM Linha: (870)
Vindo de......: MAIN Linha: (255)
A linha onde deu o erro é a seguinte:
Não entendi a causa do erro.
O outro problema é a inkey(), que está parando o programa a todo momento. Eu tenho que teclar algo sempre para ele prosseguir. Não era pra ser assim, certo? Até tentei tirar essa inkey(), mas daí o programa deu erro.
problema com a keysec() no Harbour
Enviado: 30 Out 2012 10:03
por Jairo Maia
Olá Inácio,
Obrigado pelo teste. Fiz as alterações com base em suas observações. Quando puder testar novamente e retornar, agradeço.
Código: Selecionar todos
/*
*
* My_KeySec( nKey, nTime, nCounter, lMode )
*
* Insere teclas no Buffer do teclado:
*
* nKey = Tecla a ser inserida no Buffer.
* nTime = Tempo em segundos para inserir nKey no Buffer
* PS: Tempo m¡nimo 0.1 ( 1s / 10 ).
* nCounter = Numero de vezes a inserir nKey no Buffer.
* lMode = Se .T. reseta nTime para inserir ( nCounter * nKey )
* apos pressionar alguma tecla.
*
* Retorna .T. se o tempo foi esgotado, e .F. se foi pressionado
* alguma tecla dentro do tempo.
*
*/
Function My_KeySec( nKey, nTime, nCounter, lMode )
Local nVezes := 0
Local nTecla := 0
Clear Typeahead // limpa o buffer do teclado
If Hb_IsNumeric( nKey )
If !Hb_IsNumeric( nTime ) .Or. nTime <= 0
nTime := 0.1
EndIf
IF !Hb_IsNumeric( nCounter ) .Or. nCounter <= 0
nCounter := 1
EndIf
If !Hb_IsLogical( lMode )
lMode := .F.
EndIf
nTecla := InKey( nTime )
If ( lMode .And. nTecla > 0 )
While ( nVezes < nCounter )
Hb_KeyPut( nKey )
Inkey()
nVezes++
EndDo
Else
Hb_KeyPut( nKey )
Inkey()
nVezes++
While ( nVezes < nCounter )
If ( lMode .And. nTecla = 0 )
nTecla := InKey( nTime )
ElseIf !lMode
nTecla := InKey( nTime )
Endi
Hb_KeyPut( nKey )
Inkey()
nVezes++
EndDo
EndIf
EndIf
Return ( nTecla = 0 )
problema com a keysec() no Harbour
Enviado: 31 Out 2012 00:03
por cjp
Meu caro, eu é que agradeço a tua disponibilidade em ajudar.
Testei, mas continua parando no inkey().
problema com a keysec() no Harbour
Enviado: 31 Out 2012 13:48
por Jairo Maia
Olá Inácio,
cjp escreveu:Testei, mas continua parando no inkey().
Sim. Fiz vários testes novamente, e a função está funcionando corretamente. Quanto a parar no inkey() o tempo definido está corretíssimo. Caso não seja isto que você quer, então não é a KeySec() que pode lhe atender. O que ocorre é que realmente em xHarbour e Harbour, esta função tem problema. O objetivo foi criar uma função que tinha os mesmos objetivos dela, e que funcionasse.
Veja como tem que funcionar a função KeySec():
KeySec()
Starts a timer to write a key code into the keyboard buffer.
Syntax
Keysec( <nKey> , ;
<nTime> , ;
[<nCounter>], ;
[<lMode>] ) --> lSuccess
Arguments
<nKey>
This is the numeric key code to write into the keyboard buffer. #define constants listed in the Inkey.ch file are used for <nKey>.
<nTime>
This is a numeric value specifying the time after which the character is written into the keyboard buffer. Positive values indicate the time in seconds, while negative values are interpreted as multiples of 1/18.2 seconds.
<nCounter>
This parameter specifies the number of times <nKey> should be placed into the keyboard buffer before the timer ends. The default value is 1.
<lMode>
This parameter defaults to .F. (false). When .T. (true) is passed, the timer is reset when a key is pressed.
Return
The function returns .T. (true) when the timer is successfully activated, otherwise .F. (false).
Note: when the function is called without a parameter, the timer is deactivated.
Verificando seus códigos postados, vi que você usa o seguinte por exemplo para esta função:
Veja que em nCounter, você sempre coloca -1, quando este parâmetro tem por objetivo informar a função a quantidade de vezes a ser colocada no Buffer do Teclado a tecla definada em nKey, tendo que ser necessariamente número positivo.
Pelo que percebo, sua expectativa não está contemplada nesta função. Na sua opinião, como ela deveria funcionar?
problema com a keysec() no Harbour
Enviado: 01 Nov 2012 01:27
por cjp
Meu caro,
Sempre usei a keysec() com o objetivo principal de avançar num wait "", ou um @...prompt, por exemplo, quando o usuário não tecla nada. Então, a keysec() servirá para "dar um enter" na opção default. Me entende?
No meu entendimento, a keysec() não poderia ter essa parada, porque essa parada está sendo feita a todo passo do programa, já que a keysec() se executa continuamente. Então, por exemplo: se o programa está num @...prompt, caso o usuário faça alguma escolha no menu, não era pra ter nenhuma parada, mas com esse inkey(), está tendo uma parada, o usuário tem que teclar outra tecla para prosseguir. Me entende?
A opção -1, segundo me ensinaram, significaria que a keysec() se repetiria indefinidamente. Não é isso? De toda forma, isso não altera o problema que está dando. Se eu colocar 2, 10, ou 100, o problema dará no mesmo.
problema com a keysec() no Harbour
Enviado: 04 Dez 2012 00:38
por cjp
Eric,
Realmente não resolveu o problema.
Estou usando a versão 3.0 do Harbour.
problema com a keysec() no Harbour
Enviado: 14 Mar 2013 22:18
por cjp
Caros colegas do grupo,
Encareço a ajuda de vocês para uma solução para esta função keysec().
Não entendo porquê, mas ela não está funcionando corretamente.
Aparentemente, ela está esperando que o usuário tecle alguma coisa para, só então, acionar a tecla pretendida na keysec(), o que é um contrassenso, pois a ideia da função é justamente ela simular o pressionamento da tecla em questão, sem intervenção do usuário.
Explico:
Usando assim:
A pretensão é que, passados 45 segundos sem qualquer ação do usuário, a função simule o pressionamento de ESC pelo usuário, saindo de um dbedit(), por exemplo.
Entretanto, ele não sai nunca do dbedit() espontaneamente. Mas, quando o usuário tecla qualquer tecla, daí sim ele acresce um ESC depois da tecla pressionada pelo usuário, com consequências imprevisíveis.
Em suma, parece que ele está esperando a ação do usuário para entrar no keysec(), o que não é correto.
Alguém poderia me ajudar?
problema com a keysec() no Harbour
Enviado: 15 Mar 2013 10:29
por Pablo César
Oi Inácio, seus tópicos são sempre extensos... rs
Olha eu fiz um teste com o seguinte código (preste atenção ao código):
Código: Selecionar todos
// #include <hmg.ch>
REQUEST HB_GT_WIN_DEFAULT
Function Main()
Local cText:="Teste no MemoEdit"
SetMode(25,80)
SetColor("b/w")
// SET SCOREBOARD Off
keysec(27,15,-1,.t.)
cTexto:=MemoEdit(cText,05,10,18,60)
Alert(cTexto)
Return Nil
Veja eu compilei com REQUEST HB_GT_WIN_DEFAULT para que pudesse ser em modo console pela IDE da HMG, o que basicamente é praticamente quase igual que compilar com puro Harbour. A versão do Harbour é 3.2.0dev (Rev. 18443). Fiz um teste simples, só que reduzi para 15 segundos (para não ter que esperar muito) e anexei o executável para você ver com os próprios olhos e perceber que tudo ocorre normal. A única diferença que há é quando você remove o comentário da linha onde está o comando SET SCOREBOARD Off, isto é, deixando ele válido, portanto não irá aparecer aquela famosa pergunta na parte superior direita "
Abort edit Y/N ?". Também preste atenção que desabilitado a linha SET SCOREBOARD Off, só irá perguntar mesmo, se o usuário fizer alguma alteração no texto, senão, nem pergunta.
Portanto há NADA de errado com o KeySec.
problema com a keysec() no Harbour
Enviado: 15 Mar 2013 12:11
por cjp
Realmente, Pablo, o teu exemplo funciona perfeitamente.
A única coisa que tenho diferente aqui é a versão do Harbour (estou usando a 3.0) e a HB_GT_WIN_DEFAULT, que não uso. Será que o problema é num desses fatores?
De qualquer forma, vou testar estes dois pontos e verificar como fica.
Obrigado.
problema com a keysec() no Harbour
Enviado: 15 Mar 2013 12:31
por Pablo César
Eu ja apresentei o HMG para você... então por quê sofrer

Use a IDE do HMG em modo console também e seja feliz !
problema com a keysec() no Harbour
Enviado: 15 Mar 2013 19:44
por cjp
Infelizmente ainda não aprendi o suficiente para usá-la. Não tive tempo para estudá-la o suficiente.
Fiz alguns testes. Percebi que o problema ocorre só (ou principalmente) em uma função minha. Pode não ser problema da keysec(), mas não consigo achar nenhum problema na minha função que justifique isso. Estou postando a função para ver se alguém poderia ajudar:
Código: Selecionar todos
usebase(arq)
go bottom
skip -15
set color to w/r
clear
@ 0,0 to maxrow(),maxcol() double
if us#"I"
@ maxrow()-4,2 say "Tempo máximo para esta tarefa: "+alltrim(str(te))+" minutos"
endif
@ maxrow()-2,1 say "R-responder; B-atualiza índice só desta tarefa; setas-sobe e desce"
@ maxrow()-1,1 say "1 a 9-adiam a tarefa por 1 a 9 horas; M-adia meia hora; F-adia 5 minutos"
set cursor on
if us="I"
private v1[7]
private v3[7]
else
private v1[3]
private v3[3]
endif
if us#"I"
v1[1]="substr(dtoc(data),1,5)"
else
v1[1]="Data"
endif
v1[2]="substr(hora,1,5)"
v1[3]="Tarefa"
v3[1]="Data"
v3[2]="Hora"
if us="I"
v1[4]="Tempoestim"
v1[5]="Tempousado"
v1[6]="Tempocompu"
v1[7]="Vinculo"
v3[4]="Tpe"
v3[5]="Tpu"
v3[6]="Tpc"
endif
prvez="S"
sele 3
if usebase(ativ)=.t.
append blank
repl data with date()
repl hora with time()
repl acao with "ENT-III"
endif
use
sele (substr(arq,1,at(".",arq)-1))
if keysec(27,77,-1,.t.)#.t.
mandmail1("","Keysec retornou falso no responde2 8429")
endif
dbedit(1,1,maxrow()-6,maxcol()-1,v1,"responde2",,v3)
function responde2
nTecla2:=lastkey()
save scre to tlresp2
nsec=0
if nTecla2=27 .or. reccount()=0
keysec(277,125,-1,.t.)
rest scre from tlresp2
keyb "y"
return(0)
elseif upper(chr(nTecla2))="B"
if usebase("consulta")=.t.
locate for arquivo=arq
if found()
rcindres=recno()
atindres()
endif
endif
if usebase("consedit")=.t.
go rc
rlbs()
replace exibe with ex
endif
keyb "y"
return(0)
elseif upper(chr(nTecla2))="V" .and. us="I"
usebase("consedit")
go rc
arq=arquivo
ftecv()
keyb "y"
return(0)
elseif chr(nTecla2)="0" .and. us="I"
usebase("consedit")
go rc
arq=arquivo
fteczero()
keyb "y"
return(0)
elseif upper(chr(nTecla2))="-" .and. us="I"
usebase("consedit")
go rc
arq=arquivo
ftecmen()
keyb "y"
return(0)
elseif upper(chr(nTecla2))="+" .and. us="I"
usebase("consedit")
go rc
arq=arquivo
ftecmais()
keyb "y"
return(0)
elseif upper(chr(nTecla2))="E" .and. us="I"
usebase("consedit")
go rc
arq=arquivo
ftece()
keyb "y"
return(0)
elseif upper(chr(nTecla2))="K" .and. us="I"
usebase("consedit")
go rc
fteck()
keyb "y"
return(0)
elseif upper(chr(nTecla2))="S" .and. us="I"
if usebase("consedit","S")=.t.
go rc
ftecs()
endif
keyb "y"
return(0)
elseif upper(chr(nTecla2))="X" .and. us="I"
if usebase("consedit","S")=.t.
go rc
ftecx()
endif
keyb "y"
return(0)
elseif upper(chr(nTecla2))="M" .or. upper(chr(nTecla2))="F" .or. (nTecla2>48 .and. nTecla2<58) .or. (us="I" .and. (upper(chr(nTecla2))="D" .or. upper(chr(nTecla2))="Q" .or. upper(chr(nTecla2))="U" .or. upper(chr(nTecla2))="Z" .or. upper(chr(nTecla2))="G" .or. upper(chr(nTecla2))="O" .or. upper(chr(nTecla2))="P" .or. upper(chr(nTecla2))="W"))
clear
if usebase("consedit")=.t.
go rc
endif
tpa=val(chr(nTecla2))
tpa2=nTecla2
keyb "y"
ftecmnr()
return(0)
elseif upper(chr(nTecla2))="A" .and. us="I"
if usebase("consedit")=.t.
go rc
arq=arquivo
endif
if usebase(arq,"S")=.t.
browse()
pack
endif
usebase("com"+substr(arq,1,1))
append blank
repl comandos with (arq)
@ 23,1 clear to 23,79
@ 23,5 say "Tarefa salva para enviar mais tarde"
inkey(2)
if usebase("consedit","S")=.t.
go rc
dele
pack
endif
use (arq)
keyb "y"
return(0)
elseif nTecla2=7 .and. us="I" //DEL
if usebase("consedit","S")=.t.
go rc
ftecdel()
endif
keyb "y"
return(0)
elseif upper(chr(nTecla2))="R"
ftecr()
keyb "y"
return(0)
elseif upper(chr(nTecla2))="T" .and. us="I"
ftect()
keyb "y"
return(0)
elseif upper(chr(nTecla2))="I"
fteci()
keyb "y"
return(0)
endif
return(2)
Alguém saberia me dizer se tem alguma coisa que esteja impedindo a keysec() de funcionar direito nesse dbedit()?
Noto que o problema ocorre assim que entra no dbedit(), sem que se tecle qualquer outra coisa depois de entrar no dbedit().