Jump to content
Fivewin Brasil

Search the Community

Showing results for tags 'xbase'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Categories

There are no results to display.

Forums

  • FiveWin
    • WorkShop
    • Advantage Server
    • FiveScript
    • FiveWin Avaliação
    • TopConnect
    • Classes
    • Programação
    • FiveWin - Conversão de 16 bits para 32 bits
    • Seminário
    • Artigos / Tutoriais
    • Off - Topic
  • Suporte Estendido
    • Duvidas Gerais

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

Found 2 results

  1. Amiguinhos, Visitem e vejam [url=http://www.xbasewebsite.com/]http://www.xbasewebsite.com/[/url]
  2. Amiguinhos, Aquele velho sonho de conseguir executar código xBase contido em uma .DLL compilada com Harbour se concretizou para mim. Noites sem dormir e muita pesquisa, testes, compilações, chingamentos e sem sapeca-iá-iá, mas consegui. Meus primeiros testes foram com exemplos existentes em todo lugar, Harbour, xHarbour, Fivewin, etc. Busquei informações de como o RunDLL32 do Windows trabalhava e fiz minhas tentativas. Num primeiro momento consegui fazer um EXE executar uma função em uma DLL mas só executava a primeira função que encontrava. Bom já era um começo, mas ao retornar ao EXE paulava. Tentei com RunDLL32 chamado do EXE e não enfrentava mais este problema, mas tinha uma demora de uns segundos e não era o que eu queria. Fiz meu próprio RunDLL32 mas ainda tinha de executá-lo indiretamente. Bom enfim, cheguei onde queria e o primeiro passo para isto foi compilando o código de minha DLL: rochadll.prg /* * Jose Carlos da Rocha * Trabalho com DLL de codigo xBase para uso com Harbour * Sao Paulo - 09/09/2014 * Baseados nos exemplos BabuDLL e outros */ #include "fivewin.ch" #pragma BEGINDUMP #include <windows.h> #include <hbvm.h> #include <hbapiitm.h> BOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { HB_SYMBOL_UNUSED( hinstDLL ); HB_SYMBOL_UNUSED( fdwReason ); HB_SYMBOL_UNUSED( lpvReserved ); switch( fdwReason ) { case DLL_PROCESS_ATTACH: hb_vmInit( FALSE ); break; case DLL_PROCESS_DETACH: hb_vmQuit(); break; } return TRUE; } void pascal __export HBDLLENTRY( char * cProcName ) { hb_itemDoC( cProcName, 0, 0 ); return 0; } void pascal __export CusTstBrw() { hb_itemDoC( "CusTstBrw", 0 ); } void pascal __export HBDLLENTRY2( char * cProcName, PHB_ITEM pParam1, PHB_ITEM pParam2 ) { hb_itemDoC( cProcName, 2, pParam1, pParam2 ); } #pragma ENDDUMP /* * MENUITEM "&Clientes..." ACTION HbDllEntry( "Customer" ) MESSAGE "Manutencao de Clientes" * Esta funcao foi chamada atraves de parametro da funcao exportavel hbDLLEntry() * Chamada indireta, pois a funcao abaixo passa por outra funcao para agir * Aqui o exemplo CUSTOMER foi imputado na DLL para demonstrar que trechos grandes de codigo * podem residir dentro de uma DLL e serem chamados a partir de um EXE externo. */ #include "Customer.ch" function Customer() local oWnd, oBar local oClients, oClient //local oName, cName SET _3DLOOK ON USE Customer SHARED NEW ALIAS Clients USE Sales SHARED NEW SELECT Clients DEFINE WINDOW oWnd TITLE "Reporting tools" MDI ; MENU BuildMenu(oClients) COLOR "N/W" DEFINE BUTTONBAR oBar OF oWnd SIZE 60, 60 2007 DEFINE BUTTON OF oBar ACTION MsgInfo( "Click" ) ; FILENAME "..\bitmaps\attach.bmp" PROMPT "Attach" DEFINE BUTTON OF oBar ACTION MsgInfo( "Click" ) ; FILENAME "..\bitmaps\calendar.bmp" PROMPT "Calendar" DEFINE BUTTON OF oBar ACTION MsgInfo( "Click" ) ; FILENAME "..\bitmaps\people2.bmp" PROMPT "Clients" DEFINE BUTTON OF oBar ACTION MsgInfo( "Click" ) SET MESSAGE OF oWnd TO "Testing the FiveWin Report Class" CENTERED ACTIVATE WINDOW oWnd CLOSE DATABASES return nil function BuildMenu(oClients) local oMenu MENU oMenu MENUITEM "&DataBases" MENU MENUITEM "&Clients..." ACTION BrwClients(oClients) ; MESSAGE "Clients management" MENUITEM "&Report..." ACTION GenReport() SEPARATOR MENUITEM "&End" ACTION oWnd:End() ; MESSAGE "End this test" ENDMENU oMenu:AddMdi() // Add standard MDI menu options ENDMENU return oMenu function BrwClients(oClients) local oBrw, oIco, oBarBrw if oClients != nil return nil endif DEFINE ICON oIco FILENAME "..\icons\customer.ico" DEFINE WINDOW oClients TITLE "Clients management" ; MDICHILD ICON oIco DEFINE BUTTONBAR oBarBrw OF oClients DEFINE BUTTON OF oBarBrw ACTION ShowClient(oClients) @ 2, 0 LISTBOX oBrw FIELDS OF oClients ; SIZE 500, 500 // ON CHANGE ChangeClient(oClients) oClients:SetControl( oBrw ) ACTIVATE WINDOW oClients ; VALID( oClients := nil, .t. ) // We destroy the object return nil function GenReport() local oWnd, oIco DEFINE ICON oIco FILENAME "..\icons\print.ico" DEFINE WINDOW oWnd MDICHILD TITLE "Clients report" ; VSCROLL HSCROLL ICON oIco ACTIVATE WINDOW oWnd return nil function ShowClient(oClients) local oIco, oClient local oName, cName if oClient != nil return nil endif DEFINE ICON oIco FILENAME "..\icons\Person.ico" DEFINE DIALOG oClient RESOURCE "Client" ; ICON oIco TITLE "Detalhes" REDEFINE SAY ID 3 OF oClient // To get the proper color REDEFINE SAY ID 4 OF oClient REDEFINE SAY ID 5 OF oClient REDEFINE GET oName VAR cName ID ID_NAME OF oClient REDEFINE BUTTON ID ID_NEXT OF oClient ACTION GoNext(oClients,oName) SELECT Sales // We select Sales to properly initialize the Browse REDEFINE LISTBOX FIELDS ID ID_SALES OF oClient ACTIVATE DIALOG oClient CENTERED NOWAIT ; VALID ( oClient := nil, .t. ) // Destroy the object SELECT Clients return nil function ChangeClient(oClients,oName) if oClients != nil cName = AllTrim( Clients->Last ) + ", " + Clients->First oName:Refresh() endif return nil function GoNext(oClients,oName) if oClients != nil oClients:oControl:GoDown() else SKIP if EoF() GO BOTTOM endif endif ChangeClient(oClients,oName) return nil /* * MENUITEM "&Browse..." ACTION HbDllEntry( "CusTeste" ) MESSAGE "Browse de Clientes" * Esta funcao foi chamada atraves de parametro da funcao exportavel hbDLLEntry() * Chamada indireta, pois a funcao abaixo passa por outra funcao para agir */ function CusTeste() USE Customer SHARED NEW ALIAS Clients Browse() CLOSE DATABASES return .t. /* * MENUITEM "&Customer..." ACTION CusTstBrw() MESSAGE "Browse de Clientes" * Esta funcao foi chamada dentro da DLL usando o proprio nome ao inves de * usar hbDLLEntry(), desta forma ficou mais legal */ function CusTstBrw() USE Sales SHARED NEW Browse() CLOSE DATABASES return .t. Dentro do código da DLL existem aplicativos que serão chamados pela aplicação principal, Customer(), CusTeste() e CusTstBrw(). Atentem para o seguinte trecho: #pragma BEGINDUMP ... void pascal __export HBDLLENTRY( char * cProcName ) ... void pascal __export CusTstBrw() ... #pragma ENDDUMP Vejam que HBDLLENTRY e CusTstBrw são exportadas, ou seja, são visíveis as chamadas à DLL. Então como compilar este .PRG e transformá-lo em uma .DLL? Eu usei o bom-e-velho BUILDH.BAT com algumas alterações, vejam os trechos que foram modificados: %hdir%\bin\harbour %1 /n /i%fwh%\include;%hdir%\include /w0 /p %3 /d__HARBOUR__ > comp.log IF ERRORLEVEL 1 GOTO COMPILEERRORS @type comp.log echo -O2 -e%1.exe -I%hdir%\include;%bcdir%\include %1.c > b32.bc %bcdir%\bin\bcc32 -M -c @b32.bc copy %bcdir%\lib\uuid.lib :ENDCOMPILE IF EXIST %1.rc %bcdir%\bin\brc32 -r -I%bcdir%\include %1 rem IF EXIST %1.rc %vcdir%\bin\rc -r -d__FLAT__ %1 echo %bcdir%\lib\c0d32.obj + > b32.bc Quem usa este .BAT dirá, mas não tem nada de diferente neste trecho, mas tem sim e está na última linha, onde se vê echo %bcdir%\lib\c0d32.obj + > b32.bc Quando compilamos nossos programas para gerar executáveis o arquivo c0w32.obj é o usado, mas neste caso usaremos o c0d32.obj. Outra linha alterada no nosso BUILDH.BAT é a linha de chamada do iLink32.exe if %GT% == gtgui %bcdir%\bin\ilink32 -Gn -aa -s -Tpd @b32.bc No lugar de -Gn -aa -s -Tpe eu alterei para -Gn -aa -s -Tpd, onde e é para EXE e d é para DLL. Bom, depois de gerada a DLL é possivel testá-la sem precisar do uso do aplicativo principal, bastando usar para isto o RunDLL32.exe do Windows, executando um comando simples: %windir%\System32\RunDLL32 rochadll.dll,CusTstBrw Leve em consideração que os testes foram feitos dentro da pasta SAMPLES do Fivewin, portanto as tabelas CUSTOMER.DBF e SALES.DBF serao usadas. Se a DLL foi bem gerada um browse aparecerá mostrando os registros da tabela. Agora vamos a parte do aplicativo principal. Este poderá ser compilado normalmente usando o BUILDH.BAT: rocha.prg /* * Jose Carlos da Rocha * Trabalho com DLL de codigo xBase para uso com Harbour * Sao Paulo - 09/09/2014 * Baseados nos exemplos BabuDLL e outros */ #include "FiveWin.ch" FUNCTION Main() local oWndMain, oBarMain DEFINE WINDOW oWndMain TITLE "Janela dentro do EXE" MDI MENU BuildMenuMain() COLOR "N/W" DEFINE BUTTONBAR oBarMain OF oWndMain SIZE 60, 60 2007 DEFINE BUTTON OF oBarMain ACTION WinExec( "RunDLL32.exe rochadll.dll,CusTstBrw" ) DEFINE BUTTON OF oBarMain ACTION UseDLL( "CusTstBrw", "rochadll.dll" ) SET MESSAGE OF oWndMain TO "Testing the FiveWin DLLs" CENTERED ACTIVATE WINDOW oWndMain MAXIMIZED VALID MsgYesNo( "Quer sair?" ) RETURN nil FUNCTION BuildMenuMain() local oMenu MENU oMenu MENUITEM "Administracao" MENU MENUITEM "&Clientes..." ACTION HbDllEntry( "Customer" ) MESSAGE "Manutencao de Clientes" MENUITEM "&Browse..." ACTION HbDllEntry( "CusTeste" ) MESSAGE "Browse de Clientes" MENUITEM "&Customer..." ACTION CusTstBrw() MESSAGE "Browse de Clientes" SEPARATOR MENUITEM "&Sair" ACTION oWnd:End() ; MESSAGE "Sair do sistema" ENDMENU oMenu:AddMdi() // Add standard MDI menu options ENDMENU return oMenu FUNCTION UseDLL( cFuncName, cDllName ) local hDLL, cFarProc hDLL = LoadLibrary( cDllName ) if hDll > 32 cFarProc := GetProcAddress( hDLL, "DLLSYMINIT", .T., _INT ) CallDLL( cFarProc ) Eval( &( "{||" + cFuncName + "() }" ) ) endif return nil //-------------------------------------------------------------------------// #include "dll.ch" DLL32 FUNCTION CusTstBrw() AS LONG PASCAL LIB "rochadll.dll" DLL32 FUNCTION HBDLLENTRY( cProc AS LPSTR ) AS LONG PASCAL LIB "rochadll.dll" DLL32 FUNCTION HBDLLENTRY2( cProc AS LPSTR, pItem1 AS LONG, pItem2 AS LONG ) AS LONG PASCAL LIB "rochadll.dll" DLL32 FUNCTION HBDLLENTRY3( cProc AS LPSTR, pItem1 AS _INT, pItem2 AS _INT ) AS _INT PASCAL LIB "rochadll.dll" Vejamos agora algumas caracteristicas: ... DEFINE BUTTON OF oBarMain ACTION WinExec( "RunDLL32.exe rochadll.dll,CusTstBrw" ) ... No trecho acima faço execução de uma função dentro da .DLL usando execução de aplicativo externo. ... DEFINE BUTTON OF oBarMain ACTION UseDLL( "CusTstBrw", "rochadll.dll" ) ... Neste trecho, usando funções do Harbour exemplifico como chamar uma função existente na .DLL. Esta função deve ser EXPORTável e para tal foi necessária a definição de chamada desta função: ... DLL32 FUNCTION CusTstBrw() AS LONG PASCAL LIB "rochadll.dll" ... Abaixo vemos as formas de chamar nossas funções usando HbDllEntry, mas particularmente acho feio assim: ... MENUITEM "&Clientes..." ACTION HbDllEntry( "Customer" ) MESSAGE "Manutencao de Clientes" MENUITEM "&Browse..." ACTION HbDllEntry( "CusTeste" ) MESSAGE "Browse de Clientes" ... A função HbDllEntry() enxerga as funções que não são EXPORTáveis. Vale lembrar que as .DLL não ficaram pequenas, mas o fator levado em consideração é que para a manutenção fica mais produtivo ter várias .DLLs no sistema e ao modificar uma ou outra, podemos atualizar somente elas sem prejuízo ao EXE principal. Outra coisa importante: As telas usadas no aplicativo, não importando qual .DLL poderá usá-la, deverão ser compiladas com o .EXE principal. O Harbour usado foi a versão 3.2-17626. O download deste trabalho encontra-se no 4shared.com. Tenho grande certeza, que seria possivel chamar código xBase contido nas .DLLs através de outras linguagens como Delphi ou Visual Basic. Vale a pena testar e retornar.
×
×
  • Create New...