FiveWin, Harbour y C para ignorantes.

Post Reply
FiveWiDi
Posts: 910
Joined: Mon Oct 10, 2005 2:38 pm

FiveWin, Harbour y C para ignorantes.

Post by FiveWiDi »

Hola a todos,

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
 
Last edited by FiveWiDi on Thu Mar 26, 2009 10:38 am, edited 4 times in total.
Un Saludo
Carlos G.

FiveWin 19.06 + Harbour 3.2, BCC 7 Windows 10
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: FiveWin, Harbour y C para ignorantes.

Post by Antonio Linares »

Carlos,

Me alegro de que lo hayas conseguido y te agradezco que lo compartas con todos para que asi le sirva a mas gente.

Gracias :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
Salvador
Posts: 142
Joined: Sun Dec 18, 2005 3:18 pm
Location: España

Re: FiveWin, Harbour y C para ignorantes.

Post by Salvador »

Hola a todos.
Creo que este post es el sitio mas indicado para hacer mi pregunta.
Estoy utilizando FWPPC y la función de Harbour hb_reta(x) devuelve un array de una sola dimensión.
¿Como puedo devolver un array multidimensional?.

Gracias.
Saludos
Salvador
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: FiveWin, Harbour y C para ignorantes.

Post by Antonio Linares »

Salvador,

El código fuente de la función Directory() de Harbour es un buen ejemplo:

Code: Select all

/*
 * $Id: direct.c 10040 2009-01-14 15:32:43Z vszakats $
 */

/*
 * Harbour Project source code:
 * DIRECTORY() function
 *
 * Copyright 1999 Leslee Griffith <les.griffith@vantagesystems.ca>
 * www - http://www.harbour-project.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
 *
 * As a special exception, the Harbour Project gives permission for
 * additional uses of the text contained in its release of Harbour.
 *
 * The exception is that, if you link the Harbour libraries with other
 * files to produce an executable, this does not by itself cause the
 * resulting executable to be covered by the GNU General Public License.
 * Your use of that executable is in no way restricted on account of
 * linking the Harbour library code into it.
 *
 * This exception does not however invalidate any other reasons why
 * the executable file might be covered by the GNU General Public License.
 *
 * This exception applies only to the code released by the Harbour
 * Project under the name Harbour.  If you copy code from other
 * Harbour Project or Free Software Foundation releases into a copy of
 * Harbour, as the General Public License permits, the exception does
 * not apply to the code that you add in this way.  To avoid misleading
 * anyone as to the status of such modified files, you must delete
 * this exception notice from them.
 *
 * If you write modifications of your own for Harbour, it is your choice
 * whether to permit this exception to apply to your modifications.
 * If you do not wish that, delete this exception notice.
 *
 */

/*
 * Notes from the fringe... <ptucker@sympatico.ca>
 *
 * Clipper is a bit schizoid with the treatment of file attributes, but we've
 * emulated that weirdness here for your viewing amusement.
 *
 * In Clippers' homeworld of DOS, there are 5 basic attributes: 'A'rchive,
 * 'H'idden, 'S'ystem, 'R'eadonly and 'D'irectory.  In addition, a file can
 * have no attributes, and only 1 file per physical partition can have the
 * 'V'olume label.
 *
 * For a given file request, it is implied that the attribute mask includes
 * all attributes except 'H'idden, 'S'ystem, 'D'irectory and 'V'olume.
 * The returned file list will always include (for instance) 'R'eadOnly files
 * unless they also happen to be 'H'idden and that attribute was not requested.
 *
 * "V" is a special case - you will get back the entry that describes the
 * volume label for the drive implied by the filemask.
 *
 * Differences from the 'standard' (where supported):
 * - Filenames will be returned in the same case as they are stored in the
 *   directory.  Clipper (and VO too) will convert the names to upper case
 * - Filenames will be the full filename as supported by the OS in use.
 * - There are a number of additional file attributes returned.
 *   They are:
 *       'I' - DEVICE      File is a device
 *       'T' - TEMPORARY   File is a Temporary file
 *       'P' - SPARSE      File is Sparse
 *       'L' - REPARSE     File/Dir is a reparse point
 *       'C' - COMPRESSED  File/Dir is compressed
 *       'O' - OFFLINE     File/Dir is not online
 *       'X' - NOTINDEXED  Exclude File/Dir from Indexing Service
 *       'E' - ENCRYPTED   File/Dir is Encrypted
 *       'M' - VOLCOMP     Volume Supports Compression
 * - Clipper can sometimes drop the ReadOnly indication of directories.
 *   Harbour detects this correctly.
 *
 * TODO: - check that path support vis stat works on all platforms
 *       - UNC Support? ie: dir \\myserver\root
 *
 */

#include "hbapi.h"
#include "hbapifs.h"
#include "hbapiitm.h"

#include "directry.ch"

/* NOTE: 8.3 support should be added in a separate way, like
         as a function which converts full names to 8.3 names, since
         this issue is very much platform specific, and this is
         not the only place which may need the conversion [vszakats]. */

HB_FUNC( DIRECTORY )
{
   char *    szDirSpec = hb_parc( 1 );
   char *    szAttributes = hb_parc( 2 );
   BOOL      fFree = FALSE;
   ULONG     ulMask;

   PHB_ITEM  pDir = hb_itemArrayNew( 0 );
   PHB_FFIND ffind;

   /* Get the passed attributes and convert them to Harbour Flags */

   ulMask = HB_FA_ARCHIVE
          | HB_FA_READONLY
          | HB_FA_DEVICE
          | HB_FA_TEMPORARY
          | HB_FA_SPARSE
          | HB_FA_REPARSE
          | HB_FA_COMPRESSED
          | HB_FA_OFFLINE
          | HB_FA_NOTINDEXED
          | HB_FA_ENCRYPTED
          | HB_FA_VOLCOMP;

   if( szAttributes && *szAttributes )
   {
      if( ( ulMask |= hb_fsAttrEncode( szAttributes ) ) & HB_FA_LABEL )
      {
         /* NOTE: This is Clipper Doc compatible. (not operationally) */
         ulMask = HB_FA_LABEL;
      }
   }

   if( szDirSpec && *szDirSpec )
   {
      szDirSpec = ( char * ) hb_fsNameConv( ( BYTE * ) szDirSpec, &fFree );
      if( ulMask != HB_FA_LABEL )
      {
         if( *szDirSpec )
         {
            /* CA-Cl*pper compatible behavior - add all file mask when
             * last character is directory or drive separator
             */
            int iLen = strlen( szDirSpec ) - 1;
#ifdef HB_OS_HAS_DRIVE_LETTER
            if( szDirSpec[ iLen ] == HB_OS_PATH_DELIM_CHR ||
                szDirSpec[ iLen ] == HB_OS_DRIVE_DELIM_CHR )
#else
            if( szDirSpec[ iLen ] == HB_OS_PATH_DELIM_CHR )
#endif
            {
               if( fFree )
               {
                  char * szTemp = hb_xstrcpy( NULL, szDirSpec, HB_OS_ALLFILE_MASK, NULL );
                  hb_xfree( szDirSpec );
                  szDirSpec = szTemp;
               }
               else
               {
                  szDirSpec = hb_xstrcpy( NULL, szDirSpec, HB_OS_ALLFILE_MASK, NULL );
                  fFree = TRUE;
               }
            }
         }
         else
         {
            if( fFree )
            {
               hb_xfree( szDirSpec );
               fFree = FALSE;
            }
            szDirSpec = ( char * ) HB_OS_ALLFILE_MASK;
         }
      }
   }
   else
      szDirSpec = ( char * ) HB_OS_ALLFILE_MASK;

   /* Get the file list */

   if( ( ffind = hb_fsFindFirst( szDirSpec, ulMask ) ) != NULL )
   {
      PHB_ITEM pSubarray = hb_itemNew( NULL );

      do
      {
         char buffer[ 32 ];

         hb_arrayNew( pSubarray, F_LEN );
         hb_arraySetC   ( pSubarray, F_NAME, ffind->szName );
         hb_arraySetNInt( pSubarray, F_SIZE, ffind->size );
         hb_arraySetDL  ( pSubarray, F_DATE, ffind->lDate );
         hb_arraySetC   ( pSubarray, F_TIME, ffind->szTime );
         hb_arraySetC   ( pSubarray, F_ATTR, hb_fsAttrDecode( ffind->attr, buffer ) );

         /* Don't exit when array limit is reached */
         hb_arrayAddForward( pDir, pSubarray );
      }
      while( hb_fsFindNext( ffind ) );

      hb_itemRelease( pSubarray );

      hb_fsFindClose( ffind );
   }

   if( fFree )
      hb_xfree( szDirSpec );

   hb_itemReturnRelease( pDir );
}
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply