StartThread()

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

Moderador: Moderadores

Avatar do usuário
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

StartThread()

Mensagem por juniorcamilo »

Amigos
li vários post no fórum e não estou conseguindo sucesso!
utilizo xHarbour 123 em console
exemplo

Código: Selecionar todos

#include 'JR.CH'
#include "INKEY.CH"
#include "FILEIO.CH"
#include "GTINFO.CH"
#include "wvtwin.ch"
#include "hbgtinfo.ch"
#include "directry.ch"
#include "hbcompat.ch"
REQUEST DBFCDX,DBFNTX
Function Main()
SetMode(25,80)  //tamanho da tela
SET( _SET_EVENTMASK, INKEY_ALL - INKEY_MOVE ) // + HB_INKEY_GTEVENT )
SETCANCEL(.f.)
SET EXCL OFF
SET TALK OFF
SET BELL OFF
SET SOFTSEEK OFF
SET EXACT ON
SET ECHO OFF
SET CONSOLE OFF
SET STATUS OFF
SET SAFETY OFF
SET SCOREBOARD OFF
SET CONFIRM ON
SET DELETE ON
SET UNIQUE OFF
SET DATE FRENCH
SET WRAP ON
SET EPOCH TO (YEAR(DATE())-89)
SET FIXED ON
SET DECIMALS TO 09
//1970
SET MESSAGE TO 22 CENTER

*------------------------------------------
teste:= StartThread('teste')
StopThread( teste )
*------------------------------------------

return 
*----------------------------------------------------------------------------
Static Function teste()

return "123" 
só esta retornando nil!
oq estou errando?
Avatar do usuário
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

StartThread()

Mensagem por juniorcamilo »

alguem usa esse comando?
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

StartThread()

Mensagem por Itamar M. Lins Jr. »

Ola!
Vc fez um exemplo com apenas 2 linhas necessárias. Todo o resto não serve para demonstrar nada do que está perguntando.
Já procurou na pasta samples ou test do xHarbour ? Já procurou exemplos na internet ?

Código: Selecionar todos

xProcesso := startthread( @TarefaParalela() ) // tá assim seu código ?

Código: Selecionar todos

 // Exemplo1 do xHarbour 

#include "hbclass.ch"

PROCEDURE Main()

  LOCAL nStart := Seconds()
  LOCAL oMyObject := MyClass()
  LOCAL MethodPtr := HB_ObjMsgPtr( oMyObject, "Count" )
  LOCAL xThread

  CLEAR SCREEN

  nStart := Seconds()

  // 1st param is the Startup Function, 2nd. is Self if 1st param is a Method or NIL otherwise,
  // rest are paramaters to be passed to the Function/Method.
  StartThread ( @MyThreadFunc(), 2, "1st Thread:",     0,  5000 )
  StartThread ( @MyThreadFunc(), 4, "2nd Thread:",  5000, 10000 )
  StartThread ( @MyThreadFunc(), 6, "3rd Thread:", 10000, 15000 )

  WaitForThreads()
  @ 8, 0 SAY "Threads Time:" + Str( Seconds() - nStart )

  nStart := Seconds()

  // StartThread() for methods can be called using an already available
  // Method Pointer or using a method name
  StartThread ( oMyObject, "Count", 10, "1st Thread:",     0,  5000 )
  StartThread ( oMyObject, "Count", 12, "2nd Thread:",  5000, 10000 )
  StartThread ( oMyObject, MethodPtr, 14, "3rd Thread:", 10000, 15000 )

  WaitForThreads()
  @ 16, 0 SAY "[METHODS] Threads Time:" + Str( Seconds() - nStart )

  nStart := Seconds()

  MyThreadFunc( 18, "1st Run:",     0,  5000 )
  MyThreadFunc( 20, "2nd Run:",  5000, 10000 )
  MyThreadFunc( 22, "3rd Run:", 10000, 15000 )

  @ 24, 0 SAY  "Sequential Time:" + Str( Seconds() - nStart )

  Inkey(0)
RETURN

PROCEDURE MyThreadFunc( nRow, cName, nStart, nMax )

  LOCAL i

  FOR i := nStart TO nMax
     //@ nRow, 10 SAY cName + Str( i )
     // Atomic operation
     DispOutAt(nRow, 10, cName + Str( i ))
  NEXT

RETURN

CLASS MyClass
    METHOD Count( nRow, cName, nStart, nMax )
ENDCLASS

METHOD Count( nRow, cName, nStart, nMax ) CLASS MyClass
  LOCAL i

  FOR i := nStart TO nMax
     //@ nRow, 10 SAY cName + Str( i )
     // Atomic operation
     DispOutAt(nRow, 10, cName + Str( i ))
  NEXT

RETURN NIL 
http://fivewin.com.br/index.php?/topic/ ... r-windows/

Procure colocar seu código enxuto, só o basicão mesmo.

Se puder use o Harbour.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

StartThread()

Mensagem por juniorcamilo »

Itamar M. Lins Jr. escreveu: Itamar M. Lins Jr.
sim fiz como disse e sim havia visto os exemplos, mas mesmo assim continua retornando nil!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

StartThread()

Mensagem por JoséQuintas »

Convém destacar que nem toda LIB gráfica é preparada pra multithread, e no XHarbour isso de multithread não é isolado igual no Harbour.
No seu fonte tem #include "wvtwin.ch", isso é gtwvg? no XHarbour ela deixou de ser atualizada há décadas.
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
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

StartThread()

Mensagem por juniorcamilo »

JoséQuintas escreveu:Convém destacar que nem toda LIB gráfica é preparada pra multithread, e no XHarbour isso de multithread não é isolado igual no Harbour.
No seu fonte tem #include "wvtwin.ch", isso é gtwvg? no XHarbour ela deixou de ser atualizada há décadas.
uso a gtwvt!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

StartThread()

Mensagem por JoséQuintas »

Só um exemplo em Harbour, usando GTWVG e multithread: compilar usando GTWVG.HBC -mt

Código: Selecionar todos

PROCEDURE Main

   LOCAL nCont

   FOR nCont = 1 TO 5
      AbreJanela( nCont )
      Inkey(1)
   NEXT
   hb_ThreadWaitForAll()

   RETURN

FUNCTION AbreJanela( nNumero )

   hb_ThreadStart( { || Rotina( nNumero ) } )
   RETURN NIL

FUNCTION Rotina( nNumero )

   LOCAL GetList := {}

   hb_gtReload( "WVG" )
   SetMode( 20, 40 )
   CLS
   @ 2, 2 SAY "Numero:" GET nNumero PICTURE "9999"
   READ

   RETURN NIL
Importante: As janelas abrem uma encima da outra, manualmente movi pra ficar assim
gtwvg.png
Anexos
test.zip
(465.29 KiB) Baixado 306 vezes
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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

StartThread()

Mensagem por JoséQuintas »

E sem LIB nenhuma, precisei acrescentar isto:

Código: Selecionar todos

PROCEDURE HB_GTSYS
   REQUEST HB_GT_WVT_DEFAULT
hbmk2 test -gui -mt

O resultado é o mesmo, mas só usa o CORE, SEM lib adicional.
Aliás... multithread só entra no EXE se compilar com -mt, veja no Xharbour se não está faltando isso.
E se está compilando em GUI (-gui), porque em console não dá pra ter várias janelas.
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
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

StartThread()

Mensagem por juniorcamilo »

habilitei mt mas sem sucesso! uso o xdev!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

StartThread()

Mensagem por JoséQuintas »

Pera aí...
Porque aquele #include "hbcompat.ch" ???
Tô achando que tem #include demais.

E aquele hb_objMsgPtr() que está sendo usado?
Realmente pode ser usado?
Essa forma é válida pra usar em multithread?

No Harbour obrigatoriamente é um codeblock, e isso não me parece codeblock.

Na prática aí estão sendo usados vários recursos ao mesmo tempo, e se um deles falhar, tudo falha.

Deveria testar uma coisa de cada vez, e só quando funcionar uma coisa testar a outra.
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
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

StartThread()

Mensagem por Itamar M. Lins Jr. »

Ola!
Tô achando que tem #include demais.
Vc viu o código dele ?

*------------------------------------------
36 teste:= StartThread('teste')
37 StopThread( teste )
38 *------------------------------------------
39
40 return
41 *----------------------------------------------------------------------------
42 Static Function teste()
43
44 return "123"

Ele usou esse exemplo ai, ele pegou isso de onde ?
Todo o resto da postagem dele é desnecessário.
Tá vendo o código ?
Veja ai: teste:= StartThread('teste'), pegou isso onde ? esse exemplo ai está em que local da internet ?
Esta chamando uma função ou enviando a palavra "teste" para dentro da própria função StartThread ?

Código: Selecionar todos

 Multi Threading (MT) Support:

xHarbour supports MT applications. There is still some more work to be done, but you can already take advantage of this very powerful feature.
Basic sample can be found at tests/mttest.prg

Syntax:
StartThread( @MyThreadFunc() [, xParam1 [,xParamN ] ] )

NOTE: MT Application must link against the MT versions of the Libraries, i.e. vmmt.lib, rtlmt.lib, ppmt.lib, rddmt.lib, dbfntxmt.lib and dbfcdxmt.lib. The full description of MT is beyond the scope of this document.
Depois eu fui procurar e até achei o post de 2016.

Código: Selecionar todos

PROCEDURE Main
LOCAL pThread

CLS
USE Customer
pThread := StartThread( "ShowTime", 0, MaxCol()-7 )

Browse()

StopThread( pThread )

WaitForThreads()
RETURN

PROCEDURE ShowTime( nRow, nCol )
DO WHILE .T.
DispOutAt( nRow, nCol, Time() )
ThreadSleep( 1000 )
ENDDO
RETURN
Porém nestes casos, é bom achar a sintaxe correta da função, como são passado os parâmetros. E não é mais assim.
Lembrando que o xHarbour tem que ser recompilado! ou seja os fontes do xharbour devem ser recompilados para criar as libs com o sufixo "mt". no final!

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

StartThread()

Mensagem por Itamar M. Lins Jr. »

Ola!
No Harbour 3.4 na pasta \contrib\xhb\hbcompat.ch

Código: Selecionar todos

/* MT functions */
   #xtranslate hb_mtvm()                       => hb_MultiThread()
   #xtranslate hb_threadSelf()                 => GetCurrentThread()
   #xtranslate hb_threadID( [<x,...>] )        => GetThreadId( <x> )
   #xtranslate hb_threadStart( <x,...> )       => StartThread( [<x>] )
   #xtranslate hb_threadJoin( <x> )            => JoinThread( <x> )
   #xtranslate hb_threadQuitRequest( <x> )     => KillThread( <x> )
   #xtranslate hb_threadWaitForAll()           => WaitForThreads()
   #xtranslate hb_threadTerminateAll()         => KillAllThreads()

   #xtranslate hb_mutexNotify( <x,...> )       => Notify( <x> )
   #xtranslate hb_mutexNotifyAll( <x,...> )    => NotifyAll( <x> )

   #xtranslate hb_mutexSubscribe( <x,...> )    => {| mtx, nTimeOut, xSubscribed | ;;
                                                  LOCAL lSubscribed ;;
                                                  xSubscribed := Subscribe( mtx, ;
                                                                            iif( HB_ISNUMERIC( nTimeOut ), nTimeOut * 1000, ), ;
                                                                            @lSubscribed ) ;
                                                  RETURN lSubscribed ; }:eval( <x> )
   #xtranslate hb_mutexSubscribeNow( <x,...> ) => {| mtx, nTimeOut, xSubscribed | ;;
                                                  LOCAL lSubscribed ;;
                                                  xSubscribed := SubscribeNow( mtx, ;
                                                                               iif( HB_ISNUMERIC( nTimeOut ), nTimeOut * 1000, ), ;
                                                                               @lSubscribed ) ;
                                                  RETURN lSubscribed ; }:eval( <x> )

   #xtranslate hb_mutexLock( <x>, <n> )        => iif( ! HB_ISNUMERIC( <n> ), hb_mutexLock( <x> ) ;
                                                     iif( <n> <= 0, hb_MutexTryLock( <x> ), ;
                                                        hb_MutexTimeOutLock( <x>, <n> ) ) )
Sintaxe da função no Harbour.

Código: Selecionar todos

hb_threadStart( [<nThreadAttrs> ,] <@sStart()> | <bStart> | <cStart> [, <params,...> ] ) -> <pThID>
O que está entre colchetes é opcional.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

StartThread()

Mensagem por JoséQuintas »

Lembrei que tenho xharbour aqui, só pra brincar com hbmk2 nele.

\xharbour\tests\mttest.prg

Código: Selecionar todos

#include "hbclass.ch"

PROCEDURE Main()

  LOCAL nStart := Seconds()
  LOCAL oMyObject := MyClass()
  LOCAL MethodPtr := HB_ObjMsgPtr( oMyObject, "Count" )
  LOCAL xThread

  CLEAR SCREEN

  nStart := Seconds()

  // 1st param is the Startup Function, 2nd. is Self if 1st param is a Method or NIL otherwise,
  // rest are paramaters to be passed to the Function/Method.
  StartThread ( @MyThreadFunc(), 2, "1st Thread:",     0,  5000 )
  StartThread ( @MyThreadFunc(), 4, "2nd Thread:",  5000, 10000 )
  StartThread ( @MyThreadFunc(), 6, "3rd Thread:", 10000, 15000 )

  WaitForThreads()
  @ 8, 0 SAY "Threads Time:" + Str( Seconds() - nStart )

  nStart := Seconds()

  // StartThread() for methods can be called using an already available
  // Method Pointer or using a method name
  StartThread ( oMyObject, "Count", 10, "1st Thread:",     0,  5000 )
  StartThread ( oMyObject, "Count", 12, "2nd Thread:",  5000, 10000 )
  StartThread ( oMyObject, MethodPtr, 14, "3rd Thread:", 10000, 15000 )

  WaitForThreads()
  @ 16, 0 SAY "[METHODS] Threads Time:" + Str( Seconds() - nStart )

  nStart := Seconds()

  MyThreadFunc( 18, "1st Run:",     0,  5000 )
  MyThreadFunc( 20, "2nd Run:",  5000, 10000 )
  MyThreadFunc( 22, "3rd Run:", 10000, 15000 )

  @ 24, 0 SAY  "Sequential Time:" + Str( Seconds() - nStart )

  Inkey(0)
RETURN

PROCEDURE MyThreadFunc( nRow, cName, nStart, nMax )

  LOCAL i

  FOR i := nStart TO nMax
     //@ nRow, 10 SAY cName + Str( i )
     // Atomic operation
     DispOutAt(nRow, 10, cName + Str( i ))
  NEXT

RETURN

CLASS MyClass
    METHOD Count( nRow, cName, nStart, nMax )
ENDCLASS

METHOD Count( nRow, cName, nStart, nMax ) CLASS MyClass
  LOCAL i

  FOR i := nStart TO nMax
     //@ nRow, 10 SAY cName + Str( i )
     // Atomic operation
     DispOutAt(nRow, 10, cName + Str( i ))
  NEXT

RETURN NIL
SET PATH=d:\xharbour\bin;d:\xharbour\comp\bcc582\bin
SET HB_COMPILER=bcc
SET HB_INSTALL_PREFIX=d:\xharbour
teste 1:
d:\xharbour\tests>hbmk2 mttest

hbmk2: Processing environment options: -comp=bcc
hbmk2: Processing configuration: d:\xharbour\bin\hbmk.hbc
xHarbour 1.2.3 Intl. (SimpLex) (Build 20190613)
Copyright 1999-2018, http://www.xharbour.org http://www.harbour-project.org/
Compiling 'mttest.prg'...
Generating C source output to 'C:\Users\jmcqu\AppData\Local\Temp\hbmk_rruxo3.dir\mttest.c'...
Done.
Lines 72, Functions/Procedures 4, pCodes 332
C:\Users\jmcqu\AppData\Local\Temp\hbmk_rruxo3.dir\mttest.c:
Turbo Incremental Link 5.69 Copyright (c) 1997-2005 Borland
Error: Unresolved external '_HB_FUN_WAITFORTHREADS' referenced from C:\USERS\JMCQU\APPDATA\LOCAL\TEMP\HBMK_RRUXO3.DIR\MTTEST.OBJ
hbmk2: Error: Running linker. 2
ilink32.exe @C:\Users\jmcqu\AppData\Local\Temp\nicvg8.lnk

hbmk2: Error: Referenced, missing, but unrecognized Harbour function(s):
WAITFORTHREADS()
d:\xharbour\tests>
teste 2:
d:\xharbour\tests>hbmk2 mttest -mt

hbmk2: Processing environment options: -comp=bcc
hbmk2: Processing configuration: d:\xharbour\bin\hbmk.hbc
xHarbour 1.2.3 Intl. (SimpLex) (Build 20190613)
Copyright 1999-2018, http://www.xharbour.org http://www.harbour-project.org/
Compiling 'mttest.prg'...
Generating C source output to 'C:\Users\jmcqu\AppData\Local\Temp\hbmk_30fsxw.dir\mttest.c'...
Done.
Lines 72, Functions/Procedures 4, pCodes 332
C:\Users\jmcqu\AppData\Local\Temp\hbmk_30fsxw.dir\mttest.c:
Turbo Incremental Link 5.69 Copyright (c) 1997-2005 Borland
Fatal: Unable to open file 'RTLMT.LIB'
hbmk2: Error: Running linker. 2
ilink32.exe @C:\Users\jmcqu\AppData\Local\Temp\op40j2.lnk
d:\xharbour\tests>
Não sei qual/quais LIBs adicionar.
NÃO uso xharbour.
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
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

StartThread()

Mensagem por Itamar M. Lins Jr. »

Ola!
Não sei qual/quais LIBs adicionar.
NÃO uso xharbour.
MT de verdade no xHb, é sonho.
Eles usam hb_idle()

Código: Selecionar todos

 Now we can have multitasking on ST !
    This is done as an extension of idle state.
    Background functions works on every vmExecute() call,
    so PAY ATTENTION in use of them! A wrong use will make your prg very SLOW.
    Background functions are operative throught a SET BACKGROUND TASKS ON|OFF
    or Set( _SET_BACKGROUNDTASKS, .T.|.F. )
    Default is set to FALSE.
    Even it is set to FALSE, you can call it explicitly using HB_BackgroundRun()
    i.e. inside HB_Idle*() functions.
Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

StartThread()

Mensagem por JoséQuintas »

Fiz umas tentativas:

troquei WaitForThreads() por Inkey(10)

Mudei esta parte

CLEAR SCREEN
? "Tecle ENTER"
Inkey(0)

E compilei hbmk2 mttest -gtwin

Pelo menos o EXE rodou.
Se o resultado é o que esperado... aí já não sei dizer.

Código: Selecionar todos

Tecle ENTER                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             Threads Time:        10.01                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [METHODS] Threads Time:         7.59                                                                                                                                                                                                                      1st Run:      5000                                                                                                                                                                                                                              2nd Run:     10000                                                                                                                                                                                                                              3rd Run:     15000                                                                                                                                                                                                                    Sequential Time:         0.63
d:\xharbour\tests>
Lógico... o Inkey(10) acaba fazendo demorar mais, porque fica esperando 10 segundos.

E aproveitando:
NÃO uso XHarbour
Mas com HBMK2... fica simples como o Harbour
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