Estas son notas para los que como yo no tenemos ni idea de 'C' y precisamos llamar a una función 'C' de una .Lib de terceros, desde FiveWin/Harbour.
Gracias a este foro, sobre todo a Antonio Linares lo he conseguido.
La .lib de terceros en mi caso era: ter16bc.lib
--->>> ATENCIÓN: la .lib debe ser compatible con nuestro compilador/lincador.
La función de la .lib a usar era: CreateTerWindow()
Recibía como parámetro un puntero a una estructura: arg_list
y devolvía un handle de una ventana que yo quería obtener/manipular/gestionar desde un array de 2 elementos: aRet
Debía comenzar mi código 'C' con:
#pragma BEGINDUMP
#include <hbapi.h>
y acabarlo con:
#pragma ENDDUMP
Hasta aquí fácil.
Dentro del código 'C' debía declarar la estructura, así:
struct arg_list {
int x;
long LineLimit;
BOOL WordWrap;
BYTE InputType;
BYTE file[131];
HGLOBAL hBuffer;
HINSTANCE hInst;
HWND hParentWnd;
DWORD style;
};
También dentro del código 'C' debia declarar la función 'C' que yo iba a utilizar de la .lib (prototipo?), así:
HWND CreateTerWindow( struct arg_list * );
Hace 20 años me enseñaron que los arteriscos tenían algo que ver (indicaban) con los punteros de 'C' (vaya nivelazo tengo!).
NOTA---------------------------------------------------------------------------------
Por cierto para definir el prototipo debemos saber si la función es del tipo 'PASCAL', 'C' o 'WINAPI'.
Si disponemos de la DLL, para ello se puede crear un fichero DEF a partir de la DLL:
impdef.exe TuDLL.DEF TuDLL.DLL
Este fichero es de tipo texto (ascii) y su contenido será más o menos así:
LIBRARY TuDLL.DLL
EXPORTS
ClearAllAnalog @13 ; ClearAllAnalog
CreateTerWindow @8 ; CreateTerWindow
ClearAnalogChannel @14 ; ClearAnalogChannel
Si los simbolos usa SÓLO mayusculas y NO lleva subrayado delante seran del tipo 'PASCAL':
HWND PASCAL CreateTerWindow( struct arg_list * );
Si los simbolos usa mayusculas y minusculas y SI lleva subrayado delante seran del tipo 'C':
HWND CreateTerWindow( struct arg_list * );
Si los simbolos usa mayusculas y minusculas y NO lleva subrayado delante seran del tipo 'WINAPI':
HWND WINAPI CreateTerWindow( struct arg_list * );
Fin de NOTA--------------------------------------------------------------------------
También dentro del código 'C' debía declarar/codificar la función 'Harbour' (por decirlo de alguna manera, para que nos entendamos) que sería la que llamaría en última instancia a la función 'C'. Si no estoy equivocado su nombre debe estar en mayúsculas!, así:
HB_FUNC( ACREATETERWINDOW )
Esta función recibía en mi caso una array con los valores que debía asignar a los 'campos' de la estructura que recibiría la función 'C'.
Aquí empezó mi dolor de cabeza por ignorante, los int, long, BOOL, BYTE,... tienen tratamiento diferente según cada tipo de dato. Observad el código de ejemplo y vereis como se asignan.
Este es el código de la función 'Harbour':
HWND hWndTer;
struct arg_list aParams;
aParams.x = hb_parni(1,1);
aParams.LineLimit = hb_parnl(1,2);
aParams.WordWrap = hb_parl(1,3);
aParams.InputType = hb_parc(1,4)[ 0 ];
strcpy( aParams.file, hb_parc( 1, 5 ) );
aParams.hBuffer = ( HWND ) hb_parnl(1,6);
aParams.hInst = ( HWND ) hb_parnl(1,7);
aParams.hParentWnd = ( HWND ) hb_parnl(1,8);
aParams.style = hb_parnl(1,9);
hWndTer = CreateTerWindow( &aParams );
hb_reta( 2 ); // creamos y devolvemos un array de 2 elementos.
// rellenamos los datos del array (situado en "return", que se indica con -1)
hb_stornl( ( LONG ) hWndTer, -1, 1 );
hb_stornl( ( LONG ) aParams.hTextWnd, -1, 2 );
Bueno hasta aquí creo que sólo lo entiendo yo, aquí os dejo el código del PRG de ejemplo:
... y no os olvideis abrir y cerrar paréntesis,.... y los punto y coma al final de cada línea de 'C'.
Un Saludo
Carlos G.
Code: Select all
FUNCTION LlamaTer( oWndMain )
Local oWndTer := Nil
Local nStyle := 0
Local aParametros := {}
Local aRet := {}
DEFINE WINDOW oWndTer MDICHILD FROM 0,0 TO 520,804 TITLE "Control per escriure" ;
COLORS CLR_BLACK, nil OF oWndMain NOZOOM PIXEL //FIVEWIDI
ACTIVATE WINDOW oWndTer
nStyle := nOR( WS_CAPTION, WS_CHILD ,WS_VISIBLE, WS_TABSTOP )
aParametros := { 0, ; // x
999, ; // LineLimit
.F., ; // WordWrap
"J", ; // InputType
"C:\temp\ea.txt", ; // File
0, ; // hBuffer
0, ; // hInst
oWndTer:HWnd, ; // hParentWnd
nStyle, ; // Style
}
aRet := aCreateTerWindow( aParametros )
Return aRet
/* -------------------------------------------------------------------------------------- */
#pragma BEGINDUMP
#include <hbapi.h>
#include <windows.h>
struct arg_list {
int x; /* Initial x position of the editing window,
you may specify CW_USEDEFAULT to use default values. */
long LineLimit; /* Number of lines allowed in the editor window.
Set to 0 to have unlimited number of lines */
BOOL WordWrap; /* Set this flag to true (1), if you wish to enable the
word wrapping feature. */
BYTE InputType; /* This flag specifies the input type. If you wish to
edit a file, set the input_type to 'F'. Conversely,
if you wish to pass the text for editing in a buffer,
set this field to 'B'. */
BYTE file[131]; /* If the input type is set to 'F', specify the file
name for editing in this field. */
// ===== Buffer input fields only =======
HGLOBAL hBuffer; /* Specify the global memory handle containing the
input text data. This handle becomes the property
of the editor. Your program must never try to lock
or free this handle */
HINSTANCE hInst; // Handle of the current instanaces.
HWND hParentWnd; // Handle to the parent window
DWORD style; // Editor window style
};
HWND CreateTerWindow( struct arg_list * );
HB_FUNC( ACREATETERWINDOW )
{
HWND hWndTer;
struct arg_list aParams;
aParams.x = hb_parni(1,1);
aParams.LineLimit = hb_parnl(1,2);
aParams.WordWrap = hb_parl(1,3);
aParams.InputType = hb_parc(1,4)[ 0 ];
strcpy( aParams.file, hb_parc( 1, 5 ) );
aParams.hBuffer = ( HWND ) hb_parnl(1,6);
aParams.hInst = ( HWND ) hb_parnl(1,7);
aParams.hParentWnd = ( HWND ) hb_parnl(1,8);
aParams.style = hb_parnl(1,9);
hWndTer = CreateTerWindow( &aParams );
hb_reta( 2 ); // creamos y devolvemos un array de 2 elementos.
// rellenamos los datos del array (situado en "return", que se indica con -1)
hb_stornl( ( LONG ) hWndTer, -1, 1 );
hb_stornl( ( LONG ) aParams.hTextWnd, -1, 2 );
}
#pragma ENDDUMP