Problema no tbrowse

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

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

Problema no tbrowse

Mensagem por JoséQuintas »

O tbrowse está funcionando.
Numa máquina lenta, a atualização de tela acaba "comendo" letras da digitação.
Já testei algumas coisas mas não deu certo.
Por exemplo, oBrowse:Invalidate(), mas quando tecla ENTER, está posicionado em registro errado.

Código: Selecionar todos

   DO WHILE lmore
      oBrowse:RefreshCurrent()
//------------ aqui a aceleração, pra só atualizar a tela enquanto não digitar nada   
      nkey := 0
      DO WHILE nkey == 0 .AND. .NOT. oBrowse:Stable
         oBrowse:Stabilize()
         nkey := Inkey()
      ENDDO
//-------------------------------
//------------ e aqui só pede pra digitar se estiver estabilizado - se foi teclado algo durante a atualização de tela anterior já prossegue
      IF oBrowse:Stable
         oBrowse:RefreshCurrent()
         DO WHILE .NOT. oBrowse:Stabilize() // nem sei se precisaria, já que só entra aqui se estiver estabilizado
         ENDDO
         oBrowse:ColorRect( { oBrowse:RowPos, 1, oBrowse:RowPos, oBrowse:ColCount }, { 3, 3 } ) // linha está com o cursor
         oBrowse:ColorRect( { oBrowse:RowPos, oBrowse:ColPos, oBrowse:RowPos, oBrowse:ColPos }, { 2, 2 } ) // linha/coluna está com o cursor
         nkey := Inkey(600)
         IF nKey == 0
            KEYBOARD Chr( K_ESC )
         ENDIF
      ENDIF
//------------------------------------------------------------
      IF ( mAcao := SetKey( nKey ) ) != NIL
         Eval( mAcao, ProcName(), ProcLine(), ReadVar() )
      ENDIF
      //Traduz Mouse
      nMRow := MROW()
      nMCol := MCOL()
      DO CASE
      CASE nKey == K_RBUTTONDOWN
         KEYBOARD Chr( K_ESC )
         LOOP
      CASE nKey == K_LBUTTONDOWN
         FOR nCont = 1 TO Len( aHotKeys )
            IF nMRow >= aHotKeys[ nCont, 1 ] .AND. nMRow <= aHotKeys[ nCont, 3 ] .AND. nMCol >= aHotKeys[ nCont, 2 ] .AND. nMCol <= aHotKeys[ nCont, 4 ]
               nKey := aHotKeys[ nCont, 6 ]
               EXIT
            ENDIF
         NEXT
      ENDCASE
      DO CASE
      CASE nKey > 999
         DO CASE
         CASE mBrzMove( oBrowse, nMRow, nMCol, nTop + 1, nLeft + 1, nBottom - 1, nRight - 1 ) // aceleração de mouse
         CASE mBrzClick( oBrowse, nMRow, nMCol ) // click no tbrowse atual   // click do mouse
            KEYBOARD Chr( K_ENTER )
            nKey := Inkey(0)
         ENDCASE
      CASE nkey == K_DOWN ;       oBrowse:Down()    ;  LOOP
      CASE nkey == K_PGDN ;       oBrowse:PageDown() ; LOOP
      CASE nkey == K_PGUP ;       oBrowse:PageUp() ;   LOOP
      CASE nkey == K_CTRL_PGDN ;  oBrowse:GoBottom() ; LOOP
      CASE nkey == K_UP ;         oBrowse:Up() ;       LOOP
      CASE nkey == K_CTRL_PGUP ;  oBrowse:GoTop() ;    LOOP
      CASE nkey == K_HOME ;       oBrowse:GoTop() ;    LOOP
      CASE nkey == K_END ;        oBrowse:GoBottom() ; LOOP
      CASE nkey == K_RIGHT ;      oBrowse:Right() ;    LOOP
      CASE nkey == K_LEFT ;       oBrowse:Left() ;     LOOP
//------------------------ este bloco é onde causa o problema em máquina lenta
      CASE ( nkey > 31 .AND. nkey <= 127 ) .AND. ( .NOT. Empty( OrdKey() ) .AND. ValType( &( OrdKey() ) ) == "C" )
         IF dbSeek( cUserScope + Chr( nkey ) )
            cUserScope += Chr( nkey )
         ELSEIF dbSeek( cUserScope + Upper( Chr( nkey ) ) )
            cUserScope += Upper( Chr( nkey ) )
         ELSE
            MsgWarning( "Não Localizado texto iniciando com " + cUserScope + Chr( nkey ) + "!" )
            KEYBOARD Chr( 205 )
            Inkey(0)
         ENDIF
         dbSeek( cUserScope )
         oBrowse:RefreshAll()
         LOOP
//------------- termina aqui
//------------ já este bloco funciona perfeito, ao teclar back space, e a lógica é a mesma SEEK + refreshall
      CASE nkey = K_BS
         cUserScope := left( cUserScope, Max( Len( cUserScope ) - 1, Len( cDefaultScope ) ) )
         IF .NOT. Empty( OrdKey() ) .AND. ValType( &( OrdKey() ) ) == "C"
            dbSeek( cUserScope )
            oBrowse:RefreshAll()
         ENDIF
         LOOP
// ----------termina aqui
 ...
ENDDO
Durante o post vi duas possibilidades:
- Talvez usar Nextkey() em algum ponto
- Quando estabilizado, justamente o novo Inkey() acaba "comendo" a letra do inkey() anterior

A dificuldade maior agora é conseguir fazer um tbrowse lento pra poder testar.
Talvez a base de telefones de SP, com alguns milhões de registros, e com set filter....
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
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Problema no tbrowse

Mensagem por asimoes »

Talvez usando evento de tela possa mudar a situação.
HRB_DOEVENTS()

Dentro do do while...enddo

Código: Selecionar todos

#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
#include <olectl.h>
#include <time.h>
HB_FUNC( HRB_DOEVENTS )
{
   MSG Msg;

   while( PeekMessage( ( LPMSG ) &Msg, 0, 0, 0, PM_REMOVE ) )
   {
      TranslateMessage( &Msg );
      DispatchMessage( &Msg );
   }
}
#pragma ENDDUMP
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Problema no tbrowse

Mensagem por JoséQuintas »

Como "comer" tecla só pode ser inkey()... por enquanto substituí esta parte:

Código: Selecionar todos

IF oBrowse:Stable
por

Código: Selecionar todos

IF nKey == 0
Se foi digitada uma tecla, não entra no IF e não faz inkey(0).
Segue em frente, processa a tecla e volta.

Se resolver ok, e se causar problema de posicionamento, altero dentro do if, neste ponto:

Código: Selecionar todos

IF nKey == 0
   nKey := Inkey(600)
   IF nKey == 0
      nKey := K_ESC
   ENDIF
ENDIF
Vamos ver o que dá.
Se eu conseguir testar por aqui aviso - depende de forçar lentidão.
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