Contar caracteres no Memoedit() do Xharbour 1.2.1

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

Moderador: Moderadores

Ceb
Usuário Nível 1
Usuário Nível 1
Mensagens: 14
Registrado em: 16 Set 2015 09:55
Localização: Alegre/ES

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Ceb »

Boa noite!

Preciso editar um texto do zero ou pegá-lo num campo de algum dbf, porém, preciso saber a quantidade de caracteres assim que chamar o Memoedit() e a medida de vou editando, ele vai atualizando este valor, considerando espaços dentro do texto. Resumindo, preciso limitar X caracteres para estes texto.

Desde já, agradeço pela ajuda.

Att,

Ceb
Avatar do usuário
Vander
Usuário Nível 3
Usuário Nível 3
Mensagens: 214
Registrado em: 23 Jul 2004 01:43
Localização: João Monlevade - MG

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Vander »

HbMake v1.17
xHarbour build 0.99.70 Intl. (SimpLex)
Borland C++ 5.5.1
fivewin 6.12 (FREE)
Workshop 4.5
MEdit
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por asimoes »

A função Len() faz o que você está querendo.

Ex.>

Código: Selecionar todos

cVar:="HELLO WORLD"

nLen:=Len(cVar)

cVar += " ALO MUNDO"

nLen:=Len(cVar)

cVar += TABELA->Campo

nLen:=Len(cVar)

? nLen

If nLen > 100
   Alert("Ops chegou a 100 caracteres")
Endif
►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
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Jairo Maia »

Olá Pessoal,

Creio que isso não é possível.

Mesmo considerando que é possível saber a linha e coluna do cursor no texto, nem mesmo assim daria para fazer esse controle. Por exemplo se tentar controlar pelo número de linhas e número de colunas na UDF (User defined Function), a linha e coluna é a linha e coluna do cursor. Então se após digitar algumas linhas se o usuário voltar o cursor e continuar digitando, o texto ficará maior que o pretendido, bem como ele pode acrescentar conteúdo de uma variável de um campo memo já existente.

Se o limite é realmente necessário usando o MemoEdit(), não há outra forma a não ser colocá-lo dentro de um laço, e checar se excedeu ou não após sair do memo, tratar, e se for o caso emitir a mensagem ao usuário para corrigir e dar um loop. Tentando explicar seria algo como isso:

Código: Selecionar todos

Function Main()
  
 Local nMeuLimite := 100 

 Do While .t.      

  cTexto := MemoEdit( cTexto, 1, 1 , MaxRow()-1, MaxCol()-1, .T., "FuncaoDoUsuario" )

  cTexto := RTrim( cTexto )

  If Len( cTexto ) > nMeuLimite
   Hb_Alert( "Limite Excedido. Máximo permitido: " + Hb_NToS( nMeuLimite ) )
   Loop
  Else
   Replace cCampoMemo With cTexto
  EndiF

  Exit

 EndDo

Return Nil
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por asimoes »

Outra opção seria criar Gets considerando o tamanho máximo a ser digitado:

Ex.: Só poderá digitar até o limite de 150 caracteres.

Código: Selecionar todos

cGet1:=Space(50)
cGet2:=Space(50)
cGet3:=Space(50)

@ 10,00 GET cGet1 PICTURE "@!"
@ 11,00 GET cGet2 PICTURE "@!"
@ 12,00 GET cGet3 PICTURE "@!"
READ

►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
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Eolo »

Creio que isso não é possível.
É possível, sim.

Quando vc inclui uma função de usuário, ela passa a controlar a Memoedit, então dá pra checar em tempo real o limite de caracteres. Eu uso isso campos memo.

Um exemplo, simples e incompleto:

(é só um exemplo, não é pra copiar e colar. O exemplo no help do xHarbour tem o que falta)

Código: Selecionar todos

*...
cTexto:=MemoEdit(cTexto,1,1,MaxRow()-1,MaxCol()-1,.T.,"XPTO" )
*...

function xpto
priv tam:=len(cTexto), limite:=100
priv l:=laskey()
if l=… A_Z, 0_9 ou outros caracteres permitidos
  if (tam+1)>limite
    * Mensagem: Limite atingido
    Retu 32 
  else  
    tam:=tam+1
  endi
elseif l=8 // backspace
   if tam>0
     tam=tam-1
   endi
endi
* faltam os outros RETU...
etc.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Jairo Maia »

Olá Eolo,

Isso cai no que eu disse anteriormente. Mas se houver algum exemplo que eu possa em tempo de execução, ou seja, em tempo de digitação avisar sobre o limite, passarei a usar. Seria muito legal.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Eolo »

Tá no exemplo que eu postei.

Seguinte: quando vc inclui uma função de usuário, tudo o que for digitado na janela do Memoedit passa pelo controle da função, que aí retorna alguma coisa pro Memoedit.

Então, no meu exemplo, se você digita a letra J, a variável tam assume 1, a Memoedit mostra o J na janela e continua a execução (iddle). Em seguida, vc digita A e tam vira 2. Digita E, indevidamente, e tam vira 3. Mas aí vc corrige, pressiona Backspace, o E é apagado e tam volta pra 2. Etc etc.

Quando vc tecla CRTL W ou alguma outra tecla pra salvar e sair (eu uso F10), a função de usuário avisa a Memoedit que é pra encerrar o jogo.


Então, essa variável tam, controlada pela função do usuário, é quem vai dizer quando o limite (que vc definir) for atingido.

1. No meu exemplo, se tam+1 for maior que o limite, você refuga a entrada e soca um alerta na tela: “limite atingido”. Esse alerta é gerado dentro da função de usuário.

2. Quer ver quantos caracteres são, à medida em que forem digitados, em tempo real? Inclua “@24,0 say tamanho” no final da função de usuário. A cada letra digitada, o número vai mudar.

Não entrei em muitos detalhes, mas a coisa é bem simples.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Jairo Maia »

Olá Eolo,

Deu certo, estabelecendo alguns critérios:

1 - Neutralizar a tecla INSERT, ficando permanente no modo de INSERÇÃO;
2 - Neutrlaizando a tecla DELETE, ficando a deleção exclusivamente pela BACKSPACE. Isso porque se não neutralizá-la, o usuario pode posicionar-se no final do texto, pressionar DELETE e depois inserir caracteres tantas quantas vezes pressionou DELETE, ficando o texto maior que o desejado.

Abaixo a adaptação do exemplo do manual e funcionando:

Código: Selecionar todos

#include "Inkey.ch"
#include "Memoedit.ch"

STATIC slChanged := .F.

PROCEDURE Main( cFileName )
      Local cText, lInsert, nk_Ins, nk_del
      Private nLenText, nMaxLen := 45  // limitando a 45 caracteres...
      
      nk_Ins := SetKey( K_INS, { || Nil } )  // neutraliza INSERT
      nk_del := SetKey( K_DEL, { || Nil } )  // neutraliza DELETE
      
      lInsert := Set( _SET_INSERT, .T. )  // tem que ser permanente, nao pode permitir sobreposicao...

      Clear Screen
      
      cText := "Teste de limitacao de texto no MemoEdit."
      nLenText := Len( cText )

      @ 0, 0 TO MaxRow(), MaxCol() DOUBLE

      cText := MemoEdit( cText, 1, 1 , MaxRow()-1, MaxCol()-1, .T., "USERFUNC" )

      Hb_Alert( cText )
      //Replace cCampoMemo With cText

      Set( _SET_INSERT, lInsert )  // retorna estado de INSERT
      SetKey( K_INS, nk_Ins )      // restaura tecla INSERT
      SetKey( K_DEL, nk_del )      // restaura tecla DELETE

      Clear Screen

   RETURN


   FUNCTION UserFunc( nMode, nRow, nCol )
      LOCAL nKey  := LastKey()
      LOCAL nRet  := ME_DEFAULT
      LOCAL cInfo := ""

      DO CASE
      //CASE nMode == ME_INIT
         //Set( _SET_INSERT, .F. )  // start in overstrike mode

      CASE nMode == ME_IDLE

         If nKey = K_BS           // se pressionou BACKSPACE,
           nLenText--             // decrementa nLenText...
         ElseIf nKey > 31 .AND. nKey < 256
           nLenText++
           If nLenText > nMaxLen  // seatingiu limite, bloqueia...
             Hb_Alert( "Limite excedido. Maximo permitido: " + Hb_NToS( nMaxLen ) )
             Clear Typeahead      //limpa teclado
             Hb_KeyPut( K_BS )    // remove ultimo caractere digitado
             Return 0             // volta ao texto 
           EndIf
         EndIf

          slChanged := .T.

         cInfo := "[row: " + LTrim(Str(nRow))
         cInfo += " col: " + LTrim(Str(nCol))+"]"
         cInfo += Chr(205)+Chr(205)

         cInfo += "[Ins]"

         IF slChanged
            cInfo += Chr(205)+Chr(205)+"[Chg]"
         ENDIF

         @ MaxRow(), 2 SAY cInfo + Replicate(Chr(205),6)

      CASE nMode == ME_UNKEY .OR. nMode == ME_UNKEYX
         // buffer is changed
         slChanged := ( nMode == ME_UNKEYX )

         DO CASE
         //CASE nKey IN { K_ALT_W, K_CTRL_W, K_ESC }
         CASE AScan( nKey, { K_ALT_W, K_CTRL_W, K_ESC } ) > 0
            nRet := ME_IGNORE     // ignore default termination keys

         CASE nKey == K_ALT_S
            nRet := K_ALT_W       // Save with Alt+S

         CASE nKey == K_ALT_C
            nRet      := K_ESC    // Cancel with Alt+C
            slChanged := .F.
         ENDCASE

      ENDCASE

   RETURN nRet
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por asimoes »

Se o que for digitado aceitar somentes letras e números:

IsAscii( "ABC123" )

ElseIf nKey > 31 .AND. nKey < 256

Por

ElseIf IsAscii(Chr(nKey))
►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)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por alxsts »

Olá!

Questão interessante a apresentada neste tópico, que mostra como é difícil trabalhar com uma "caixa preta", sem ter acesso ao buffer de edição da função.

Outra opção, alem da apresentada pelo Jairo, seria criar uma MemoEdit() customizada, utilizando o fonte disponível no Github (Copyright 2000 Maurilio Longo <maurilio.longo@libero.it>).
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por asimoes »

O autor do tópico ainda não se manifestou em relação as soluções apresentadas, inclusive será que ele quer a solução para o xharbour 1.2.1?
►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)
Ceb
Usuário Nível 1
Usuário Nível 1
Mensagens: 14
Registrado em: 16 Set 2015 09:55
Localização: Alegre/ES

Contar caracteres no Memoedit() do Xharbour 1.2.1

Mensagem por Ceb »

Boa noite!

Primeiramente quero deixar aqui o meu muito obrigado ao Vander, Asimoes, Jairo, Eolo e Alxsts. Quero que saibam também, que apreciei cada palavra que vocês postaram aqui e que todas, sem exceção foram de grande valia para que eu chegasse a uma decisão.

Das sugestões apresentadas, a do Eolo era a mais provável, mas, conforme o Jairo relatou, haveria necessidade de estabelecer alguns critérios para que o controle funcionasse corretamente. Porém, a edição sem usar DELETE e BACKSPACE iria obrigar o(s) usuário(s) a se adaptar(em) e surgiriam vários pedidos para habilitar tais teclas.

Então, considerando o tempo que tenho para disponibilizar tal recurso, segui o que me parecia se encaixar mais dentro de minhas limitações, ou seja: conforme o Jairo sugeriu acima, eu coloquei o memoedit() dentro de um loop e aviso que XX caracteres ultrapassaram o limite de XX caracteres e volta a edição até que o usuário ajuste o texto.

Obs: antes de contar/avisar que o texto excedeu o limite de caracteres, eu substituo alguns do texto ex: chr(13)+chr(10) por " ", chr(32)+chr(32) por " " e chr(141)+chr(10) por "", fazendo uso do StrTran.

Antes que eu esqueça, a finalidade do uso do Memoedit() é para editar/criar uma mensagem curta para envio de SMS por Http.

Att,

Ceb
Responder