[返回]
中国计算机报2000年第21期

Win32 API函数与PB编程

经 乾

  在PB编程实践中,如何获取当前目录?如何得到光盘的盘符?如何控制由Run运行的程序?对于此类PB不能直接解决的问题,可以求助于Win32 API函数。其实PB编程的大部分FAQ都可以通过Win32 API函数来解决。下面是一些典型的应用。

  1.如何使PB窗口总在最上层(Always On Top)

  通过SetWindowPos函数把窗口的显示层次修改为HWND—TOPMOST,就可使指定窗口永远不会被其它窗口覆盖,该函数声明为:

  Function Long SetWindowPos(Long hwnd,Long ord,Long x,Long y,Long dx,Long dy,Long uflag) Library ″user32″

  参数1为要顶层显示的窗口句柄,参数2指定显示的层次,参数7为附加选项,其余参数指定窗口位置和大小,均可忽略。在窗口的Open或Activate事件中加入如下函数调用:

  SetWindowPos(Handle(This),-1,0,0,0,0,3)

  参数2取-1表示在最顶层显示窗口,取1表示在最底层显示;最后一个参数若取1,表示窗口大小保持不变,取2表示保持位置不变,因此,取3(=1+2)表示大小和位置均保持不变,取0表示将窗口的大小和位置改变为指定值。

  2.在PB中如何获得光盘盘符

  通过GetDriveType函数可以获取驱动器(如:软驱、硬盘、光驱、网络映射驱动器等)的信息,该函数声明为:

  Function Uint GetDriveTypeA (String drive) Library ″kernel32.dll″

  参数为一个盘符(如“C:"),返回值:1表示未知,2表示软驱,3表示本地硬盘,4表示网络驱动器,5表示光驱。因此如下代码可以获得光盘的盘符:

  For i=Asc(′D′) to Asc(′Z′)

  //列举所有可能的CDROM驱动器

  If GetDriveTypeA(Char(i)+″:″)=5 Then

  //若找到CDROM

  MessageBox(″CDROM″,Char(i)+″:″)

  //显示光盘盘符

  Exit //退出列举

  End If

  Next

  3.在PB中如何获取目录信息

  ⑴获取当前目录。通过GetCurrentDirectory函数可以获取当前目录,该函数声明为:

  Function Ulong GetCurrentDirectoryA(Ulong buflen, ref String dir) Library ″kernel32.dll″

  参数2为接收当前目录的字符缓冲区,前面必须加ref表示地址引用;参数1用来指定字符缓冲区的长度。调用过程为:

  String curdir

  curdir=Space(256)

  //为字符缓冲区开辟内存空间

  GetCurrentDirectoryA(256,curdir)

  MessageBox(″Current Directory″,curdir)

  ⑵获取Windows及系统目录。要用到GetWindowsDirectory和GetSystemDirectory两个函数,须作如下声明:

  Function Uint GetWindowsDirectoryA(ref String dir,Uint buflen) Library ″kernel32.dll″

  Function Uint GetSystemDirectoryA(ref String dir,Uint buflen) Library ″kernel32.dll″

  4.在PB中如何注销当前用户、关闭计算机、重启计算机

  通过ExitWindowsEx函数可实现这三个功能,首先作如下声明:

  Function Long ExitWindowsEx(Long uflag,Long nouse) Library ″user32.dll″

  参数2保留不用,可取0;参数1取0可以注销当前用户,取1可以关闭计算机,取2可以重启计算机,其值再加4表示强制结束“未响应"的进程。

  5.控制由Run运行的程序(简称Run程序)

  在PB程序设计中,可以用Run()来运行一些程序。比如用户按了F1,就运行一个chm文件。但Run程序无法与PB主程序协调工作,若用户按了多次F1,就会启动Run程序的多个实例,主程序退出时,Run程序依然运行。可以用如下函数来使它们协调工作:

  Function Ulong FindWindowA(Ulong classname, String windowname) Library ″user32.dll″

  Function Long SetParent(Long childwin,Long parentwin) Library ″user32.dll″

  ⑴使Run程序只运行一个实例

  handle=FindWindowA(nul,wtitle)

  //查找Run程序是否已经运行,wtitle为Run程序的标题

  IF handle〉0 Then Return

  //若已经在运行就返回

  Run(″C:\Program Files\Joint\Joint.chm″)

  //否则运行Run程序

  ⑵PB主程序退出时,Run程序也关闭

  handle=FindWindowA(nul,wtitle)

  SetParent(handle,Handle(w—main))

  //使Run程序窗口成为PB主程序的子窗口

  6.映射网络驱动器

  若要在程序中把远程主机的资源映射到本地驱动器,可以用如下函数:

  Function long WNetAddConnectionA(String path,string pwd,String drv) Library ″mpr.dll″

  如下代码可以把远程主机Alexander上的共享文件夹My Documents映射到本地的J盘:

  WNetAddConnectionA(″\\Alexander\My Documents″,″″,″J:″)//参数2为访问口令

  它的作用相当于在DOS提示符下执行:Net Use J: \\Alexander\My Documents

  7.显示或隐藏Windows的任务栏

  要显示或隐藏任务栏,首先要得到它的窗口句柄。任务栏是一个特殊的窗口,它的窗口类为:Shell—TrayWnd,没有标题,故只能用FindWindowEx函数来取得它的句柄:

  Function long FindWindowEx(long ph, long ch, ref String cn, ref String wn) Library ′user32′

  Function Long ShowWindow(Long hWnd, Long nCmdShow ) Library ′user32′

  用ShowWindow来显示或隐藏窗口,其第二个参数为0表示隐藏,为5表示显示:

  handle = FindWindowEx(0,0,″Shell—TrayWnd″, wn)//wn为空串

  ShowWindow(handle,0)//隐藏任务栏

  8.如何将长文件名转换为短文件名

  通过GetShortPathName函数可以把长文件名转换为8.3格式,其声明为:

  Function Long GetShortPathNameA(String lf, ref String sf, Long buflen) Library ′kernel32′

  参数1为长文件名,参数2为保存短文件名的缓冲区,参数3为缓冲区长度。例如:

  GetShortPathNameA(″C:\My Documents\PowerBuilder编程实践.Doc″, sf,256)//sf=Space(256)

  9.如何在PB中实现延时

  延时函数很有用,PB虽然没有提供,但可以通过Win32的Sleep函数来扩展:

  Function Long Sleep(Long ms) Library ″kernel32″

  调用:Sleep(1000)//延时1秒

  10.如何在PB中播放音乐

  PB没有提供任何多媒体函数,要播放音乐只能通过Win32 API的PlaySound来实现:

  Function Long PlaySound (String Filename,Int Mod,Int Flags ) Library ″winmm.dll″

  参数1为wav文件名,参数2必须取0,参数3取1表示后台播放,取8表示循环播放,因此取9(=1+8)表示在后台循环播放。