Tuesday, September 1, 2009

Examples of using C_EXEC in SCL

SCL provides a function called C_EXEC which will allow you to execute functions in Windows DLL files. If you have used the Declare Function ... functionality in VBA then you'll see this is the same kind of functionality.

Basically, to use C_EXEC you need to know the name of the function in the DLL file, as well as its argument list. For example, the Sleep function resides in the kernel32.dll file that comes with Windows. It takes one argument, which is the sleep time in milliseconds. This function simply delays for the specified period of time, then returns control of the program back to whatever called it. This allows you to put a pause of whatever length you want in your program.

Since there is no built-in sleep function in SCL, this is a good function to have handy, always compiled and ready to use.

The syntax for the C_EXEC function is simple:

C_EXEC( routine_name_and_location , arg1 , arg...)

where routine_name_and_location is the dll filename and function name separated by a colon (:). Any extra arguments to C_EXEC should correspond to arguments in the DLL function.

So for the Sleep function, a C_EXEC call would look like this:
C_EXEC( 'kernel32.dll:Sleep' , 1000 )

Calling this in SCL would make your SCL code delay for 1 second.

We can wrap this in a nice routine that you can leave compiled all the time:

routine sleep( milliseconds : Integer ) : Integer
Const
THE_DLL 'kernel32.dll'
THE_CMD 'Sleep'
Var
func_return : Integer
Begin
/*
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
*/
func_return = c_exec( THE_DLL + ":" + THE_CMD , \
milliseconds )
return true
End


Here's another example using the mciSendStringA function in winmm.dll to open your CD drive door (I know, very useful):

procedure open_cd_drive()
Const
THE_DLL 'winmm.dll'
THE_CMD 'mciSendStringA'
Var
func_return : Integer
lpstrCommand : String
lpstrReturnString : String
uReturnLength : Integer
hwndCallback : Integer
Begin

/*
Public Declare Function SendCDcmd Lib "winmm.dll" \
Alias "mciSendStringA" ( \
ByVal lpstrCommand As String, \
ByVal lpstrReturnString As String, \
ByVal uReturnLength As Long, \
ByVal hwndCallback As Long) As Long
*/
lpstrCommand = 'set CDAudio door open'
lpstrReturnString = ''
uReturnLength = 127
hwndCallback = 0

func_return = c_exec( THE_DLL + ":" + THE_CMD , \
lpstrCommand , \
lpstrReturnString , \
uReturnLength , \
hwndCallback )

End

Hopefully this gives you a good taste of what is possible with using C_EXEC to extend some of the functionality of SCL beyond what's currently available. If you want to see how you can create your own Windows DLL (and thereby provide your own custom functions in a compiled form) you can look at this web site. At some point in the future I hope to release a DLL library of functions to help add some functionality to SCL.