Jump to content
Fivewin Brasil

FWH nao faz validacao como FW ??


lili

Recommended Posts

Migrei uma aplicação 16 para 32 bits. Já tinha notado que no 32 bits o fwh passa o foco para o proximo controle antes de terminar o valid do get e se for falso volta o foco para o get. No 16 bits ele primeiro validava o get para depois passar o foco para o proximo controle.

Olhei o tget e nao vi diferença neste sentido entre o 16 e 32 bits, mas na hora de executar ela existe!

Para mim isto é um grave problema, pois dependendo da rapidez na digitação nao executa a validação dos gets, porque o foco vai para outro controle ...

Quanto mais lenta a maquina maior o problema, chegando as vezes a passar campos em branco onde a validação nunca permitiria isto. (No 16 bits além de mais rápido NUNCA saía da validação sem realmente validar)

Como nao vi nada sobre isto aqui no forum fica a pergunta: Ninguém teve problema com validação do get no fwh?

Link to comment
Share on other sites

Fiz um exemplo testfoco.prg abaixo. Mas precisa do testfoco.rc tambem abaixo. Sugiro compilar com a classe tget alterada para colocar cor de fundo no foco para melhor visualização.

Teste no fwh e no fw. Voce vai ver a diferença.

***** TESTFOCO.PRG ************

// QUANDO EXECUTAR, APOS APARECER A JANELA DÊ ENTER BEM RAPIDO 3 VEZES E VEJA QUE O CURSOR ANDA NOS GETS PARA DEPOIS VOLTAR AO 1.

#include "FiveWin.ch"

function Main()

local oDlg, oGet1, oGet2

local cText1 := "primeiro"

local cText2 := "segundo"

local cText3 := "terceiro"

local cText4 := "quarto"

DEFINE DIALOG oDlg RESOURCE "Cycle"

REDEFINE GET oGet1 VAR cText1 ID 110 VALID funcao1() .and. funcao2() OF oDlg

REDEFINE GET oGet2 VAR cText2 ID 120 OF oDlg

REDEFINE GET cText3 ID 130 OF oDlg

REDEFINE GET cText4 ID 140 OF oDlg

REDEFINE BUTTON ID 150 OF oDlg ACTION oDlg:End()

ACTIVATE DIALOG oDlg CENTERED

return nil

//---

static function funcao1

local i

for i:=1 to 100

for y:=1 to 5000

next

next

return .t.

//---

static function funcao2

for i:=1 to 100

for y:=1 to 5000

next

next

return .F.

*** FIM DO PRG**

********TESTFOCO.RC***

#include "..\include\WinApi.ch"

cycle DIALOG 41, 42, 142, 79

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION "Cycling through GETs"

FONT 8, "Arial"

{

EDITTEXT 110, 8, 10, 63, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP

EDITTEXT 120, 8, 26, 71, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP

EDITTEXT 130, 8, 42, 62, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP

EDITTEXT 140, 8, 58, 80, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP

PUSHBUTTON "&End", 150, 112, 4, 24, 14

}

***** FIM DO TESTFOCO.RC *****

Link to comment
Share on other sites

Olá Pessoal,

Este é um problema do fivewin que de tanto eu bater a cabeça para resolve-lo, larguei prá lá.icon_smile_sad.gificon_smile_angry.gif Me disseram na epoca que eu tinha que mudar a classe tget para fazer a validação se não me engano no método keydown, mas não deu certo. Gostaria que alguém que entende um pouco de classes nos desse uma força pois o funcionamento correto evitaria vários problemas. No meu caso eu uso o combobox sempre que recebe o foco ele é aberto, só que se ouvesse um get anterior que não fosse valido o que acontecia ? O get perdia o foco, o combo se abria, fechava e depois voltava para o get. Cá pra nós... Muito amador não acham ??? O fivewin é uma excelente ferramenta em constante evolução, só que isto já deveria ter sido corrigido há anos atrás.

Bom pessoal é isso aí...

Abraços,

Rossine

FW 2.2c + @say + Clipper 5.2e + libs 5.3b / FWH 2.5 + @say + xHarbour Comercial

Link to comment
Share on other sites

Issu é estranho Lili, pois uso a mesma clase que vc....e tambem já migrei meu sistema para 32 bit.....e realmente issu não ocorre em nenhum dos meus (valids)....mesmo que digitado bem rapido.

poste o código real do teu sistema...pois o que vc postou não tem muita lógica...é apenas contagens.

poste o verdadeiro que testaremos e compararemos o problema que eu acho não existir no FWH.

um abraço.

A&F Soft

Clipper 5.2e Lib 5.3b Blinker 7 WorkShop Pelles FW, FWH, xHarbor Comercial, todos Última release

Link to comment
Share on other sites

  • 2 months later...

O Eroni acabou de incluir uma duvida igual. Tambem estou no aguardo de uma solução. Tive que fazer validaçoes extras (alem das valid dos get) para o erro nao ocorrer. Exemplo:

Na nota fiscal quando digita muito rapido passa cliente, vendedor, etc em branco, mesmo com valid nao permitindo isto, entao coloquei no botao de confirmacao, antes de gravar,para verificar se nao passou nenhum campo em branco e se passou faço voltar com setfocus no campo para ler novamente. Ufa!

Lia

Link to comment
Share on other sites

Olá Galera,

Isto realmente ocorre com o FWH. Façam o teste que o Rossine disse. Criem um get com o valid e logo em seguida coloquem um combo. Vcs perceberam que o combo chega a executar antes do get ter validado, dai vem a msg de erro que vc colocou no get, e pronto a merda ta feita. Realmente isto é muito AMADOR e nas outras (ferramentas de desenvolvimento, VB/Delphi) isto não acontece, e como disse o Rossine isto deve ser fácil de alterar nos fontes. Mas até hoje nada.

Um abraço,

Alexandre Pereira

fwh 2.4, xharbour, .99, HbMake

msn: alexpdasilva6@hotmail.com

Link to comment
Share on other sites

Olá Pessoal,

Fiz algumas mudanças na classe do fivewin para xharbour onde transfiro todo controle para a função "bChange". Lá eu trato Seta p/cima, baixo, ENTER, ESC, click do mouse e tudo mais. Funcionou 100% e o get é validado antes de perder o foco icon_smile_big.gif.

Além disto estou usando uma nova tecnologia do xharbour que é a sobreposição de classes do fivewin. Antes quando não usava isto, toda a vez que saía uma nova versão do fwh, eu tinha que fazer as mesmas mudanças nas classes do fwh e era um trabalho penoso icon_smile_sad.gif. Muitos talvez até usem o método citado abaixo, mas para os que não usam, vale a pena investir um pouco de tempo a mais e aprender a programar com este método. Bom, segue abaixo as mudanças que fiz na classes TGET do fivewin. Vejam bem, não é necessário mudar a classe TGET do fivewin. O que voces devem fazer é pegar o fonte a baixo e gerar um .PRG tipo "MYCLASS.PRG", linkar junto ao seu projeto e chamar a função MYCLASS() no início do programa. Aí o xharbour desconsidera a classe original do fwh e usa as suas mudanças apartir dali. Segue o código:

#include "FiveWin.ch"

#include "hbclass.ch"

#include "Constant.ch"

#include "Set.ch"

#include "wcolors.ch"

*****************

function MY_CLASS

*****************

override method KeyDown in class TGet with TGetKeyDown

override method KeyChar in class TGet with TGetKeyChar

override method LButtonDown in class TGet with TGetLButtonDown

extend class TGet with data lDrag

return NIL

//----------------------------------------------------------------------------//

*************************** TGet

static function TGetKeyDown( nKey, nFlags )

***************************

local Self := HB_QSelf()

local nHi, nLo, nPos, nLastHi := -1

::nLastKey = nKey

do case

case nKey == VK_TAB .or. ; && Tem de ter isto para nao processar

nKey == VK_RETURN && duas vezes em outra parte iterna do fivewin

&& Aqui trava tanto o TAB quanto SHIFT+TAB

return 0

case nKey == VK_UP

if Len( ::oWnd:aControls ) > 1

lAccept := .T.

if ::bChange != nil

lAccept = Eval( ::bChange, nKey, nFlags, Self )

endif

if ( ValType( lAccept ) == "L" .and. lAccept ) .or. .not. ValType( lAccept ) == "L"

if Upper( ::oWnd:ClassName() ) == "TCOMBOBOX"

::oWnd:oWnd:GoPrevCtrl( ::hWnd )

else

::oWnd:GoPrevCtrl( ::hWnd )

endif

return 1 && O Fivewin processa internamente o get

else

return 0 && O Fivewin NAO processa internamente o get

endif

endif

case nKey == VK_DOWN

if Len( ::oWnd:aControls ) > 1

lAccept := .T.

if ::bChange != nil

lAccept = Eval( ::bChange, nKey, nFlags, Self )

endif

if ( ValType( lAccept ) == "L" .and. lAccept ) .or. .not. ValType( lAccept ) == "L"

if Upper( ::oWnd:ClassName() ) == "TCOMBOBOX"

::oWnd:oWnd:GoNextCtrl( ::hWnd )

else

::oWnd:GoNextCtrl( ::hWnd )

endif

return 1

else

return 0

endif

endif

case nKey == VK_LEFT

if GetKeyState( VK_CONTROL )

::oGet:WordLeft()

else

::oGet:Left()

endif

::oGet:Pos = Max( ::oGet:Pos, 1 )

while .t.

CallWindowProc( ::nOldProc, ::hWnd, WM_KEYDOWN, nKey, nFlags )

::GetSelPos( @nLo, @nHi )

if nLo <= ::oGet:Pos - 1

EXIT

endif

end

::nPos = nLo + 1

if ::nPos < ::oGet:Pos

::SetPos( ::oGet:Pos )

else

::oGet:Pos = ::nPos

endif

return 0

case nKey == VK_RIGHT

nPos = ::oGet:Pos

if GetKeyState( VK_CONTROL )

::oGet:wordRight()

else

::oGet:right()

endif

if nPos <> ::oGet:Pos

while .t.

CallWindowProc( ::nOldProc, ::hWnd, WM_KEYDOWN, nKey, nFlags )

::GetSelPos( @nLo, @nHi )

if nHi + 1 >= ::oGet:Pos .or. ::lPassword .or. ;

nHi == nLastHi

EXIT

endif

nLastHi = nHi

end

::oGet:Pos = nHi + 1

::nPos = nHi + 1

endif

return 0

// Many thanks to HMP

case nKey == VK_INSERT .and. ! GetKeyState( VK_SHIFT ) ;

.and. ! GetKeyState( VK_CONTROL ) // to copy to the clipboard

Set( _SET_INSERT, ! Set( _SET_INSERT ) )

DestroyCaret()

if Set( _SET_INSERT )

CreateCaret( ::hWnd, 0, 6, ::nGetChrHeight() )

else

CreateCaret( ::hWnd, 0, 2, ::nGetChrHeight() )

endif

ShowCaret( ::hWnd )

return 0

case ( nKey == VK_INSERT .and. GetKeyState( VK_SHIFT ) ) .or. ;

( nKey == ASC("V") .and. GetKeyState( VK_CONTROL ) ) .or. ;

( nKey == ASC('X') .and. GetKeyState( VK_CONTROL ) )

if ! ::lReadOnly

CallWindowProc( ::nOldProc, ::hWnd, WM_KEYDOWN, nKey, nFlags )

SysRefresh()

if ValType( ::oGet:buffer ) = "C"

::oGet:buffer = Pad( GetWindowText( ::hWnd ), Len( ::oGet:buffer ) )

SetWindowText( ::hWnd, ::oGet:buffer )

else

::oGet:buffer = GetWindowText( ::hWnd )

endif

::oGet:Assign()

::GetSelPos( @nLo, @nHi )

::nPos = nHi + 1

::oGet:Pos = ::nPos

if ::bChange != nil

Eval( ::bChange, nKey, nFlags, Self )

endif

endif

return 0

case nKey == VK_HOME .or. nKey == VK_END

if GetKeyState( VK_SHIFT )

CallWindowProc( ::nOldProc, ::hWnd, WM_KEYDOWN, nKey, nFlags )

::GetSelPos( @nLo, @nHi )

::oGet:Pos = nLo + 1

::nPos = nLo + 1

else

if nKey == VK_HOME

::oGet:Home()

::SetPos( ::oGet:Pos )

endif

if nKey == VK_END

::oGet:End()

::SetPos( ::oGet:Pos )

endif

endif

return 0

case nKey == VK_DELETE .or. nKey == VK_BACK

if ::lReadOnly

return 0

endif

if ::lDrag

return ::Tcontrol:KeyDown( nKey, nFlags )

* ou assim -> return Self:Tcontrol:KeyDown( nKey, nFlags )

endif

::GetSelPos( @nLo, @nHi )

// Deletes selection

if nHi != nLo

::GetDelSel( nLo, nHi )

if GetKeyState( VK_SHIFT )

CallWindowProc( ::nOldProc, ::hWnd, WM_KEYDOWN, nKey, nFlags )

endif

else

*MUDEI AQUI - INICIO

if nKey == VK_DELETE

::oGet:Delete()

elseif nHi > 0

::oGet:BackSpace()

endif

endif

::EditUpdate()

if ::bChange != nil

Eval( ::bChange, nKey, nFlags, Self )

endif

*MUDEI AQUI - FIM

return 0

otherwise

if ::bChange != nil

lAccept = Eval( ::bChange, nKey, nFlags, Self )

if ValType( lAccept ) == "L" .and. ! lAccept

return 0

endif

endif

* if ::bChange != nil

* Eval( ::bChange, nKey, nFlags, Self )

* endif

endcase

#ifdef __XHARBOUR__

if ::bKeyDown <> nil

::Assign()

end

#endif /* __XHARBOUR__ GET*/

return ::Tcontrol:KeyDown( nKey, nFlags )

*return Self:Tcontrol:KeyDown( nKey, nFlags )

*************************** TGet

static function TGetKeyChar( nKey, nFlags )

***************************

local Self := HB_QSelf()

local nHi, nLo

local lAccept

local bKeyAction := SetKey( nKey )

local nDefButton

if ! Empty( ::cPicture ) .and. '@!' $ ::cPicture

nKey = Asc( Upper( Chr( nKey ) ) )

endif

if bKeyAction != nil .and. lAnd( nFlags, 16777216 ) // function Key

Eval( bKeyAction, ProcName( 4 ), ProcLine( 4 ), Self )

return 0 // Already processed, API do nothing

endif

if ::lReadOnly

if nKey == VK_ESCAPE

::oWnd:End()

endif

return 0

endif

do case

case nKey == VK_BACK // Already processed at KeyDown

return 0

//case nKey == VK_ESCAPE

// return 0

case nKey == VK_TAB .and. GetKeyState( VK_SHIFT )

lAccept := .T.

if ::bChange != nil

lAccept = Eval( ::bChange, nKey, nFlags, Self )

endif

if ( valType( lAccept ) == "L" .and. lAccept ) .or. .not. valType( lAccept ) == "L"

if Upper( ::oWnd:ClassName() ) == "TCOMBOBOX"

::oWnd:oWnd:GoPrevCtrl( ::hWnd )

else

::oWnd:GoPrevCtrl( ::hWnd )

endif

endif

return 0

case nKey == VK_TAB .or. nKey == VK_RETURN

if ::bChange != nil

lAccept = Eval( ::bChange, nKey, nFlags, Self )

if ValType( lAccept ) == "L" .and. lAccept

::oWnd:GoNextCtrl( ::hWnd )

endif

else

::oWnd:GoNextCtrl( ::hWnd )

endif

* MUDEI AQUI - INICIO

* #ifdef __HARBOUR__

* if lAccept .and. nKey == VK_RETURN // Execute DEFPUSHBUTTON Action

* ::Tcontrol:KeyChar( nKey, nFlags )

* endif

* #endif

* MUDEI AQUI - FIM

return 0

case nKey >= 32 .and. nKey < 256

#ifdef __HARBOUR__

// deadkey+tab [or enter] previously pressed will cause a r/t error

if ::oGet:buffer == nil

return 0

endif

#endif

::GetSelPos( @nLo, @nHi )

// Delete selection

if nHi != nLo

::GetDelSel( nLo, nHi )

::EditUpdate()

endif

if ::oGet:Type == "N" .and. ;

( Chr( nKey ) == "." .or. Chr( nKey ) == "," )

::oGet:ToDecPos()

else

* MUDEI AQUI - INICIO

* if ::bChange != nil

* lAccept = Eval( ::bChange, nKey, nFlags, Self )

* if ValType( lAccept ) == "L" .and. ! lAccept

* return 0

* endif

* endif

* MUDEI AQUI - FIM

if Set( _SET_INSERT ) // many thanks to HMP

::oGet:Insert( Chr( nKey ) )

else

::oGet:Overstrike( Chr( nKey ) )

end

endif

if ::oGet:Rejected

MsgBeep()

endif

::EditUpdate()

*MUDEI AQUI - INICIO

* ::assign()

* if ::oGet:TypeOut

* if ! Set( _SET_CONFIRM )

* ::oWnd:nLastKey = VK_RETURN // VK_DOWN 17/10/95

* ::oWnd:GoNextCtrl( ::hWnd )

* else

* MsgBeep()

* endif

* endif

if ::bChange != nil

lAccept = Eval( ::bChange, nKey, nFlags, Self )

if ValType( lAccept ) == "L" .and. ! lAccept

return 0

endif

endif

**MUDEI AQUI - FIM

otherwise

**MUDEI AQUI - INICIO

if ::bChange != nil

lAccept = Eval( ::bChange, nKey, nFlags, Self )

if ValType( lAccept ) == "L" .and. ! lAccept

return 0

endif

endif

**MUDEI AQUI - FIM

return ::Tcontrol:KeyChar( nKey, nFlags )

endcase

return 0

******************************* TGet

static function TGetLButtonDown( nRow, nCol, nFlags )

*******************************

local Self := HB_QSelf()

local nLo, nHi

if ::lDrag

return Super:LButtonDown( nRow, nCol, nFlags )

else

CallWindowProc( ::nOldProc, ::hWnd, WM_LBUTTONDOWN, nFlags,;

nMakeLong( nCol, nRow ) )

::GetSelPos( @nLo, @nHi )

::nPos = nHi + 1

if ::oGet:Type != "N" .and. ::nPos == 1

::oGet:Home()

::SetPos( ::oGet:Pos )

else

::oGet:Pos = ::nPos

endif

return 1

endif

if ::bLClicked != nil

return Eval( ::bLClicked, nRow, nCol, nFlags )

endif

return nil

//----------------------------------------------------------------------------//

Se alguém for utilizar estas mudanças e conseguir melhorá-la

ou corrigir algum BUG, favor postar a possível solução aqui.

Como fazer isto funcionar: em todo GET vocês teram que definir a chamada do bloco "bchange", tipo:

oget:bchange := { |nKey,oGet| CONTROLANDO_O_GET( nKey, oGet ) }

... No mais é isto aí. Testem e vejam se resolvem o problema de vocês. Eu sei que será um pouco complicado fazer estas mudanças em todos os códigos fontes de voces onde se referem ao GET, mas fazer o que ??? icon_smile_sad.gif. No meu caso em todo o meu sistema eu tenho toda classe definida uma única vez, ou seja, uso somente 1 get em todo meu sistema, aí fica fácil de alterar o sistema né ? icon_smile_big.gif

Abraços,

Rossine

FW 2.2c + @say + Clipper 5.2e + libs 5.3b / FWH 2.5 + @say + xHarbour Comercial 0.99.41

Link to comment
Share on other sites

Eu fiz algo parecido com a ultima tentativa de solução, mas ela só funciona quando já existe um get em foco ( a janela já está aberta), mas quando a janela está para se abrir e o usuário teclou rapidamente várias teclas, simplesmente continua pulando as validações. Experimentem acionar uma opção no programa de vocês com o teclado, sem usar o mouse, ao dar o ENTER na opção do menu rapidamente, teclem várias teclas muito rapidamente e ao abrir a janela vocês verão o que acontece, muitos gets pulados.

Ja tentei travar o teclado e só liberar depois de abrir a janela, mas em alguns computadores dá erro de gpf.

Eroni

(48) 437-4916

xHarbour 0.99.1 & FWH 2.4

SqlLib, MySql & Dbf

Link to comment
Share on other sites

Só para completar, eu já mexi nas classes tGet, tdialog e tWindow, mas tem hora que simplesmente não executa os metódos keychar/keydown e não se consegue saber qual tecla foi pressionada, sei lá o que acontece.

Eroni

(48) 437-4916

xHarbour 0.99.1 & FWH 2.4

SqlLib, MySql & Dbf

Link to comment
Share on other sites

Ola Lili, qual e a versão do xHarbour e a do FwH

Onde você vê um obstáculo alguém vê o término da viagem e o outro vê uma chance de crescer.

Elias Abrão Júnior

Fone : (0**11) 5181-6909 São Paulo - SP

eajunior.fw@terra.com.br

xHarbour 0.99.0 - Fivewin 2.5 e xMate

Link to comment
Share on other sites

Ola Lili, qual e a versão do xHarbour e a do FwH

Onde você vê um obstáculo alguém vê o término da viagem e o outro vê uma chance de crescer.

Elias Abrão Júnior

Fone : (0**11) 5181-6909 São Paulo - SP

eajunior.fw@terra.com.br

xHarbour 0.99.0 - Fivewin 2.5 e xMate

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...