Date: 02-16-2022
Return to Index
created by gbSnippets
'There are times when a programmer wants to provide access to a DLL, but must take
'into account the possibility that the DLL is not present on the user's machine. Loading
'the DLL at run-time, rather than compile-time is the solution, for which PowerBASIC
'provides the CALL DWord statement. Used with the API LoadLibrary and
'GetProcAddress functions, Call Dword is an alternative to linking with DLLs at compile-time.
'In general, four steps must be taken:
'1. Declare
'use PowerBASIC Declare to define a local Sub/Function that has the same arguments
'as the function that will be called from the external DLL. It can have the same
'name as the target procedure in the external DLL. The Sub/Function is not actually
'written, just Declare the function so the name can be used to indirectly call
'the external DLL.
'2. LoadLibrary
'use this API at runtime to load the DLL containing the target procedure
'3. GetProcAddress
'use this API to get the address of a procedure in the now-loaded DLL
'4. Call DWord
'use this PowerBASIC statement to run the DLL procedure, using either
'of the two syntax options for Call DWord
'Primary Code:
'Syntax: there are two syntax options, depending on whether the target
'procedure has arguments. The enclosing () are required.
Call Dword dwpointer [{BDECL | CDECL | SDECL} ()] 'no arguments, default is SDECL
Call Dword dwpointer USING abc([arguments]) [TO result_var] 'arguments
'Use the following to get the pointer to a local sub/function:
dwPointer = CodePTR(MySub) 'address of the entry point of a local sub/function
'Notes on USING Syntax:
' - requires a corresponding Declare statement (no LIB clause) to create
' a model procedure declaration
' - TO is optional, except for Functions whose return value is a non-Integer class
'Compilable Example: (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
'#Dim All
%Unicode=1
#Include "Win32API.inc"
'Here's the target procedure in the external DLL Kernel32.DLL
'Declare Function GetDiskFreeSpaceEx LIB "KERNEL32.DLL" ALIAS "GetDiskFreeSpaceExA" _
' (lpPath As AsciiZ, lpFreeToCaller AS QUAD, lpTotalBytes AS QUAD, lpTotalFreeBytes AS QUAD) As Long
Declare Function MyDiskFreeSpaceEx _
(lpPath As AsciiZ, lpFreeToCaller AS QUAD, lpTotalBytes AS QUAD, lpTotalFreeBytes AS QUAD) As Long
Global hDlg as Dword
Function PBMain() As Long
Dialog New Pixels, 0, "Test Code",300,300,200,200, %WS_OverlappedWindow To hDlg
Control Add Button, hDlg, 100,"Push", 50,10,100,20
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
If CB.Msg = %WM_Command AND CB.Ctl = 100 AND CB.Ctlmsg = %BN_Clicked Then
Local hLib AS Dword, pAddr AS Dword, szDrv As AsciiZ * %MAX_PATH, lResult As Long
Local FreeToUserQuota&&, SizeOfDisk&&, TotalFree&&
szDrv = "C:\"
hLib = LoadLibrary("KERNEL32.DLL")
pAddr = GetProcAddress(hLib, "GetDiskFreeSpaceExA")
If pAddr <> 0 Then
Call Dword pAddr USING MyDiskFreeSpaceEx(szDrv, FreeToUserQuota&&, SizeOfDisk&&, TotalFree&&) TO lResult
MsgBox Str$(FreeToUserQuota&&) + " " + Str$(SizeOfDisk&&) + " " + Str$(TotalFree&&)
End If
FreeLibrary hLib
End If
End Function
'gbs_00321
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm