AYUDA CON API'S

Post Reply
ARCC
Posts: 86
Joined: Sat Jun 24, 2006 4:27 pm
Location: Maracaibo - Zulia - Venezuela
Contact:

AYUDA CON API'S

Post by ARCC »

Buen día para todos...

Que tal amigos me pueden ayudar por favor a adaptar o utilizar las siguientes api's en FWH:

#pragma BEGINDUMP
#include <hbapi.h>
#include <windows.h>

HB_FUNC( GETDRIVETYPE )
{
hb_retnl( GetDriveTypeA( hb_parc( 1 ) ) );
} // SOLO FUNCIONA ESTA :-(

HB_FUNC( GETDISKFREESPACE )
{
LPSTR lpRootPathName = hb_parc(1);
LPLONG lpSectorsPerCluster = hb_parnl(2);
LPLONG lpBytesPerSector = hb_parnl(3);
LPLONG lpNumberOfFreeClusters = hb_parnl(4);
LPLONG lpTtoalNumberOfClusters = hb_parnl(5);

hb_retnl( GetDiskFreeSpaceA( lpRootPathName, &lpSectorsPerCluster,
&lpBytesPerSector, &lpNumberOfFreeClusters,
&lpTtoalNumberOfClusters ) )
}

HB_FUNC( GETVOLUMEINFORMATION )
{
LPSTR lpRootPathName = hb_parnc(1);
LPSTR lpVolumeNameBuffer = hb_parnc(2);
LPLONG nVolumeNameSize = hb_parnl(3);
LPLONG lpVolumeSerialNumber = hb_parnl(4);
LPLONG lpMaximumComponentLength = hb_parnl(5);
LPLONG lpFileSystemFlags = hb_parnl(6);
LPSTR lpFileSystemNameBuffer = hb_parnc(7);
LPLONG nFileSystemNameSize = hb_parnl(8);

hb_retnl( GetVolumeInformationA( lpRootPathName, lpVolumeNameBuffer,
nVolumeNameSize, &lpVolumeSerialNumber,
&lpMaximumComponentLength, &lpFileSystemFlags,
&lpFileSystemNameBuffer, nFileSystemNameSize ) )
}
#pragma ENDDUMP

Esto es lo poco que he podido hacer viendo ejemplos en el foro :(, a lo mejor es una tontería pero de verdad no manejo para nada C, por eso solicito su gran ayuda.

Nota: Les agradecería si me pueden informar si existe alguna ayuda para realizar estas conversiones de de API en C, ya que serian de gra ayuda para _ :lol:
Saludos,

Antonio Castro
Maracaibo - Venezuela
ant_cas@yahoo.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Antonio,

LP... significa LONG POINTER que significa "puntero" (LONG = largo, que significa 32 bits). Un "puntero" es la dirección de un valor:

Code: Select all

HB_FUNC( GETDISKFREESPACE ) 
{ 
   LPSTR lpRootPathName = hb_parc(1); 
   LONG SectorsPerCluster; 
   LONG BytesPerSector; 
   LONG NumberOfFreeClusters; 
   LONG TotalNumberOfClusters; 

   hb_retnl( GetDiskFreeSpace( lpRootPathName, &SectorsPerCluster, 
                 &BytesPerSector, &NumberOfFreeClusters, 
                 &TotalNumberOfClusters ) ) 
} 
Las cadenas son siempre punteros a un grupo de bytes, por lo que no hay que modificarlos.

Y ahora falta devolver los valores que la función pone en esas variables tipo LONG. Inténtalo :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Mira el prototipo de la función en C:

Code: Select all

BOOL WINAPI GetDiskFreeSpace(
  __in   LPCTSTR lpRootPathName,
  __out  LPDWORD lpSectorsPerCluster,
  __out  LPDWORD lpBytesPerSector,
  __out  LPDWORD lpNumberOfFreeClusters,
  __out  LPDWORD lpTotalNumberOfClusters
);
__in se refiere a que es valor de "entrada". Es decir, recibe ese valor.
__out se refiere a que es valor de "salida". Es decir, va a devolver un valor en esa variable.

Por cierto, que hemos declarado las variables como LONG y lo correcto es LPDWORD (puntero largo a DWORD). DWORD significa "double word" (palabra larga) refiriéndose que es un valor de 32 bits. Con signo, si no me equivoco.
regards, saludos

Antonio Linares
www.fivetechsoft.com
ARCC
Posts: 86
Joined: Sat Jun 24, 2006 4:27 pm
Location: Maracaibo - Zulia - Venezuela
Contact:

Post by ARCC »

Buen día para todos...

Que tal Antonio, despues de estar un BUEN rato tratando que hacer que funcione el código que me diste no he pordido hacer sino esto y no funciona porque no devuelve el valor en las variable por referencia:

BOOL WINAPI GetDiskFreeSpace(
IN LPCTSTR lpRootPathName,
OUT LPDWORD lpSectorsPerCluster,
OUT LPDWORD lpBytesPerSector,
OUT LPDWORD lpNumberOfFreeClusters,
OUT LPDWORD lpTotalNumberOfClusters );

Por favor me puedes ayuda a resolver este problemita, e insisto si me pueden informar por favor si existe alguna ayuda para realizar estas conversiones de API en C, así no te quitaría más tiempo en estas tonterías
Saludos,

Antonio Castro
Maracaibo - Venezuela
ant_cas@yahoo.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Antonio,

La única ayuda es aprender (practicando) a usar el lenguaje C y revisar el código en lenguaje C que proporciona FiveWin en los directorios source\winapi y source\function

Para completar tu función tienes que decidir como quieres devolver los valores, ya que como has visto, la función en C devuelve varios valores que deposita en variables de tipo DWORD.

Quieres devolver un array con todos esos valores ó prefieres pasar esos valores por referencia a la función y que la función en C _ ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
ARCC
Posts: 86
Joined: Sat Jun 24, 2006 4:27 pm
Location: Maracaibo - Zulia - Venezuela
Contact:

Post by ARCC »

Buen día para todos...
Antonio Linares wrote:Antonio,
Quieres devolver un array con todos esos valores ó prefieres pasar esos valores por referencia a la función y que la función en C _ ?
Creo que lo mejor es que la misma función devuelva los valores por referencia, pero sería bueno saber como se devuelven a un array, así tendría las 2 formas de hacerlo y me serviría para aprender y no molestarte de nuevo por esto. Gracias Antonio por tu ayuda
Saludos,

Antonio Castro
Maracaibo - Venezuela
ant_cas@yahoo.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Antonio,

Para devolver un array hay que añadir este código al final:

Code: Select all

   hb_reta( 4 ); // creamos y devolvemos un array de 4 elementos.

   // rellenamos los datos del array (situado en "return", que se indica con -1)
   hb_stornl( SectorsPerCluster, -1, 1 );
   hb_stornl( BytesPerSector, -1, 2 );
   hb_stornl( NumberOfFreeClusters, -1, 3 );
   hb_stornl( TotalNumberOfClusters, -1, 4 );
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Para devolver los valores por referencia hay que añadir este código al final (y no usar el anterior):

Code: Select all

   hb_stornl( SectorsPerCluster, 2 ); // Almacena en el parámetro 2
   hb_stornl( BytesPerSector, 3 );  // Almacena en el parámetro 3
   hb_stornl( NumberOfFreeClusters, 4 ); // Almacena en el parámetro 4 
   hb_stornl( TotalNumberOfClusters, 5 ); // Almacena en el parámetro 5
Esos valores se tienen que pasar a la función desde el PRG con "@" delante, para indicar "por referencia".
regards, saludos

Antonio Linares
www.fivetechsoft.com
ARCC
Posts: 86
Joined: Sat Jun 24, 2006 4:27 pm
Location: Maracaibo - Zulia - Venezuela
Contact:

Post by ARCC »

Buen día para todos...

Antonio,

Muchas gracias por tu ayuda resolví viendo unos ejemplos y la librería hbapi.h, me orienté gracias a los comentrios que tiene cada función y vi que eran para devolver los valores por referencia :lol:

hb_stornl( long lValue, int iParam, ... ); /* stores a long on a variable by reference */

hb_storc( char * szText, int iParam, ... ); /* stores a szString on a variable by reference */

Tambien había visto hb_reta( ULONG ulLen ); /* returns an array with a specific length */, pero no sabía como cargar los valores :D

Tuve un pequeño problema para hacer trabajar la función GETVOLUMEINFORMATION, poque con este código no funciona

Code: Select all

HB_FUNC( GETVOLUMEINFORMATION )
{
   LPSTR lpRootPathName = hb_parc( 1 );
   LPSTR lpVolumeNameBuffer;
   DWORD nVolumeNameSize;
   DWORD lpVolumeSerialNumber;
   DWORD lpMaximumComponentLength;
   DWORD lpFileSystemFlags;
   LPSTR FlpFileSystemNameBuffer;
   DWORD nFileSystemNameSize;

   hb_retnl( GetVolumeInformation( lpRootPathName, lpVolumeNameBuffer,
                                   lpVolumeNameBuffer, &lpVolumeSerialNumber,
                                   lpMaximumComponentLength, lpFileSystemFlags,
                                   lpFileSystemNameBuffer, lpFileSystemNameBuffer ) );

   hb_storc(  lpVolumeNameBuffer,     2 );
   hb_storc(  lpFileSystemNameBuffer, 7 );
   hb_stornl( lpVolumeSerialNumber,   4 );
} // ASI NO FUNCIONA
Pero me fijé en el código de harddisk.c y lo adapté a mis necesidades y funcionó perfecto

Code: Select all

HB_FUNC( GETVOLUMEINFORMATION )
{
   LPSTR lpRootPathName = hb_parc( 1 );
   BYTE  lpVolumeNameBuffer[ 256 ];
   DWORD lpVolumeSerialNumber;
   BYTE  lpFileSystemNameBuffer[ 256 ];

   hb_retnl( GetVolumeInformation( lpRootPathName, lpVolumeNameBuffer,
                                   lpVolumeNameBuffer, &lpVolumeSerialNumber,
                                   lpMaximumComponentLength, lpFileSystemFlags,
                                   lpFileSystemNameBuffer, lpFileSystemNameBuffer ) );

   hb_storc(  lpVolumeNameBuffer,     2 );
   hb_storc(  lpFileSystemNameBuffer, 7 );
   hb_stornl( lpVolumeSerialNumber,   4 );
} // ESTE ASI FUNCIONA
pero tengo la duda de porque no funciona de la primera forma si está igual como lo dice el API??? :cry:
Saludos,

Antonio Castro
Maracaibo - Venezuela
ant_cas@yahoo.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Antonio,

Tienes que comprender mejor el tema de los punteros en C. Entender los punteros en C es obtener el "aprobado" en lenguaje C :-)

El lenguaje C no permite errores, pero eso es lo bueno de él, que hace exactamente lo que se le dice. Porque si se le dice algo mal, él no lo arregla por nosotros :-)

Si te fijas en la documentación de la función del API, dice esto:

lpVolumeNameBuffer
Points to a buffer that receives the name of the specified volume.

Es decir, ha de apuntar a un buffer que va a recibir el nombre. Luego has de crear un buffer, por eso cuando lo declaras como BYTE lpVolumeNameBuffer[ 256 ]; entonces si estás creando un buffer, y el nombre de ese buffer es su dirección (es su "puntero").

Si lo declaras como LPSTR lo que declaras es una dirección, pero una dirección a donde ?? a ningún sitio, lo que resultará en un GPF seguramente :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
ARCC
Posts: 86
Joined: Sat Jun 24, 2006 4:27 pm
Location: Maracaibo - Zulia - Venezuela
Contact:

Post by ARCC »

Buen día para todos...

Antonio,

Muy agradecido por tu tiempo, paciencia y por las explicaciones tan claras, se ve a leguas que eres un barbaro en C :shock:

Por lo pronto me bajé unos manuales de apuntadores en C para conocer algo al respecto :roll:, y gracias a tu ayuda pude hacerle unas mejoras a la clase TDiskInfo, las cuales voy a colocar por aca para ver si le sirve de algo a los compañeros del foro.
Saludos,

Antonio Castro
Maracaibo - Venezuela
ant_cas@yahoo.com
Post Reply