Clipper On Line • Ver Tópico - Controles automaticos

Controles automaticos

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

 

Controles automaticos

Mensagempor Toledo » 25 Mar 2014 17:15

Paulo_CPV escreveu:Toledo ainda está dando erro

Você diz que dá um erro, mas não fala qual é o erro.
Toledo escreveu:mostre como você está montando o TEXTBOX e como está as funções de validação e SetConfOFF

Bom, você não passou qual é a função SetConfOFF, então vou presumir que seja a função que o Pablo postou na sua última mensagem.
Mas na função do Pablo (MiniGui Extended) faria apenas uma modificação:
Function SetConfOFF(cCampo)  //modifiquei esta linha
Local cFrmName   := ThisWindow.Name
Local cCmpName   := This.FocusedControl
Local x := GetControlIndex(cCmpName, cFrmName)
Local nMaxLength := _HMG_aControlRangeMax[x]
Local nInputMask := Len(_HMG_aControlInputMask[x])

If nInputMask > 0
   nMaxLength := nInputMask
Endif
If !Empty(cCampo)  //modifiquei esta linha
   If nMaxLength == GetProperty(cFrmName,cCmpName,"CaretPos")
      InsertTab()
   Endif
Endif
Return Nil


Toledo escreveu:volte a função de validação para ON ENTER

Como observei na minha mensagem anterior, você teria que voltar a função de validação para ON ENTER.
Em todos os exemplos que postei ou nos exemplos do Pablo, sempre utilizamos ON CHANGE (ou ON ENTER). Observe que tem um espaço depois de ON.
Paulo_CPV escreveu:::ValidarData( This.Value )

O que é estes dois pontos duplos antes do nome da função?
Paulo_CPV escreveu:IF nMes = 2

A sua função de validação de data só vai funcionar corretamente se o mês da data for fevereiro (2) e o dia tem que ser 28 ou 29, conforme ano bissexto. Qualquer outra data, vai ocorrer um erro, mesmo que a data esteja certa.

Bom, para que a validação e a função SetConfOFF() funcione, faça o seguinte:

1 - utilize a função SetConfOFF() que postei acima.
2 - altere a sua função de validação de data por esta:

Function ValidarData( cData )
Local lRet:=.T.
if Empt(cData)
MSGINFO("Data digitada incorreta ! Por favor digite novamente.")
cFrmName := thiswindow.name
cCmpName := this.focusedcontrol
SETFOCUS &(cCmpName) OF &(cFrmName)
endif
Return (lRet)

Observação: quando a data não for válida (por exemplo: 31/02/2014) o foco vai continuar no campo.

3 - no TextBox use:

        ON ENTER { || ValidarData(This.Value) }
        ON CHANGE {|| SetConfOFF(This.Value) }

Acho que isto vai resolver.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Controles automaticos

Mensagempor Paulo_CPV » 25 Mar 2014 20:21

Boa noite!

Toledo não abusar muito de você, será que tem como eu mudar de cor do TEXTBOX deferemciando do que não foi digitado ainda?

Abraços,

Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Controles automaticos

Mensagempor Toledo » 25 Mar 2014 21:15

Amigo, não sei se entendi direito o seu pedido, mas segue um exemplo:

#include "minigui.ch"

Function Main()

SET NAVIGATION EXTENDED

   DEFINE WINDOW Form_1 ;
      AT 0,0 ;
      WIDTH 400 HEIGHT 300 ;
      TITLE 'Exemplo de Controle de Focus' ;
      MAIN

      DEFINE LABEL Label_1
        ROW   10
        COL   10
        WIDTH   60
        VALUE 'Campo 1:'
      END LABEL

      DEFINE TEXTBOX Text_1
        ROW   10
        COL   70
        WIDTH   180
        ON GOTFOCUS {|| Set_Cor(.T.) }
        ON ENTER {|| Set_Cor(.F.) }
      END TEXTBOX

      DEFINE LABEL Label_2
        ROW   38
        COL   10
        WIDTH   60
        VALUE 'Campo 2:'
      END LABEL

      DEFINE TEXTBOX Text_2
        ROW   38
        COL   70
        WIDTH   180
        ON GOTFOCUS {|| Set_Cor(.T.) }
        ON ENTER {|| Set_Cor(.F.) }
      END TEXTBOX

      DEFINE LABEL Label_3
        ROW   66
        COL   10
        WIDTH   60
        VALUE 'Campo 3:'
      END LABEL

      DEFINE TEXTBOX Text_3
        ROW   66
        COL   70
        WIDTH   180
        ON GOTFOCUS {|| Set_Cor(.T.) }
        ON ENTER {|| Set_Cor(.F.) }
      END TEXTBOX

   END WINDOW

   Form_1.Center
   Form_1.Activate

Return Nil

************************************
Func Set_Cor(lAltCor)
   cFrmName := thiswindow.name
   cTxBName := this.focusedcontrol
   if lAltCor
    SetProperty( cFrmName, cTxBName, "BackColor", {255,255,192} )
   else
    SetProperty( cFrmName, cTxBName, "BackColor", {255,255,255} )
   endif
Return .T.

No exemplo acima o comando Set_Cor(.T.) muda a cor de fundo do textbox para amarela, e Set_Cor(.F.) volta para cor branca.

Atenção: se você já estiver usando em ON GOTFOCUS ou ON ENTER alguma outra função, então chame o Set_Cor() antes da função. Por exemplo:
        ON ENTER {|| Set_Cor(.F.) , ValidarData(This.Value) }


Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Controles automaticos

Mensagempor Pablo César » 26 Mar 2014 08:14

Nossa ! Quê paciência, Toledo ! afff

Paulo, antes de postar. Pesquise, procure aprender pelos exemplos...
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar de usuário

Pablo César
Usuário Nível 7

Usuário Nível 7
 
Mensagens: 5312
Data de registro: 31 Mai 2006 10:22
Cidade/Estado: Curitiba - Paraná
Curtiu: 142 vezes
Mens.Curtidas: 152 vezes

Controles automaticos

Mensagempor Paulo_CPV » 27 Mar 2014 11:18

Bom dia!

Me desculpe Toledo, Pablo por atrapalhar vocês com as meus problemas simples, mas fiz todas as pesquisas e não estou encontrando o que está dando erro em minha rotina de validação. A validação dos campos data já resolvi estão funcionando perfeitamente em conjunto com a função que o Toledo me passou e ajustei nas minhas necessidades. Mas agora estou tentando validar o número do PIS do funcionário, bem o cálculo está fazendo corretamente.

Mas quando deixo em branco ao invés de mostrar a mensagem "Campo em branco, digite novamente" ele cai na segunda opção de erro "O PIS de número: " + cNit + " é inválido !" e quando digito um número de PIS que não confere e vai para o próximo TextBox e não fica no TextBox para ser editado. O que eu estou fazendo de errado? Segue trecho da rotina para análise dos Srs. Espero não ter mais dificuldades como está que estou tendo.

#DEFINE M_NIT  "999.999.999-99"

       DEFINE TEXTBOX text_1

         ROW      50
         COL      20
         WIDTH    120
         HEIGHT   20
         FONTNAME "Arial"
         FONTSIZE 9
         FONTBOLD .T.
         FONTCOLOR PRETO
         INPUTMASK M_NIT
         BACKCOLOR BK_TEXTO3
         ONENTER       { || IF( ValidarNit( This.Value ) = .F. , Janela10.Text_1.SetFocus , Janela10.text_2.SetFocus ) }
    ONCHANGE      { || SetConfOFF( This.Value ) }
       
       END TEXTBOX
//-----------------------------------------------------
FUNCTION ValidarNit( cNit )

   LOCAL cPeso  , nParcial , x , nResult2 , cResult , cPis , cParte
   LOCAL cDigito , cNum , lRet := .T.

   cPis := ALLTRIM( CHARREM( '. -' , cNit ) )
   
   cPeso   := "3298765432"
   cParte   := SUBSTR( cPis , 1 , 10 )
   nParcial := 0
   nResult2 := 0
//------------------------------- Calculo do digito   
   FOR x = 1 TO 10

      nParcial := nParcial + ( VAL ( SUBSTR( cParte , x ,1 ) ) * VAL( SUBSTR ( cPeso , x , 1 ) ) )
   
   NEXT x
//--------------------------------- Calculo
   nResult2 := MOD( nParcial , 11 )
   cDigito  := IF( nResult2 = 10 .OR. nResult2 = 11 , "0" , STR( INT( nResult2 ) , 1 ) )   
//--------------------------------- Resultado
   cResult  := cParte + cDigito
   cNum    := EVAL( MascaraCpf() , cResult )
//--------------------------------- Validacao
   IF EMPTY( cPis )
   
      MSG_ERRO("Campo NIT não pode ser em branco.")
      lRet := .F.
     
   ENDIF
   
   IF cPis <> cNum
     
      MSG_ERRO( "Número do NIT: " + cNit + "não confere!" )
      lRet := .F.     
     
   ENDIF
     
RETURN( lRet )

FUNCTION MascaraCpf()

RETURN({|x| IF(LEN(x) = 14 , x , SUBSTR(x,1,3)+"."+SUBSTR(x,4,3)+"."+SUBSTR(x,7,3)+"-"+SUBSTR(x,10,2))})



Abraços,

Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Controles automaticos

Mensagempor Pablo César » 27 Mar 2014 11:57

Olha Paulo, vou comentar sobre a minha opinião mais uma vez e não tem problema em apresentar as suas dúvidas desde que sejam agotadas as suas pesquisas. Basicamente refiro-me, que existe uma forte tendência de esperar que os outros resolvam os nossos problemas por falta de conhecimento. Mas o que eu tenho notado que você abre uma questão e quando é resolvida, você abre a seguir uma nova... pareceria que o objetivo é resolver todos os problemas da sua aplicação. Como eu disse, não tem problema, mas veja que existem situações que não precisaria ser apresentadas como: falha, como deficiência ou carência de perfeição. O que importa é que seu aprendizado seja concluído e não a melhora da sua rotina em si. Entendeu ?

Tem mais um ponto de opinião que acho muito relevante faze-lo notar. Alguns programadores, tem como antigo hábito, verificar se o campo/variável foi preenchida antes de acionar a pesquisa da informação. Não está em si errado que isso deva ser verificado. Apenas observo que na programação GUI, não deva seguir o mesmo conceito que fazíamos em Clipper. Pois estamos tratando com objetos e não de forma sequencial. Portanto, se você tem um botão que irá acionar a pesquisa, coisa que isto não acontecia em Clipper, apenas era acionado quando preenchido o campo, então tal verificação ou chamada da rotina de verificação, você o faz dentro da mesma rotina que irá localizar a informação. Se você tem um panorama diferente ao do console, em que o usuário pode vir a optar a fazer foco em forma aleatória (não sequencial) do preenchimento dos campos, ora através pelo mouse, por quê cargas d'aguas precisa obrigar ao usuário preencher o campo na sequência ?

Você está me entendendo ? Creio eu, que não há necessidade de manter o mesmo conceito que tínhamos na programação console para GUI. Tem de haver mudanças, inclusive da parte dos seus usuários também.

Bom esta é a minha opinião, pode vir a diferir de alguém, mas gostaria que expressassem a verdadeira necessidade de preenchimento obrigatório e sequencial...
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar de usuário

Pablo César
Usuário Nível 7

Usuário Nível 7
 
Mensagens: 5312
Data de registro: 31 Mai 2006 10:22
Cidade/Estado: Curitiba - Paraná
Curtiu: 142 vezes
Mens.Curtidas: 152 vezes

Controles automaticos

Mensagempor Toledo » 27 Mar 2014 19:45

Amigo Paulo, a melhor coisa é procurar conhecer o que está fazendo, e sempre que ocorrer algo que não está dando certo é bom analisar linha a linha para ver onde está o problema.

Então vamos analisar o seu código junto comigo:

1 - (Neste caso de uso do "SetConfOFF") O uso do ON ENTER em um TextBox para validar principalmente PIS, CPF, CNPJ, CEP, etc, onde você vai digitar o espaço completo disponível no TextBox, o correto seria ao final da digitação pressionar o ENTER para chamar a função de validação. No caso do uso do SetConfOFF(), isto não acontece, a tecla ENTER não é pressionada e sim é usado InsertTab() (simula o TAB) para ir para o próximo TextBox. Então neste caso o uso do ON ENTER não vai dar certo, sobrando apenas o uso do ON LOSTFOCUS.

2 - Você afirma que o cálculo da sua função de validação está correta:
Paulo_CPV escreveu: Mas agora estou tentando validar o número do PIS do funcionário, bem o cálculo está fazendo corretamente.

Provavelmente você não conferiu se realmente a função esta funcionando corretamente, vamos analisar esta sua função. Vamos supor que eu tenha digitado o seguinte PIS: 120.840.680-04

cPis := ALLTRIM( CHARREM( '. -' , cNit ) )

Resultado: 12084068004
   FOR x = 1 TO 10
      nParcial := nParcial + ( VAL ( SUBSTR( cParte , x ,1 ) ) * VAL( SUBSTR ( cPeso , x , 1 ) ) )
   NEXT x

Resultado:
nParcial=1x3 + 2x2 + 0x9 + 8x8 + 4x7 + 0x6 + 6x5 + 8x4 + 0x3 + 0x2
nParcial=161
nResult2 := MOD( nParcial , 11 )

Resultado: 7
cDigito  := IF( nResult2 = 10 .OR. nResult2 = 11 , "0" , STR( INT( nResult2 ) , 1 ) )

Resultado: 7
   cResult  := cParte + cDigito
   cNum    := EVAL( MascaraCpf() , cResult )

Resultado: 120.840.680-07

Bom, diante dos cálculos acima, a "tradução" da linha abaixo será:
IF cPis <> cNum

Tradução: IF 12084068004 <> 120.840.680-07

Bom, diante disto, não é correto a sua afirmação de que o cálculo está fazendo corretamente. E além do dígito não estar certo, a função está comparando o número do PIS sem pontos ( cPis ) com um outro ( cNum ) com os pontos, então esta função nunca iria validar o PIS.

Para calcular o dígito corretamente, depois da linha:
nResult2 := MOD( nParcial , 11 )

Incluir:
nResult2 := 11 - nResult2

As linhas abaixo também estão no lugar errado:
   IF EMPTY( cPis )
      MSG_ERRO("Campo NIT não pode ser em branco.")
      lRet := .F.
   ENDIF

O correto seria colocar logo depois da linha:
cPis := ALLTRIM( CHARREM( '. -' , cNit ) )

Evitando assim fazer o cálculo sem necessidade.
Neste caso eu trocaria o lRet := .F. por Return (.F.).

Bom, agora é só você analisar tudo o que foi exposto acima e corrigir o seu código.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Controles automaticos

Mensagempor alxsts » 27 Mar 2014 20:53

Olá!

O que mais me chama a atenção neste código é a linha
cNum    := EVAL( MascaraCpf() , cResult )
Desde os primórdios do Clipper 5, sabe-se que Eval() recebe um code-block como primeiro parâmetro. Interessante... está recebendo o resultado de uma função que retorna um code-block e depois faz o Eval(). Nunca havia pensado nisso.

Mas é gastar muita lenha para uma pequena fogueira.
cNum    := Transform( cResult, "@R 999.999.999-99" )
resolveria o problema.
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2945
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Controles automaticos

Mensagempor Paulo_CPV » 28 Mar 2014 11:45

Bom dia!

Pablo obrigado pelas suas considerações, concordo com tudo o que você me disse. Procurarei me empenhar mais em postar os meus tópicos aqui no Forum e só quando eu esgotei as minhas consultas aqui ou em outro lugar desta imensa Internet.

E em questão de eu tenha que validar certos controles é porque como trabalho num órgão público e temos que informar certos dados ao INSS estes campos tem ser corretamente digitados.

Ainda não consegui resolver algumas validações aqui, mas vou batalhar aqui e quando eu tiver uma solução postarei o resultado que eu encontrei.

Abraços,

Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Controles automaticos

Mensagempor Pablo César » 28 Mar 2014 13:34

Quê bom Paulo que você entendeu sem ter ficado chateado ou constrangido, ao final de contas todos somos eternos aprendizes. :)

Paulo_CPV escreveu:E em questão de eu tenha que validar certos controles é porque como trabalho num órgão público e temos que informar certos dados ao INSS estes campos tem ser corretamente digitados.
Acho que você não entendeu a minha colocação. Veja, eu não disse não fazer validação do que foi digitado. Apenas acho que não é necessário que ocorra na mesma situação que fazíamos em Clipper ou em modo console (como queira chamar). Isto porque você está obrigando ao usuário digitar algo no campo e a programação GUI (gráfica) trata tudo por objetos, tal é assim que por causa da existência do mouse, o usuário normalmente pode vir a focar, alternar/pular os campos. Você só precisa fazer a validação no momento certo.

Só para que você entenda, tem outro tópico que falo sobre esta questão, veja o demo que disponibilizei nesta mensagem e você irá notar que houve um cambio de conceitos.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar de usuário

Pablo César
Usuário Nível 7

Usuário Nível 7
 
Mensagens: 5312
Data de registro: 31 Mai 2006 10:22
Cidade/Estado: Curitiba - Paraná
Curtiu: 142 vezes
Mens.Curtidas: 152 vezes

Controles automaticos

Mensagempor Toledo » 30 Mar 2014 11:35

Amigos, esta simulação do "SET CONFIRM OFF" usada no ON CHANGE em conjunto com alguma outra função de validação no ON ENTER não estava dando certo, pois se o TextBox for preenchido completamente a função SetConfOFF() era executada e passava o foco para o próximo campo sem executar a função de validação do ON ENTER.
Bom, numa primeira avaliação achei que a solução seria mudar a função de validação de ON ENTER para ON LOSTFOCUS, mas como o Pablo observou a validação ocorre mesmo se o programa for minimizado ou alguma outra aplicação é selecionada. Então a única saída seria colocar a função de validação dentro da função SetConfOFF(), mas por se tratar de uma função que pode ser usada em vários campos TextBox em um mesmo formulário, também ficaria complicado fazer isto, você teria que colocar todas as funções de validação no SetConfOFF(), e a função ficaria enorme.

Mas consegui dar um jeito nisto, seja o demo em anexo.

Abraços,
Anexos
setconfoff.zip
Este exemplo é para MiniGui Extended
(639.03 KiB) Baixado 105 vezes
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Controles automaticos

Mensagempor Pablo César » 09 Abr 2014 00:32

Oi Toledo,

Lembra de algumas propriedades que a MiniGui tem mesmo que em forma de informação guardada em vetores e a HMG não tem ? Tais como estas:

_HMG_aControlRangeMax
_HMG_aControlInputMask
_HMG_aControlDblClick

Bom, sempre há um jeito de fazer as coisas. Um dessas propriedades consegui através do uso de API e as outras que se armazena também em vetor ( _HMG_SYSDATA ). Então consegui elaborar as funções de controle e queria compartilhar com vocês:

#include <hmg.ch>

Function Main()
SET NAVIGATION EXTENDED
SET DATE TO BRITISH
SET CENTURY ON

DEFINE WINDOW Form_1 AT 0,0 ;
    WIDTH 400 HEIGHT 175 NOSIZE ;
    TITLE 'Simulating SET CONFIRM OFF at TextBoxes' ;
    MAIN
   
    ON KEY ESCAPE ACTION ThisWindow.Release()
   
    DEFINE STATUSBAR FONT "Courier New" SIZE 9
        STATUSITEM PadC("Press <Insert> key and type again",44)
        STATUSITEM " Insert" WIDTH 94 ICON if ( IsInsertActive() , "zzz_led_off" , "zzz_led_on" )
    END STATUSBAR
   
    DEFINE LABEL Label_1
        ROW   20
        COL   30
        WIDTH 160
        VALUE 'Field 1 (Length 10):'
        FONTBOLD .T.
    END LABEL

    DEFINE TEXTBOX Text_1
        ROW       20
        COL       160
        WIDTH     180
        MAXLENGTH 10
        ON CHANGE {|| SetConfOFF() }
      ON ENTER {||Test_Enter()}
    END TEXTBOX

    DEFINE LABEL Label_2
        ROW    48
        COL    30
        WIDTH  160
        VALUE 'Field 2 (Length 10):'
        FONTBOLD .T.
    END LABEL

    DEFINE TEXTBOX Text_2
        ROW   48
        COL   160
        WIDTH   180
        DATE .T.
        ON CHANGE {|| SetConfOFF() }
    END TEXTBOX

    DEFINE LABEL Label_3
        ROW   76
        COL   30
        WIDTH 160
        VALUE 'Field 3 (Length 14):'
        FONTBOLD .T.
    END LABEL

    DEFINE TEXTBOX Text_3
        ROW     76
        COL     160
        WIDTH   180
        INPUTMASK "999.999.999-99"
        ON CHANGE {|| SetConfOFF() }
    END TEXTBOX
   
    _DefineTimer ( 'StatusKeyBrd' , "Form_1" , 50 , ;
        {|| _SetStatusIcon ( 'StatusBar' , "Form_1" , 2 , if ( IsInsertActive() , "zzz_led_off" , "zzz_led_on" ) ) } )

END WINDOW
CREATE EVENT PROCNAME OnkeyAllEditBox()
Form_1.Center
Form_1.Activate
Return Nil

Function SetConfOFF()
Local cFrmName   := ThisWindow.Name
Local cCmpName   := This.FocusedControl
Local cMask := GetTextBoxMask(cCmpName,cFrmName)
Local nMaxLength := GetTextBoxMaxLength(cCmpName,cFrmName)
Local bEnter     := GetTextBoxEnter(cCmpName,cFrmName)
Local nInputMask := Len(cMask)

If nInputMask > 0
   nMaxLength := nInputMask
Endif
If !Empty(cCmpName)
   If nMaxLength == GetProperty(cFrmName,cCmpName,"CaretPos")
      If ValType( bEnter ) != 'U'
         If ValType( bEnter ) == 'B'
            If Eval( bEnter )
              _SetNextFocus()
            Endif
         Else
            _SetNextFocus()
         Endif
      Else
         _SetNextFocus()
      Endif
   Endif
Endif
Return Nil

Function GetTextBoxMask(cCmpName,cFrmName)
Local nIndex, cMask:=""

If !Empty(cCmpName)
   nIndex := GetControlIndex (cCmpName,cFrmName)
   cMask := (_HMG_SYSDATA [  9 ] [nIndex])
Endif
Return cMask

#define EM_GETLIMITTEXT      213

Function GetTextBoxMaxLength(cCmpName,cFrmName)
Local nControlHandle
Local nMaxLength := 0

If !Empty(cCmpName)
   nControlHandle := GetControlHandle( cCmpName, cFrmName )
   If nControlHandle>0
      nMaxLength := SendMessage(nControlHandle, EM_GETLIMITTEXT, 0, 0)
      If nMaxLength = 30000
         nMaxLength := 0
      Endif
   Endif
Endif
Return nMaxLength

Function GetTextBoxEnter(cCmpName,cFrmName)
Local nIndex, bEnter:=""

If !Empty(cCmpName)
   nIndex := GetControlIndex (cCmpName,cFrmName)
   bEnter := _HMG_SYSDATA [ 16 ] [nIndex]
Endif
Return bEnter

Function OnkeyAllEditBox()
Local nIndex := GetControlIndexByHandle (EventHWND())

If nIndex > 0 .AND. GetControlTypeByIndex (nIndex) == "TEXT"
   If EventMSG() == WM_CHAR
      If .NOT. (GetKeyState (VK_INSERT) == 0) .AND. HMG_GetLastVirtualKeyDown() != VK_RETURN .AND. HMG_GetLastVirtualKeyDown() != VK_BACK
         SendMessage (EventHWND(), WM_KEYDOWN, VK_DELETE, 0)
         KSETINS(.T.)
      Else
         KSETINS(.F.)
      Endif
   Endif
Endif
Return Nil

Function Test_Enter()
MsgInfo("Test, ok !")
Return .T.
Basei-me no seu ultimo exemplo e observando como foi obtido as informações no Minigui. A obtenção do EM_GETLIMITTEXT foi mérito próprio consultando internet. Bom espero que sirva para algo.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar de usuário

Pablo César
Usuário Nível 7

Usuário Nível 7
 
Mensagens: 5312
Data de registro: 31 Mai 2006 10:22
Cidade/Estado: Curitiba - Paraná
Curtiu: 142 vezes
Mens.Curtidas: 152 vezes

Controles automaticos

Mensagempor Toledo » 09 Abr 2014 09:44

Parabéns Pablo!

Quando postei a solução para MiniGui, tentei converter para HMG, mas não consegui pegar o MaxLength, pois o HMG não guarda qualquer referência sobre MaxLength no _HMG_SYSDATA, usa um função em C para limitar o espaço de edição diretamente no Form. Na época encontrei um post do Dr. Claudio Soto (http://www.hmgforum.com/viewtopic.php?f=6&t=3056) que falava sobre o assunto, mas usava a variável EM_LIMITTEXT 197. Nos testes que fiz usando esta variável não deu certo, não retornava o MaxLength corretamente. Trocando para EM_GETLIMITTEXT 213 que está no seu exemplo, funcionou certinho.

Function SetConfOFF(cCampo)
Local cFrmName   := ThisWindow.Name
Local cCmpName   := This.FocusedControl
LOCAL nDigitado  := 0
Local nMaxLength := 0
Local nInputMask := 0
If ValType(cCampo) == 'D'
  nDigitado  := len(alltrim( StrTran(DTOC(cCampo),"/","") ))
  nMaxLength := 10
ElseIf ValType(cCampo) == 'N'
  nDigitado  := len(alltrim( StrTran(str(cCampo,20,6),".","") ))
  nMaxLength := 0
Else
  nDigitado  := len(alltrim( CHARREM( '. - /' ,cCampo )))
  nMaxLength := Len(cCampo)
Endif
If nDigitado>0
  x := GetControlIndex(cCmpName,cFrmName)
  nMaxLength := SendMessage( _HMG_SYSDATA [3] [x] , 213, 0 , 0 )
  nMaxLength := IF(nMaxLength>10000,0,nMaxLength)
  IF _HMG_SYSDATA [1] [x] == "CHARMASKTEXT"
    nInputMask := Len(_HMG_SYSDATA [  9 ] [x])
  ENDIF
  If nInputMask > 0
    nMaxLength := nInputMask
  Endif
  If !Empty(cCampo)
    If nMaxLength == GetProperty(cFrmName,cCmpName,"CaretPos")
      If ValType( _HMG_SYSDATA [ 16 ]  [x] ) != 'U'
        If ValType( _HMG_SYSDATA [ 16 ]  [x] ) == 'B'
          If Eval( _HMG_SYSDATA [ 16 ]  [x]  )
            _SetNextFocus()
          Endif
        Else
          _SetNextFocus()
        Endif
      Else
        _SetNextFocus()
      Endif
    Endif
  Endif
Endif
Return Nil


Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Controles automaticos

Mensagempor wagnerjsc » 09 Abr 2014 16:57

Boa tarde a todas aproveitando o Tópico, testei SET CONFIRM OFF em um TextBox em alguns exemplos e deu certo.
Gostaria de saber se é possivel usuário voltar para o TEXTBOX anterior
teclando ceta pra cima ? e se poderia ser postando um exemplo.

E ja deixo o meu obrigado a todos os amigos do forum que estão contribuindo
muito para meu aprendizado!

Abraço

wagner
wagnerjsc
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 12
Data de registro: 24 Jan 2014 08:11
Cidade/Estado: limeira sp
Curtiu: 2 vezes
Mens.Curtidas: 0 vez

Controles automaticos

Mensagempor Toledo » 09 Abr 2014 18:20

Amigos, segue um exemplo de UP BackFocus:

#include "minigui.ch"

Function Main()

SET NAVIGATION EXTENDED

DEFINE WINDOW Form_1 ;
    AT 0,0 ;
    WIDTH 400 HEIGHT 300 ;
    TITLE 'Simulando SET CONFIRM OFF e UP BackFocus' ;
    MAIN

    DEFINE LABEL Label_1
       ROW   10
        COL   10
        WIDTH   60
        VALUE 'Campo 1:'
    END LABEL

    DEFINE TEXTBOX Text_1
        ROW   10
        COL   70
        WIDTH   180
        MAXLENGTH 20
        ON CHANGE {|| SetConfOFF(This.Value) }
    END TEXTBOX

    DEFINE LABEL Label_2
        ROW   38
        COL   10
        WIDTH   60
        VALUE 'Campo 2:'
    END LABEL

    DEFINE TEXTBOX Text_2
        ROW   38
        COL   70
        WIDTH   180
        MAXLENGTH 10
        ON CHANGE {|| SetConfOFF(This.Value) }
    END TEXTBOX

    DEFINE LABEL Label_3
        ROW   66
        COL   10
        WIDTH   60
        VALUE 'Campo 3:'
    END LABEL

    DEFINE TEXTBOX Text_3
        ROW   66
        COL   70
        WIDTH   180
        INPUTMASK "999.999.999-99"
        ON CHANGE {|| SetConfOFF(This.Value) }
    END TEXTBOX

END WINDOW

On Key UP Of Form_1 Action KeyUP()  //Obrigatório
Form_1.Center
Form_1.Activate

Return Nil

************************************
Function SetConfOFF(cCampo)
Local cFrmName   := ThisWindow.Name
Local cCmpName   := This.FocusedControl
Local x := GetControlIndex(cCmpName, cFrmName)
Local nMaxLength := _HMG_aControlRangeMax[x]
Local nInputMask := Len(_HMG_aControlInputMask[x])
If nInputMask > 0
   nMaxLength := nInputMask
Endif
If !Empty(cCampo)
   If nMaxLength == GetProperty(cFrmName,cCmpName,"CaretPos")
      If ValType( _HMG_aControlDblClick [x] ) != 'U'
        If ValType( _HMG_aControlDblClick [x] ) == 'B'
          If Eval( _HMG_aControlDblClick [x]  )
            _SetNextFocus()
          Endif
        Else
          _SetNextFocus()
        Endif
      Else
        _SetNextFocus()
      Endif
   Endif
Endif
Return Nil

**************************************
Proc KeyUP()
Local cFrmName   := ThisWindow.Name
Local cCmpName   := This.FocusedControl
Local x := GetControlIndex(cCmpName, cFrmName)
If x>1
  x-=1
  Do While (x>0)
    If (_HMG_aControlType[x] $ [NUMTEXT-TEXT-MASKEDTEXT-CHARMASKTEXT-GETBOX])
      cCmpName := _HMG_aControlNames[x]
      SETFOCUS &(cCmpName) OF &(cFrmName)
      Exit
    Endif
    x-=1
  Enddo
Endif
Return


Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Anterior Próximo



Retornar para MiniGui

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 10 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro