ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Prototyping API Calls for PowerBuilder

Prototyping API Calls for PowerBuilder

原创 Linux操作系统 作者:phield 时间:2008-09-09 10:57:57 0 删除 编辑
Prototyping API Calls for PowerBuilder 7.0.x, 8.0.x, 9.0.x and 10.0.x
The tens of thousands of function calls in the Windows environment can be helpful to PowerBuilder users, but documenting them is nearly impossible. After hundreds of user inquiries, Powersoft Technical Support compiled these technical tips to enable PowerBuilder developers to translate standard Microsoft function calls into PowerBuilder syntax, and to empower developers to use any of the external API calls within their PowerBuilder environments..

The following information will help you translate Windows SDK call to a PowerBuilder API function call. It doesn't matter whether what version of PowerBuilder is being used.

Step 1: Converting an SDK Call to a PowerBuilder API Call.

First you need to get the syntax that wil be converted. This can be obtained from either a Windows API Bible or the MSDN (Microsoft Developers Network).

Step 2: Determining Whether it is a Function or a Subroutine.

Function calls return a value; subroutines do not.

Here is an example of a Microsoft function:
BOOL GetFileVersionInfo( LPTSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData );

Here is an example of a Microsoft subroutine:
VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer);

Step 3: Converting the datatypes from Microsoft to PowerBuilder.

<>

MICROSOFT PowerBuilder
Bool Boolean
Char* Ref String
Colorref Ulong
Dword Ulong
Handle Ulong
Hdc Ulong
Hfile Ulong
Hinstance Ulong
Hwnd Ulong
Int Int
Lparm Ulong
Lpbyte Ref Long
Lpbword Ref Ulong
Lpstr,Lpststr Ref String
Lpfiletime Ref Time
Lpint Ref Long
Lpvoid Ref Struct struct_inst
Mcierror Long
Pbyte Reg Long[#]
Short Int
Structure Ref Struct Struct_inst
Uint Uint
Void** SUBROUTINE
Word Ulong
Wparam Ulong

Most of the datatypes are listed above, but some may be missing. When in doubt read the datatype description first.

*If the word "Callback appears as a datatype, it cannot be performed by PowerBuilder. Callback routines are functions that are called from within functions.

Step 4: Coding the Global/Local External Function:

This is a Microsoft function:
BOOL GetFileVersionInfo( LPTSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData );

The BOOL represents a boolean return code, which is translated to "Boolean" in PowerBuilder. A LPCTSTR means a pointer to a string (see step 3). In PowerBuilder, simply use the word "ref" before declaring the string. An LPVOID indicates that a structure is being used. In owerBuilder, create a structure, assign it to an instance variable of that structure and pass it by reference. As a result, the following function declarations can be derived:

PowerBuilder example
FUNCTION boolean GetFileVersionInfoA(ref string filename, ulong f_handle, ulong f_length, ref lpdata lpdata2) LIBRARY "version.dll"

Note: In the "gotchas" section listed below, you'll get a further explanation why an "A" is appended to the 32-bit function. You'll also find a
handy technique to help you locate function calls within the DLLs.

Step 5: Creating a Structure

In this particular example a structure is needed so you'll need information on what elements are contained within this structure. The MSDN
provides this information since the function being called is a Windows function.

In the MSDN the structure appears like this:
LPDATA = { DWORD dwSignature ; DWORD dwStrucVersion ; DWORD dwFileVersionMS ; DWORD dwFileVersionLS ; DWORD
dwProductVersionMS ; DWORD dwProductVersionLS ; DWORD dwFileFlagsMask ; DWORD dwFileFlags ; DWORD dwFileOS ;
DWORD dwFileType ; DWORD dwFileSubtype ; DWORD dwFileDateMS ; DWORD dwFileDateLS }

In PB you would go into the structure painter and in this particular case all of these elements would be converted to ULONG. If one of the
elements within the structure was a nested structure or callback routine you would not be able to use this function within PB. In that case
the only option would be to create a C DLL that makes the function call and call it from PB.

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:windowscalc.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:windowscalc.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. Some functions are cap sensitive. "Findwindowa" might fail whereas "FindWindowA" works.
2. All handles in PowerBuilder 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" (for Ansi)
Microsoft named the functions this way to differentiate between (A)-Ansi and (W)-Wide/Unicode format.
MSDN does not always list the proper names for the functions.
For example: GetFileVersionInfo is listed as a 32 bit function but it is in fact GetFileVersionInfoA.
5. Global versus Local External Function declaration.
If the function is declared globally it can be called from anywhere in your application.
If you declare the function as a Local External Function it can only be called from that window where it's declared.
Local Functions use less resources than global but the difference is very minimal.

Error Messages and what they mean:
1. Error: Error opening DLL library for external function at line in the event of object

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/32036/viewspace-442589/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-09-08

  • 博文量
    5
  • 访问量
    36932