Step 6: Scripting the Function Call.
Now that you have the function declaration you need to pass it the proper arguments. Taking the function " GetFileVersionInfoA" listed in Step 4 the following script would be needed:
First you'll need to declare the datatypes. Keep in mind the variable names do not have to match the function declaration listed in step 4.
boolean lb_rtn // Return code
string ls_filename // 1st argument - filename
ulong lu_hand // 2nd argument - f_handle
ulong lu_len // 3rd argument - f_length
lpdata lpdata2 // Last argument - assigning an instance of a structure.
Next is the hardest part and that is assigning values to the arguments. This part may require use of the MSDN, API Bible or whatever reference is available that covers the function you are calling. In this particular case the information is contained within the MSDN.
The first argument " ls_filename ", should be set to the path and filename of the target file.
ls_filename = "c:\windows\calc.exe" // The calculator would be a good file to test against.
The second argument "lu_hand" according to the MSDN is ignored. This is probably reserved for a future version of Windows to use. To be safe the argument should be set to null.
setnull(lu_hand)
The third argument "lu_len" contains the size of the buffer that the information will be returned into. It is critical that the buffer size not be too small or the information may overflow into another part of memory causing a GPF or Dr. Watson error. In this particular case since the structure contains 13 elements that are all ulong, the number 256 should be sufficient to contain the information.
lu_len = 256
The last argument "lpdata2" is an instance of the structure "lpdata" and it will be populated by the function call.
The final script will appear as follows:
boolean lb_rtn
string ls_filename
ulong lu_hand, lu_len
lpdata lpdata2
ls_filename = "c:\windows\calc.exe" // The calculator would be a good file to test against.
setnull(lu_hand)
lu_len = 256
lb_rtn = GetFileVersionInfoA(ls_filename, lu_hand, lu_len, lpdata2)
// Viewing the output -------------------------------------------------------------
sle_1.text = string(lpdata2.dwSignature)
sle_2.text = string(lpdata2.dwStrucVersion)
sle_3.text = string(lpdata2.dwFileVersionMS)
sle_4.text = string(lpdata2.dwFileVersionLS)
sle_5.text = string(lpdata2.dwProductVersionMS)
sle_6.text = string(lpdata2.dwProductVersionLS)
sle_7.text = string(lpdata2.dwFileFlagsMask)
sle_8.text = string(lpdata2.dwFileFlags)
sle_9.text = string(lpdata2.dwFileOS)
sle_10.text = string(lpdata2.dwFileType)
sle_11.text = string(lpdata2.dwFileSubtype)
sle_12.text = string(lpdata2.dwFileDateMS)
sle_13.text = string(lpdata2.dwFileDateLS)
Messagebox("Return Code", string(lb_rtn))
// -----------------------------------------------------------------------------------------
Gotcha's to look out for:
1. Make sure the DLL you are referencing is the right bit level. This can sometimes be done by looking at the DLL's properties but most likely you'll need a third party product to determine this. Remember, a 16 bit application cannot make a 32 bit API call and visaversa.
2. Some functions are cap sensitive. "Findwindowa" might fail whereas "FindWindowA" works.
3. All handles in PowerBuilder 16 bit are UINT and 32 bit are ULONG. Using the datatypes INT or LONG may work but if the handle points to an area in high memory the latter two datatypes may not be able to support such a large number.
4. Make sure you have the correct function name. Under 32 bit many of the functions had an "A" (Whcih stands for Ascii) appended to the function name to make it unique from it's 16 bit counterpart. This allows developers to place both 16 bit and 32 bit function calls in the same application and then making the correct function call based on what bit platform the program is being run from. The real re






