28 FOR \
PowerBuilder Win32 API函数调用参考手册 FUNCTION Long GetWindowsDirectory ( REF String lpBuffer, Long nSize) LIBRARY \ALIAS
函数调用后,函数将修改lpBuffer参数值,并将Windows系统路径返回到PB对应的该变量中。
而对于API函数sndPlaySound需通过传值的方式为函数传入一个String型数字声音 (.wav) 文件名,函数的PB声明如下:
FUNCTION Long sndPlaySound ( String lpszSoundName, Long uFlags) LIBRARY \FOR \
函数调用后,将演奏该文件。如:
String ls_SoundFile Long ll_ReturnLength
ls_SoundFile = Dir(\ll_ReturnLength = sndPlaySound(ls_SoundFile, 1)
这两个API函数中,尽管第一个参数都是String型,但前者是引用传递,后者是值传递,传递方式的不同,两者的作用也大相径庭。
总之,对于以引用方式传递的字符串参数,必须在调用外部函数前,使用PB的系统函数Space为参数变量分配存储空间,否则,将引起应用系统的不稳定运行(这一点往往被初学者所忽略)。
此外,如果外部函数需要一个固定长度的字符串参数,用户可使用字符型数组。
2.2.4 传递结构型数据
许多外部函数的参数要求一个结构,结构是多个相关变量的集合,其作为函数的参数并没有什么特殊之处。用户所要做的就是了解结构的定义,然后在PB中创建一个相同的结构,并确保将结构的各个成员正确地从C转换为PB的数据类型。
在PB中,如果需要将整个结构作为一个参数传递,必须以引用的方式传递,不能以传值的方式传递。在这种情况下,PB将传递结构第一个成员的地址。和数组一样,在内存中,结构的各个成员是按连续顺序存放的。
结构定义后,在引用之前必须定义一个结构型实例变量,必要时,还需初始化结构成员(给结构成员赋值)。
下面通过API函数GetSystemInfo的调用,说明如何向函数传递结构。该函数可以取得当前系统信息摘要,函数的参数为结构SYSTEM_INFO,该结构C原型定义如下:
typedef struct _SYSTEM_INFO { DWORD dwOemId; struct {
WORD wProcessorArchitecture; WORD wReserved; }
第2章 API函数的声明和调用 DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress; LPVOID lpMaximumApplicationAddress; DWORD dwActiveProcessorMask; DWORD dwNumberOfProcessors; DWORD dwProcessorType; DWORD dwAllocationGranularity; WORD wProcessorLevel; WORD wProcessorRevision; } SYSTEM_INFO, *LPSYSTEM_INFO;
29 SYSTEM_INFO结构在PB中各成员的数据类型定义和含义如下:
数据类型 结构变量 long long long
long long long long long long long long long
dwOemID
说 明
废弃,不再使用。在Win 98/95/Me设置为0; 系统CPU架构取PROCESSOR_ARCHITECTURE_UNKNOWN 或PROCESSOR_ARCHITECTURE_INTEL; 保留,未使用; 虚拟页面的相关信息;
应用和DLL库能够访问的最低端内存地址; 应用和DLL库能够访问的最高端内存地址; 表示每个处理器的掩码; 系统安装的处理器的数目;
处理器类型,返回值如表18-5所示; 被分配的虚拟内存间隔; 与系统相关的处理器架构级别号; 与系统相关的处理器架构修订号。
wProcessorArchitecture wReserved dwPageSize
lpMinimumApplicationAddress lpMaximumApplicationAddress dwActiveProcessorMask dwNumberOrfProcessors dwProcessorType wProcessorLevel
dwAllocationGranularity wProcessorRevision
GetSystemInfo函数在PB中的声明如下:
SUBROUTINE GetSystemInfo ( REF SYSTEM_INFO lpSystemInfo) LIBRARY \
当用该函数获取系统CPU架构类型时,函数的调用程序如下:
//获取CPU类型
SYSTEM_INFO lstr_SysInfo GetSystemInfo(lstr_SysInfo)
Choose Case lstr_SysInfo.dwProcessorType Case PROCESSOR_INTEL_386
Return \
Case PROCESSOR_INTEL_486
30
PowerBuilder Win32 API函数调用参考手册 Return \Return \Return \Return \Return \未知类型)\
Case PROCESSOR_INTEL_PENTIUM Case PROCESSOR_MIPS_R4000 Case PROCESSOR_ALPHA_21064 Case Else End Choose
2.2.5 传递数组
1. 直接将外部函数参数声明为动态数组
一些外部函数要求数组作为参数。数组的传递方式与PB系统函数和用户自定义函数的传递规则相同。
如果要传递数组,用户需要在声明外部函数时,在参数后面加上方括号[],表明该参数变量为数组变量。例如,要传递一个动态数组,假定有一个函数名为MyExFunc的函数,需要接受一动态长整型数组作为参数,设参数名为al_MyArray,在调用函数的脚本中,需要对数组变量或传递来的实例变量进行说明,如:
Long al_MyArray[]
当调用函数,忽略方括号,表示传递整个数组,如:
uf_MyExFunc( al_MyArray )
当然,我们也可以在函数参数中使用定长数组的传递,如果在声明外部函数时,将某个参数声明为定长数组,在调用函数时也必须为函数传入等长度的数组。另外,PB不支持动态数组和定长数组的转换,否则将会出现如下错误信息:
Bad argument list for function:XXXXX
下面我们以API函数Polygon( )调用为例,说明向外部函数传递动态数组的过程。Polygon函数的功能是画多边形,该函数PB声明如下:
FUNCTION Long Polygon ( Long hdc, REF POINTAPI lpPoint[], Long nCount) LIBRARY \
函数共有3个参数,其中第一个参数hDC是绘图设备场景的句柄;第二个参数lpPoint为POINTAPI结构型数组,该数组中的元素是所画多边形各个顶点的坐标;第三个参数nCount是所画多边形顶点的个数。第一个和第三个参数都是Long型,使用传值方式传递,而第二个参数是一个POINTAPI结构,该结构用来描述每个顶点的x、y坐标,其在PB中的定义如下:
Type POINTAPI
Long x
第2章 API函数的声明和调用
Long y
31 End Type
图2.1是示例程序的运行窗口,除了需为窗口声明上面的多边形函数外,还要声明下面外部函数GetDC,该函数用来获得窗口设备场景的句柄:
FUNCTION Long GetDC ( Long hwnd) LIBRARY \
按钮“绘制多边形”的Clicked事件脚本,演示了如何向外部函数传递数组,函数脚本如下:
Long ll_hDC, ll_WinHandle
POINTAPI lstr_Point[] //声明一个动态结构型数组
//指定多边形各顶点的坐标 lstr_Point[1].x = 10 lstr_Point[1].y = 10 lstr_Point[2].x = 250 lstr_Point[2].y = 30 lstr_Point[3].x = 166 lstr_Point[3].y = 80 lstr_Point[4].x = 150 lstr_Point[4].y = 150 lstr_Point[5].x = 50 lstr_Point[5].y = 20
//取得窗口的句柄
ll_WinHandle = Handle(Parent)
//获得窗口的设备场景 ll_hDC = GetDC(ll_WinHandle)
//绘制多边形
Polygon(ll_hDC, lstr_Point, 5)
32 PowerBuilder Win32 API函数调用参考手册
图2.1 通过传递数组绘制多边形
由于第二个参数的定义为REF POINTAPI lpPoint[],该参数通过引用方式传递,因此调用时,实际上是把数组的第一个元素的地址传送给Polygon函数。而由于数组在内存中是按顺序连续存放数据,因此可以通过第三个参数向Polygon函数传递5个数组元素。
如果要使用定长数组,函数的声明必须修改为:
FUNCTION Long Polygon ( Long hdc, REF POINTAPI lpPoint[5], Long nCount) LIBRARY \
函数调用时相应脚本要修改为:
Long ll_hDC, ll_WinHandle
POINTAPI lstr_Point[5] //声明一个定长结构型数组
//指定多边形各顶点的坐标 lstr_Point[1].x = 10 lstr_Point[1].y = 10 lstr_Point[2].x = 250 lstr_Point[2].y = 30 lstr_Point[3].x = 166 lstr_Point[3].y = 80 lstr_Point[4].x = 150 lstr_Point[4].y = 150 lstr_Point[5].x = 50 lstr_Point[5].y = 20
//取得窗口的句柄
ll_WinHandle = Handle(Parent)
//获得窗口的设备场景