Paradox Community
Search:

 Welcome |  What is Paradox |  Paradox Folk |  Paradox Solutions |
 Interactive Paradox |  Paradox Programming |  Internet/Intranet Development |
 Support Options |  Classified Ads |  Wish List |  Submissions 


Paradox Programming Articles  |  Beyond Help Articles  |  Tips & Tricks Articles  


Using Win32 API Functions with Structures
A Real Example
© 2001 Pascal Hutton

Using Win32 API Functions with Structures

Introduction

This sample uses the function EnumPorts from winspool.drv to enumerate ports installed on your system.
EnumPorts(pName cptr,
          Level clong,
          pPorts clong,
          cbBuf clong,
          pcbNeeded cptr,
          pcReturned cptr) clong [stdcall "EnumPortsA"]

Parameters

pName
Pointer to a null-terminated string that specifies the name of the server whose printer ports you wish to enumerate.

If pName is NULL, the function enumerates the local machine's printer ports.

Level
[in] Specifies the type of information returned in the pPorts buffer. If Level is 1, pPorts receives an array of PORT_INFO_1 structures. If Level is 2, pPorts receives an array of PORT_INFO_2 structures.

pPorts
[out] Pointer to a buffer that receives an array of PORT_INFO_1 or PORT_INFO_2 structures. Each structure contains data that describes an available printer port. The buffer must be large enough to store the strings pointed to by the structure members.

To determine the required buffer size, call EnumPorts with cbBuf set to zero. EnumPorts fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, and the pcbNeeded parameter returns the size, in bytes, of the buffer required to hold the array of structures and their data.

cbBuf
[in] Specifies the size, in bytes, of the buffer pointed to by pPorts.

pcbNeeded
[out] Pointer to a variable that receives the number of bytes copied to the pPorts buffer. If the the buffer is too small, the function fails and the variable receives the number of bytes required.

pcReturned
[out] Pointer to a variable that receives the number of PORT_INFO_1 or PORT_INFO_2 structures returned in the pPorts buffer. This is the number of printer ports that are available on the specified server.
NOTE:
[in]: we send a value to the dll
[out]: the dll sends data to the buffer (fills the buffer)


Return Values

If the function succeeds, the return value is a nonzero value.


The Code

PORT_INFO_1 is a structure composed of a string containing the name of the port (for example "LPT1:")
uses "winspool.drv"
EnumPorts(pName cptr,
          Level cLong,
          lpbPorts cLong,
          cbBuf cLong,
          pcbNeeded cptr,
          pcReturned cptr) cLong [stdcall "EnumPortsA"]
Enduses

uses "kernel32.dll"
GetLastError()clong [stdcall "GetLastError"]
GlobalAlloc(wFlags cLong,
            dwBytes cLong) cLong [stdcall]
RtlMoveMemory(hpvDest cptr,
              hpvSource clong,
              cbCopy cLong) cLong [stdcall]
GlobalFree(hMem cLong) cLong [stdcall]
Enduses


method pushButton(var eventInfo Event)

var
  x, rep, arpinfo, ret, ned, buf longint
  pName, buffer, ports string
  hmem, hmem2, adr longint
endvar

ports = ""
pName.blank()
ret = 0
ned = 0
hmem.blank()
buf = 0

;// here we call the function with a level 1
;// structure and all others parameters set to
;// 0 or blank, so we'll have an error and the
;// size of the buffer needed will be known.
rep = EnumPorts(pName,1,hmem,buf,ned,ret)
ports = ""

;// we assign the value of the buffer needed
;// to the size of the buffer to receive data
buf = ned

;// we allocate memory, 4 bytes will be needed
;// because the structure contains only one record
;// which is a pointer to a string (a longint value)
hmem = GlobalAlloc(fromhex("0x40"),4)

;// and now we can call the function again
rep = EnumPorts(pName,1,hmem,buf,ned,ret)

;// adr is a temporary variable which is
;// used to go through the array
adr = hmem

;// ret is the number of ports returned
;// by the function
for x from 1 to ret
  ;// buffer is the string containing the port name
  buffer = space(32)

  ;// we move the pointer contained in adr
  ;// in another pointer
  rep = RtlMoveMemory(hmem2,adr,4)

  ;// then move the data pointed by hmem2 in the
  ;// buffer 32 bytes are moved to the buffer
  rep = RtlMoveMemory(buffer,hmem2,32)

  ;// and add the result to a string
  ports = ports + buffer.rtrim()+ " "

  ;// move 4 bytes ahead to get the next port
  adr = adr + 4
endfor

;// free the memory block
rep = GlobalFree(hmem)

;// display information
msginfo("Ports on your System",ports)

endMethod

Summary

This can be used to "play" with much more complicated structures, for more information or real cases, visit http://paradoxtips.free.fr/.

Discussion of this article


 Feedback |  Paradox Day |  Who Uses Paradox |  I Use Paradox |  Downloads 


 The information provided on this Web site is not in any way sponsored or endorsed by Corel Corporation.
 Paradox is a registered trademark of Corel Corporation.


 Modified: 15 May 2003
 Terms of Use / Legal Disclaimer


 Copyright © 2001- 2003 Paradox Community. All rights reserved. 
 Company and product names are trademarks or registered trademarks of their respective companies. 
 Authors hold the copyrights to their own works. Please contact the author of any article for details.