Clipper On Line • Ver Tópico - Práticas que facilitam programar Clipper/Harbour

Práticas que facilitam programar Clipper/Harbour

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 14 Jan 2016 08:14

Quanto ao post anterior, de qualquer jeito, depende do programador incluir o recurso em suas práticas.

Outro exemplo: um array de coordenadas de mouse pra click, geralmente é um array multidimensional:

FOR nCont = 1 TO Len( aAreaMouse )
   IF MRow() >= aAreaMouse[ nCont, 1 ] .AND. MCol() >= aAreaMouse[ nCont, 2 ] .AND. MCol()  <= aAreaMouse[ nCont, 3 ]
      nKey := aAreaMouse[ nCont, 4 ]
     EXIT
   ENDIF
NEXT


FOR EACH oElement IN aAreaMouse
   IF MRow() >= oElement[ 1 ] .AND. MCol() >= oElement[ 2 ] .AND. MCol() <= oElement[ 3 ]
      nKey := oElement[ 4 ]
      EXIT
   ENDIF
NEXT


É até interessante, dá pra ter relação com um post anterior.
O "assunto" do bloco é aAreaMouse, todos os elementos do array.
E o "assunto" da rotina interna é cada um dos elementos desse array.
FOR EACH deixou isso bem claro no fonte.

Parece até que faz parte:
Acostumou a organizar o fonte e simplificar fonte, vai descobrindo técnicas/recursos que ajudam nisso.

A conclusão é que tem tudo a ver, é só começar que aos poucos tudo vém naturalmente.

Quanto a esse, pera aí que estou tentando verificar se nesse caso se aplica.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 14 Jan 2016 08:27

Nem sempre dá pra aplicar o FOR EACH, depende muito do contexto.
E também não existe uma regra fixa de como usar.

FOR nIdx := 1 to 25 STEP 2
  nLinha ++
  RestScreen(nIdx, 0, nIdx+1, 79, cTAbertura[nLinha])
  SysWait(.01)
NEXT


À primeira vista é uma rotina pra retornar textos na tela, onde aí é apenas uma página.
Sendo assim, o assunto principal seria cTAbertura.

nIdx := 1
FOR EACH oElement IN cTAbertura
   RestScreen( nIdx, 0, nIdx + 1, 79, oElement )
   SysWait( .01 )
   nIdx += 2
   IF nIdx > 25
      // mudar página? ou EXIT?
     nIdx := 1
   ENDIF
NEXT


E internamente seria o controle de "quebra de página", ou algo parecido.
No meu ponto de vista, só é interessante alterar se a rotina completa tratar todo conteúdo de cTAbertura.
Vai de cada um.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor asimoes » 14 Jan 2016 10:42

Quintas,

Voltando ao assunto FOR EACH tem esses dois métodos muito úteis:

__enumIndex() equivalente a variável I:

FOR I:=1 TO Len(aVator)
NEXT
__enumIsLast() testa se i = Len(aVetor)

cCampos:=""
FOR EACH aCampos IN aTheDBF
   cCampos+=IF(aCampos:__enumIndex() > 1,Space(1),"")+cNomeCampo + ' ' + cDecode + IF(!aCampos:__enumIsLast(),",",")")+ IF(!aCampos:__enumIndex(),HB_EOL(),"")
NEXT
►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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 14 Jan 2016 11:10

São interessantes.
Mas no caso desse uso, ficou complicado de entender o fonte, eu mesmo não entendi direito.
Me parece inclusive que tem erro.

Se entendi direito, deve ser algo parecido com isto:

cCampos := ""
FOR EACH cNomeCampo IN aTheDBF
    cCampos += Space(1) + cNomeCampo + ' ' + cDecode + ","
NEXT
cCampos := Ltrim( Substr( cCampos, 1, Len( cCampos ) - 1 ) ) + ")" + hb_eol()


Lembre-se o fonte é pra nós, não para o compilador.
Se ficar difícil, pior pra nós.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor asimoes » 14 Jan 2016 11:24

No meu exemplo o destaque é para

oElemento:__enumIndex() e oElemento:__enumIsLast()

 aVetor:={"A", "B", "C"}
cValor:=""
FOR EACH oElemento IN aVetor
    cValor += oElemento + IF(!oElemento:__enumIsLast(), ",", "")
NEXT
cValor:=""
FOR EACH oElemento IN aVetor
    cValor += StrZero(oElemento:__enumIndex,2)+" "+oElemento + IF(!oElemento:__enumIsLast(), ", ", "")
NEXT

1º Resulta: A,B,C
2º Resulta: 01 A, 02 B, 03 C
►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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 14 Jan 2016 11:36

ok, era apenas pra mostrar que existe a opção de obter mais informações da variável do FOR EACH.

Em todo caso, só pra lembrar:

Nosso maior tempo é gasto em alterações, então o fonte tem que ser voltado pra ganhar tempo em alteração.

Olhou, entendeu, alterou, fim.
Olhou, não entendeu, já se começa a perder tempo a partir daí.

Só compensa complicar em casos extremos, aonde milésimos de segundo fizerem diferença.
Ainda não peguei um caso assim.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor asimoes » 14 Jan 2016 11:48

A questão é se vai usar FOR EACH conheça bem os recursos que pode utilizar.
►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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor asimoes » 14 Jan 2016 11:55

Um exemplo que está no changelog.txt
       proc main()
         local v, h:={"a"=>1.000,"b"=>2.000,"c"=>3.000}
         heval( h, { |k,v,i| qout( k, v, i ) } ); ?
         for each v in h
            ? v, "=>", v:__enumKey(), v:__enumValue(), v:__enumIndex(), ;
                       valtype(v:__enumBase())
            v += 0.123
         next
         ? ;heval( h, { |k,v,i| qout( k, v, i ) } )
         return
►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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 14 Jan 2016 12:00

Acho essa invenção péssima, variável hash.
E tem gente que ainda abusa.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor fladimir » 17 Jan 2016 12:48

Quintas,

Dentro das práticas q facilitam programar Clipper/Harbour vc mencionou q acha péssima etc...

Gostaria de saber pq?

Eu uso para tratar arquivos INI

Exemplo:

...
   hINI := HB_ReadIni( cArqZ ) // ATENCAO É CASE SENSITIVE.

   aGet       := Inicia_Var(aGet, "MAPARES")

   aGet[D_DATAMOVZ] := CTOD( hINI["ECF"]["DATAMOVIMENTO"] ) //= 09/12/13
   aGet[D_NUMSERIE]  := hINI["ECF"]["NUMSERIE"]        //= 00000000000000000001

   *-- Verifica se a Chave existe no Hash
   if HHasKey( hINI["TOTALIZADORES"], "GRANDETOTAL" )
      aGet[D_GT_FINAL]   := StrToVal( hINI["TOTALIZADORES"]["GRANDETOTAL"]   )
   endif      

   aGet[D_DESCONTOS]  := StrToVal( hINI["TOTALIZADORES"]["TOTALDESCONTOS"]     )

...
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar de usuário

fladimir
Colaborador

Colaborador
 
Mensagens: 2434
Data de registro: 15 Nov 2006 19:21
Curtiu: 28 vezes
Mens.Curtidas: 157 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 17 Jan 2016 14:54

Desse jeito você não consegue validar o fonte.
Acontece isso com variável PRIVATE, PUBLIC, variável HASH, até mesmo classes e métodos.

No caso de hash, um .CH pode ajudar.
Acho até que foi feito só pra compatibilidade com xHarbour.

Quanto ao INI, não deixa de ser uma opção.
Mas prefiro XML mesmo, mais prático e com mais recursos.

No caso de classes e métodos... vale a pena o risco.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 18 Jan 2016 10:22

Uia, a compilação -w3 -es2 acabou de me salvar.

d:\CDROM\FONTES\HAROLDO>hbmk2 hl.hbp -comp=msvc
hbmk2: Processing environment options: -comp=msvc
hbmk2: Building sub-project (level 2): libjose.hbp
hbmk2: Processing environment options: -comp=msvc
hbmk2: Target up to date: libjose.lib
hbmk2: Compiling Harbour sources...
Harbour 3.4.0dev (0a127e0) (2016-01-15 01:54)
Copyright (c) 1999-2016, https://github.com/vszakats/harbour-core/
Compiling 'VHLAL01.prg'...
VHLAL01.prg(646) Warning W0032 Variable 'CPALAVRA' is assigned but not used in function 'MYSQLENDERECOLIKE(642)'


Apaguei uma linha a mais do fonte sem querer, aonde usava cPalavra, por isso o erro.

Se não fosse a compilação -w3 -es2, ia demorar muuuito pra descobrir isso.
Como ela avisou, o fonte anterior estava na mão.

Na correria do dia a gente não percebe esses detalhes.

A compilação -w3 -es2 não é apenas uma checagemzinha de escrever o fonte direito.
E também não é só na hora de criar um fonte novo.
É uma ajuda SEMPRE, pra qualquer alteração.
Acho que quando mencionei sobre a compilação com -w3 -es2 não chamei a atenção pra isso.

Imagine nesse caso acima, é um módulo com umas 15 opções de pesquisa diferentes, e a linha que apaguei era usada somente em uma determinada condição.
Eu iria demorar meses pra descobrir o que aconteceu.
Na compilação -w3 -es2 foi instantâneo, já mostrou no instante em que apaguei a linha.

É programar sem erros, mesmo errando.... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 18 Jan 2016 10:29

O programa git também ajuda a conferir as alterações.

Acabei de alterar na parte de cima de um jeito, e alterei a parte de baixo de outro.

alteracao.png


No fonte as coisas ficam longe, no git fica pertinho.
Dá pra conferir exatamente o que foi alterado.
Se o erro anterior passasse na compilação, talvez eu pegasse por aqui, porque ia mostrar que apaguei aquela linha.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 09 Jul 2016 11:11

Reavaliando o post do ASimões:

cCampos:=""
FOR EACH aCampos IN aTheDBF
    cCampos+=IF(aCampos:__enumIndex() > 1,Space(1),"")+cNomeCampo + ' ' + cDecode + IF(!aCampos:__enumIsLast(),",",")")+ IF(! aCampos:__enumIndex(),HB_EOL(),"")
NEXT


Sinceramente, não entendi o que ele faz, vamos por bloco.

cCampos := ""
FOR EACH aCampos IN aTheDBF
    cCampos += ;
   IF(aCampos:__enumIndex() > 1, Space(1), "" ) + ;  // ok, só no primeiro não tem espaço, poderia ser AllTrim() fora do loop
   cNomeCampo + ;                                                 // de onde vém isso?
   ' ' + ;
   cDecode + ;                                                        // de onde vém isso?
   IF( ! aCampos:__enumIsLast(), ",", ")" ) + ;           // ok, no último é ")", nos demais ",", poderia trocar no final fora do loop
   IF( ! aCampos:__enumIndex(), HB_EOL(), "" )       // não sei pra que serve isto. Se __enumindex() é número, tá esquisito.
NEXT


Provavelmente era o começo da alteração, e o fonte ficou parcial.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 28 Set 2016 13:43

Uma pequena melhoria que uso nos GETs.
Uso um bloco alterado na GETSYS - a parte com by JPA

   DO WHILE ! nPos == 0
      aVarGet := Array( Len( GetList ) )  // by JPA to otimize screen update
      FOR EACH oElement IN GetList        // by JPA to otimize screen update
         aVarGet[ oElement:__EnumIndex ] := oElement:VarGet()
      NEXT

      // GET NEXT GET from list and post it as the active GET
      PostActiveGet( oGet := GetList[ nPos ] )

      // Read the GET
      IF ( VALTYPE( oGet:reader ) == "B" )
         EVAL( oGet:reader, oGet )    // Use custom reader block
      ELSE
         GetReader( oGet, lIsMouse )            // Use standard reader
      ENDIF

      FOR EACH oElement IN GetList // by JPA to otimize screen update
         IF aVarGet[ oElement:__EnumIndex ] != oElement:VarGet()
            oElement:Display()
         ENDIF
      NEXT
      // Move to NEXT GET based on EXIT condition
      nPos := Settle( GetList, nPos )

   ENDDO


Nada demais, só atualiza a tela caso o conteúdo do GET tenha sido alterado.

Muito útil quando a digitação altera o conteúdo de outros GETs, porque na GETSYS normal isso só acontece se passar pelo GET.

#include "hbclass.ch"
PROCEDURE Main

SetMode( 35, 100 )
SetColor( "W/B,N/W,,,W/B" )
CLS
Nota := NotaClass():New()
@ 1, 0 SAY "Valor da Nota:" GET Nota:Valor VALID Nota:CalculaImpostos()
@ 2, 0 SAY "Base ICMS....:" GET Nota:IcmBase WHEN .F.
@ 3, 0 SAY "Base Reducao.:" GET Nota:IcmReducao VALID Nota:CalculaImpostos()
@ 4, 0 SAY "Alíquota.....:" GET Nota:IcmAliquota VALID Nota:CalculaImpostos()
@ 5, 0 SAY "Valor ICMS...:" GET Nota:IcmValor WHEN .F.
@ 6, 0 SAY "Base ST......:" GET Nota:StBase WHEN .F.
@ 7, 0 SAY "IVA..........:" GET Nota:StIVA VALID Nota:CalculaImpostos()
@ 8, 0 SAY "Aliq.ST......:" GET Nota:StAliquota VALID Nota:CalculaImpostos()
@ 9, 0 SAY "Valor ST.....:" GET Nota:StValor WHEN .F.
READ

CREATE CLASS NotaClass
   VAR Valor       INIT 0
   VAR IcmBase     INIT 0
   VAR IcmReducao  INIT 0
   VAR IcmAliquota INIT 0
   VAR IcmValor    INIT 0
   VAR StBase      INIT 0
   VAR StIVA       INIT 0
   VAR StAliquota  INIT 0
   VAR StValor     INIT 0
   METHOD CalculaImpostos()
   END CLASS

METHOD CalculaImpostos()

   ::IcmBase := ::Valor - ( Int( ::Valor * ::IcmReducao ) / 100 )
   ::IcmValor := Int( ::IcmBase * ::IcmAliquota ) / 100
   ::StBase := ::IcmBase + ( Int( ::IcmBase * ::StIVA / 100 ) )
   ::StValor := Max( 0, Int( ::StBase * ::StAliquota ) / 100 - ::IcmValor )
   SetPos( 11, 0 )
   ? "Icmbase:", ::IcmBase, "STBase", ::StBase
   RETURN .T.


Sem alterar a getsys, valores errados na tela, ou necessidade de fonte adicional:

Valor da Nota:        100
Base ICMS....:        100.00
Base Reducao.:         20
Alφquota.....:         10
Valor ICMS...:          8.00
Base ST......:         80.00
IVA..........:         50
Aliq.ST......:         10
Valor ST.....:          4.00

Icmbase:         80.00 STBase        120.00


Até lembrei das estorinhas de criança, que tinham o "moral da estória".
Acho que isso era algo do tipo: "use a cabeça e pense".

Qual o moral da estória aqui:
Problema resolvido de vez, sem complicar os fontes de trabalho.
Se é pra complicar, que seja pra simplificar.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Anterior Próximo



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 17 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