Page 1 of 2
DLL32 function
Posted: Fri Mar 28, 2008 5:03 pm
by metaldrummer
Amigos:
Agradeceré quien me pueda orientar o indicar donde obtener información en como manejar DLL32 Function ya que necesito de ésta para poder acceder al API de Windows.
Mil gracias de antemano.
Posted: Fri Mar 28, 2008 6:40 pm
by Antonio Linares
David,
A que función del API de Windows quieres acceder ?
Haz una búsqueda en estos foros por DLL AND function y te aparecerán muchos ejemplos
Posted: Fri Mar 28, 2008 8:05 pm
by JmGarcia
En el fichero DLL.CH esta parte de lo que buscas:
Code: Select all
#xcommand DLL [<static:STATIC>] FUNCTION <FuncName>( [ <uParam1> AS <type1> ] ;
[, <uParamN> AS <typeN> ] ) ;
AS <return> [<pascal:PASCAL>] [ FROM <SymName> ] LIB <*DllName*> ;
=> ;
[<static>] function <FuncName>( [NOREF(<uParam1>)] [,NOREF(<uParamN>)] ) ;;
local hDLL := If( ValType( <DllName> ) == "N", <DllName>, LoadLibrary( <(DllName)> ) ) ;;
local uResult ;;
local cFarProc ;;
if Abs( hDLL ) > 32 ;;
cFarProc = GetProcAddress( hDLL,;
If( [ Empty( <SymName> ) == ] .t., <(FuncName)>, <SymName> ),;
[<.pascal.>], <return> [,<type1>] [,<typeN>] ) ;;
uResult = CallDLL( cFarProc [,<uParam1>] [,<uParamN>] ) ;;
If( ValType( <DllName> ) == "N",, FreeLibrary( hDLL ) ) ;;
else ;;
MsgAlert( "Error code: " + LTrim( Str( hDLL ) ) + " loading " + ;
If( ValType( <DllName> ) == "C", <DllName>, Str( <DllName> ) ) ) ;;
end ;;
return uResult
Code: Select all
#xcommand DLL32 [<static:STATIC>] FUNCTION <FuncName>( [ <uParam1> AS <type1> ] ;
[, <uParamN> AS <typeN> ] ) ;
AS <return> [<pascal:PASCAL>] [ FROM <SymName> ] LIB <*DllName*> ;
=> ;
[<static>] function <FuncName>( [NOREF(<uParam1>)] [,NOREF(<uParamN>)] ) ;;
local hDLL := If( ValType( <DllName> ) == "N", <DllName>, LoadLib32( <(DllName)> ) ) ;;
local uResult ;;
local cFarProc ;;
if Abs( hDLL ) <= 32 ;;
MsgAlert( "Error code: " + LTrim( Str( hDLL ) ) + " loading " + <DllName> ) ;;
else ;;
cFarProc = GetProc32( hDLL,;
If( [ Empty( <SymName> ) == ] .t., <(FuncName)>, <SymName> ),;
[<.pascal.>], <return> [,<type1>] [,<typeN>] ) ;;
uResult = CallDLL32( cFarProc [,<uParam1>] [,<uParamN>] ) ;;
If( ValType( <DllName> ) == "N",, FreeLib32( hDLL ) ) ;;
end ;;
return uResult
#endif
Posted: Fri Mar 28, 2008 8:23 pm
by metaldrummer
JmGarcia wrote:En el fichero DLL.CH esta parte de lo que buscas:
Code: Select all
#xcommand DLL [<static:STATIC>] FUNCTION <FuncName>( [ <uParam1> AS <type1> ] ;
[, <uParamN> AS <typeN> ] ) ;
AS <return> [<pascal:PASCAL>] [ FROM <SymName> ] LIB <*DllName*> ;
=> ;
[<static>] function <FuncName>( [NOREF(<uParam1>)] [,NOREF(<uParamN>)] ) ;;
local hDLL := If( ValType( <DllName> ) == "N", <DllName>, LoadLibrary( <(DllName)> ) ) ;;
local uResult ;;
local cFarProc ;;
if Abs( hDLL ) > 32 ;;
cFarProc = GetProcAddress( hDLL,;
If( [ Empty( <SymName> ) == ] .t., <(FuncName)>, <SymName> ),;
[<.pascal.>], <return> [,<type1>] [,<typeN>] ) ;;
uResult = CallDLL( cFarProc [,<uParam1>] [,<uParamN>] ) ;;
If( ValType( <DllName> ) == "N",, FreeLibrary( hDLL ) ) ;;
else ;;
MsgAlert( "Error code: " + LTrim( Str( hDLL ) ) + " loading " + ;
If( ValType( <DllName> ) == "C", <DllName>, Str( <DllName> ) ) ) ;;
end ;;
return uResult
Code: Select all
#xcommand DLL32 [<static:STATIC>] FUNCTION <FuncName>( [ <uParam1> AS <type1> ] ;
[, <uParamN> AS <typeN> ] ) ;
AS <return> [<pascal:PASCAL>] [ FROM <SymName> ] LIB <*DllName*> ;
=> ;
[<static>] function <FuncName>( [NOREF(<uParam1>)] [,NOREF(<uParamN>)] ) ;;
local hDLL := If( ValType( <DllName> ) == "N", <DllName>, LoadLib32( <(DllName)> ) ) ;;
local uResult ;;
local cFarProc ;;
if Abs( hDLL ) <= 32 ;;
MsgAlert( "Error code: " + LTrim( Str( hDLL ) ) + " loading " + <DllName> ) ;;
else ;;
cFarProc = GetProc32( hDLL,;
If( [ Empty( <SymName> ) == ] .t., <(FuncName)>, <SymName> ),;
[<.pascal.>], <return> [,<type1>] [,<typeN>] ) ;;
uResult = CallDLL32( cFarProc [,<uParam1>] [,<uParamN>] ) ;;
If( ValType( <DllName> ) == "N",, FreeLib32( hDLL ) ) ;;
end ;;
return uResult
#endif
Gracias...esoy ya lo había visto
El tema es que no hayo como acceder a una función del api para realizar pruebas.
Estoy intentando obtener las impresoras que tengo instaladas en el pc.
Si utilizo:
aGetPrinters()
funciona ok...pero estoy intentando hacerlo de la forma difícil para poder entender como acceder a las funciones del api. Tengo instalado el sdk de windows para obtener las refencias a las funciones que necesito.
Este es el código que estoy utilizando y no me devuelve el arreglo con los datos:
Code: Select all
#include "fivewin.ch"
//#include "winspool.h"
#define PRINTER_ENUM_DEFAULT 0x00000001
#define PRINTER_ENUM_LOCAL 0x00000002
#define PRINTER_ENUM_CONNECTIONS 0x00000004
#define PRINTER_ENUM_FAVORITE 0x00000004
#define PRINTER_ENUM_NAME 0x00000008
#define PRINTER_ENUM_REMOTE 0x00000010
#define PRINTER_ENUM_SHARED 0x00000020
#define PRINTER_ENUM_NETWORK 0x00000040
FUNCTION Main()
LOCAL pThread, aPrinters:=Array()
IF MsgYesNo("¿Deséa mostrar las impresoras del sistema?")
EnumPrinters(PRINTER_ENUM_NAME,,1,@aPrinters)
aPrinters:=EnumPrinters(PRINTER_ENUM_NAME,,1)
//aPrinters:=aGetPrinters()
FOR n := 1 TO Len(aPrinters)
MsgInfo(aPrinters[n])
NEXT
ENDIF
RETURN NIL
DLL32 FUNCTION EnumPrinters( Flags AS DWORD, Name AS LPSTR, Level AS DWORD, @aPrinters AS BYTE, cbBuf AS DWORD, @pcbNeeded AS DWORD, @pcReturned AS DWORD) ;
AS LONG PASCAL FROM "EnumPrinters" LIB "winspool.drv"
Este es el link a la referencia del api que quiero probar para empezar a entender todo este cuento:
http://msdn2.microsoft.com/en-us/librar ... S.85).aspx
Gracias por la ayuda que me puedan brindar.
Posted: Fri Mar 28, 2008 10:06 pm
by metaldrummer
Encontré un ejemplo en un foro de no se donde y funcionó lo que buscaba, pero
¿es tan complicado el poder trabajar con el api de windows?....y soy menos que novato en C++....ufff
pongo el código por si a alguien le sirve.
Ojalá alguien más aporte sobre esto...imagínense que esto es solo la punta del iceberg para mi ya que la finalidad entre otras es poder detectar cuando llega una impresión a una impresora "X", pausar la impresión y autorizar su salida en forma manual.
Code: Select all
#include "hbclass.ch"
#include "fivewin.ch"
FUNCTION Main()
IF MsgYesNo("¿Deséa mostrar las impresoras del sistema?")
aPrinters:=WinGetPrinters()
Msginfo( Len(aPrinters), "Impresoras Encontradas")
MsgInfo( WinDefaultPrinter(), "Impresora por Defecto")
FOR n := 1 TO Len(aPrinters)
MsgInfo(aPrinters[n])
NEXT
ENDIF
RETURN NIL
STATIC FUNCTION WinGetPrinters()
LOCAL aPrn:= {}, nStart:=1, cPrinters, nStop,nPos, cPrn
cPrinters:= ENUMPRINTERS()+';'
nStop:= LEN(cPrinters)+1
DO WHILE nStart< nStop
nPos:=AT(';',cPrinters,nStart)
IF !EMPTY(cPrn:= SUBSTR(cPrinters,nStart,nPos-nStart))
AADD(aPrn,cPrn)
ENDIF
nStart:= nPos+1
ENDDO
RETURN(aPrn)
#pragma BEGINDUMP
#undef UNICODE
#include <windows.h>
#include "hbapi.h"
#include "hbvm.h"
#include "hbstack.h"
#include "hbapiitm.h"
#define MAX_FILE_NAME 1024
#define BIG_BUFFER (1024*32)
HB_FUNC ( ENUMPRINTERS)
{
UCHAR *Result ;
DWORD x, Flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS ;
LPSTR Name = NULL ;
DWORD Level = 5 ;
PRINTER_INFO_5 *pPrinterEnum, *pFree;
PRINTER_INFO_4 *pPrinterEnum4, *pFree4;
DWORD cbBuf ;
DWORD BytesNeeded=0 ;
DWORD NumOfPrinters=0 ;
OSVERSIONINFO osvi ; // altered to check Windows Version
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx (&osvi);
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
Level = 4 ;
EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum4,0,&BytesNeeded,&NumOfPrinters) ;
if (BytesNeeded > 0)
{
Result = (UCHAR *) hb_xgrab(BytesNeeded) ;
*Result = '\0' ;
pFree4 = pPrinterEnum4 = (PRINTER_INFO_4 *) hb_xgrab(BytesNeeded) ;
cbBuf = BytesNeeded ;
if (EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum4,cbBuf,&BytesNeeded,&NumOfPrinters))
{
for (x=0 ; x< NumOfPrinters ; x++, pPrinterEnum4++ )
{
strcat(Result,pPrinterEnum4->pPrinterName) ;
strcat(Result,";") ;
}
}
hb_retc(Result) ;
hb_xfree(Result) ;
hb_xfree(pFree4) ;
}
else
hb_retc("") ;
}
else
{
EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum,0,&BytesNeeded,&NumOfPrinters) ;
if (BytesNeeded > 0)
{
Result = (UCHAR *) hb_xgrab(BytesNeeded) ;
*Result = '\0' ;
pFree = pPrinterEnum = (PRINTER_INFO_5 *) hb_xgrab(BytesNeeded) ;
cbBuf = BytesNeeded ;
if (EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum,cbBuf,&BytesNeeded,&NumOfPrinters))
{
for (x=0 ; x< NumOfPrinters ; x++, pPrinterEnum++ )
{
strcat(Result,pPrinterEnum->pPrinterName) ;
strcat(Result,";") ;
}
}
hb_retc(Result) ;
hb_xfree(Result) ;
hb_xfree(pFree) ;
}
else
hb_retc("") ;
}
}
HB_FUNC( WINDEFAULTPRINTER )
{
DWORD x, y ;
UCHAR lpReturnedString[MAX_FILE_NAME] ;
x = GetProfileString("windows","device","",lpReturnedString,MAX_FILE_NAME-1);
y = 0 ;
while ( y < x && lpReturnedString[y] != ',' )
y++ ;
hb_retclen(lpReturnedString,y) ;
}
#pragma ENDDUMP
Espero le sirva a alguien.
Saludos
P.D.: new_indika si ves esto te mande un mail a tu correo a ver si te puedo consultar algunas cosillas.
Posted: Fri Mar 28, 2008 10:11 pm
by JmGarcia
metaldrummer wrote:DLL32 FUNCTION EnumPrinters( Flags AS DWORD, Name AS LPSTR, Level AS DWORD, @aPrinters AS BYTE, cbBuf AS DWORD, @pcbNeeded AS DWORD, @pcReturned AS DWORD) ;
AS LONG PASCAL FROM "EnumPrinters" LIB "winspool.drv"
En la definicion DLL32 no tienes que poner las "arrobas" (@) solo cuando la amas a la función.
Posted: Mon Mar 31, 2008 3:53 pm
by metaldrummer
JmGarcia wrote:metaldrummer wrote:DLL32 FUNCTION EnumPrinters( Flags AS DWORD, Name AS LPSTR, Level AS DWORD, @aPrinters AS BYTE, cbBuf AS DWORD, @pcbNeeded AS DWORD, @pcReturned AS DWORD) ;
AS LONG PASCAL FROM "EnumPrinters" LIB "winspool.drv"
En la definicion DLL32 no tienes que poner las "arrobas" (@) solo cuando la amas a la función.
Mira:
Tengo este código:
Code: Select all
include "fivewin.ch"
#define PRINTER_ENUM_DEFAULT 0x00000001
#define PRINTER_ENUM_LOCAL 0x00000002
#define PRINTER_ENUM_CONNECTIONS 0x00000004
#define PRINTER_ENUM_FAVORITE 0x00000004
#define PRINTER_ENUM_NAME 0x00000008
#define PRINTER_ENUM_REMOTE 0x00000010
#define PRINTER_ENUM_SHARED 0x00000020
#define PRINTER_ENUM_NETWORK 0x00000040
FUNCTION Main()
LOCAL aPrinters
IF MsgYesNo("¿Deséa mostrar las impresoras del sistema?")
EnumPrinters(PRINTER_ENUM_NAME,NILL,1,@aPrinters,, @nNecesitado, @nRetornado)
FOR n := 1 TO Len(aPrinters)
MsgInfo(aPrinters[n,1])
NEXT
ENDIF
RETURN NIL
DLL32 FUNCTION EnumPrinters( Flags AS DWORD, Name AS LPSTR, Level AS DWORD, aPrinters AS BYTE, cbBuf AS DWORD, pcbNeeded AS DWORD, pcReturned AS DWORD) ;
AS BOOL PASCAL FROM "EnumPrinters" LIB "winspool.drv"
Para este código siempre me retorna aPrinters como NILL lo mismo que las otras variables por referencia ya que nNecesitado debiera devolver el número necesitado de espacio para almacenar la información en aPrinters que nunca recibe un arreglo como indica la documentación.
En qué podré estar fallando?
Saludos
Posted: Mon Mar 31, 2008 8:38 pm
by Antonio Linares
David,
La función EnumPrinters() del API tiene un nivel de complejidad que dificilmente puede tratarse con el comando DLL FUNCTION desde PRG.
La función que has publicado en C, te funciona ?
Posted: Mon Mar 31, 2008 9:48 pm
by metaldrummer
La función EnumPrinters() del API tiene un nivel de complejidad que dificilmente puede tratarse con el comando DLL FUNCTION desde PRG.
La función que has publicado en C, te funciona ?
La función que encontré en internet que originalmente creo estaba orientada a alaska xbase++ funciona de lujo....
Mi pregunta es: porqué la DLL32 funciona en ciertas funciones y en otras no?...
Lamentablemente estoy recién comenzando a leer documentación de c++ y la verdad que soy menos que novato.
Saludos
Posted: Mon Mar 31, 2008 10:17 pm
by Antonio Linares
David,
DLL FUNCTION ... permite un acceso relativamente simple a funciones que reciben unos parámetros y devuelven un resultado.
En el caso de EnumPrinters() se rellenan unas estructuras desde C, por la misma función EnumPrinters(), y hay que manejar la información de esas estructuras, desde bajo nivel.
Teoricamente se podría hacer usando DLL FUNCTION, pero puede resultar más complejo que hacerlo usando C directamente.
Estás ya familiarizado con el uso de estructuras en lenguaje C ?
Posted: Mon Mar 31, 2008 11:12 pm
by metaldrummer
Antonio Linares wrote:David,
DLL FUNCTION ... permite un acceso relativamente simple a funciones que reciben unos parámetros y devuelven un resultado.
En el caso de EnumPrinters() se rellenan unas estructuras desde C, por la misma función EnumPrinters(), y hay que manejar la información de esas estructuras, desde bajo nivel.
Teoricamente se podría hacer usando DLL FUNCTION, pero puede resultar más complejo que hacerlo usando C directamente.
Estás ya familiarizado con el uso de estructuras en lenguaje C ?
Estimado Antonio:
Estoy recién comenzando a leer algo de C y obviamente entiendo que su curva de aprendizaje es más lenta que otros lenguajes.
Vi que hay un DllCall de xharbour que permite llamar a las funciones del API, pero cuando intento llamar al DLL la aplicación no corre. Seguro que estoy haciendo todo o casi todo mal por mi prácticamente nulo conocimiento de C. Claro que para mí es un gran reto desarrollar esta aplicación y si esto me significa tener que aprender C y C++ GENIAL ya que es algo que he anhelado por mucho tiempo. Lo divertido es que ahora tengo que hacerlo bajo presión.
Voy a intentar leer un poco un manual que bajé de internet orientado a Borland C++ y agradeceré tu ayuda y la de cualquier colega del foro.
Yo por mi parte espero sacar adelante esto y poder desarrollar una clase que almacene todo este know how
Un abrazo y agradezo cualquier ayuda
Posted: Tue Apr 01, 2008 7:53 am
by Antonio Linares
David,
El lenguaje C es realmente simple. De ahí radica su potencia y su belleza.
Fué diseñado para programar el sistema operativo Unix (padre de Linux, Mac, etc.), y se convirtió de "facto" en el lenguaje ideal para desarrollar los sistemas operativos. Por ejemplo, decidimos usar el lenguaje C para construir Harbour, para así obtener la máxima potencia y tener un control total
Hace exactamente lo que se le dice. Si se le dice algo mal, él lo hace mal. Es decir, no hace cosas por "su cuenta". Es un robot que nos obedece en todo. Y por otra parte está tan cercano a la máquina, que en realidad es "generar" ensamblador, usando un lenguaje y "lógica" a nivel humano.
Haz todas las preguntas que quieras aqui, que con mucho gusto te ayudaremos a que te "enamores" de él
y de paso le servirá a más compañeros.
Posted: Tue Apr 01, 2008 3:17 pm
by ARCC
Buen día para todos...
Que tal David y Antonio, disculpen que les realice esta pregunta la cual no está directamente asociada a la prengunta inicial, pero la cual creo que nos va a beneficiar a todos.
Al igual que David estoy incursionando en lenguaje C, y aunque tengo muy poca experiencia porque en la universidad vi lenguaje C versión 1.0, pero fue hace mucho tiempo y no recuerdo mucho.
La pregunta es: Antonio ya que debemos aprender lenguaje C para aplicarlo a [x]Harbour que versión nos recomiendas o se aplica a [x]Harbour?, porque existen muchas versiones de C (C, C++, C#, Visual C, etc.) y como debemos aprender y para no perder mucho tiempo, nos enfocariamos solo en aprender la versión que necesitamos. De antemano muchas gracias
Posted: Tue Apr 01, 2008 6:18 pm
by Antonio Linares
Lenguaje C solamente. Ni C++, ni C#, ni Visual C.
Posted: Tue Apr 01, 2008 7:08 pm
by metaldrummer
Antonio:
Mil gracias por tus respuestas. Si no me equivoco C++ es simplemente C con soporte de Clases, correcto?
Si es así, me debiera servir el libro "Teach Yourselve Borland C++ in 14 days"?. Obviamente sin aplicar la parte de objetos y ya que utilizo borland c++ 5.51 como compilador.
Nuevamente mil gracias por tu ayuda desinteresada.
Saludos