PowerBuilder编程俱乐部

Author: 柯建勋 Date: 2000年 第37期

  大家好!PowerBuilder(以下简称PB)编程俱乐部又与大家见面了,各位可到俱乐部主页http://kjx.126.com或http://pb70.yeah.net的BBS讨论区去提交或解答问题。如遇主页访问故障,可以直接访问论坛:http://kukoc.abc.yesite.com,俱乐部欢迎你的到来!
    一、请问用PB如何调用Windows的API函数,即具体要在哪几个地方写些代码?最好能给出实例。
  答:调用 API 函数步骤为:
  1.在适当的位置声明函数,如窗口内、Application内、UserObject内,定义在Local External Function或Global External Function中。如播放声音的API函数:
  Function boolean sndPlaySoundA (string SoundName,uint Flags) Library ″WINMM.DLL″
  Function uint waveOutGetNumDevs () Library ″WINMM.DLL″
  也可以创建一个UserObject,集中声明常用的API及函数本地化,如定义用户对象u_external_function:
  Declare Local External Function(定义外部函数):
  Function boolean sndPlaySoundA (string SoundName,uint Flags) Library ″WINMM.DLL″
  Function uint waveOutGetNumDevs () Library ″WINMM.DLL″
  Declare User Object Function(定义用户对象函数):
          uf_play_sound(string as_wave_name,integer ai_option)
  函数内容如下:
              //参数:as_wave_name :wav文件名
           //ai_option:同步或异步(I/0)
            uint lui_numdevs
            lui_numdevs = WaveOutGetNumDevs()
            if lui_numdevs > 0 Then
                    sndPlaySoundA(as_wave_name,ai_option)
                    return 1
            else
                    return -1
            end If
  2.调用时在程序中定义一个实体并调用其函数:
        u_external_function iu_external_function
        iu_external_function = create u_external_function
        iu_external_function.uf_play_sound(′c:\windows\media\ding.wav′,1)
  试试看,如果有声卡,就会听到“叮”的一声。
  其它API函数也是如此处理。关于如何声明,在俱乐部的主页上有一个帮助,在我的主页PB手记http://liulee.yeah.net 的“源码天地”下也有一个集成了常用API函数的用户对象,你可以下载回去参考。(此题由流方回答)
    二、如何在PB应用程序中创建目录?
  答:可以用API函数CreateDirectoryA实现,定义:
  function boolean CreateDirectoryA(ref string pathname,int sa) Library ″Kernel32.dll″
  调用代码:
         boolean rtn
        string ls_dir
        ls_dir = ″c:\newdir″ //要创建的目录名称
        rtn = CreateDirectoryA(ls_dir,0)
        if rtn then
              Messagebox(″Succeed″,″Succeed!″)
        else
              Messagebox(″Failed″,″Failed!″)
        End if
    三、我编的系统中用了OCX控件,当系统编译后发行时必须带上该OCX控件,但在用户的机子上必须注册该OCX控件才能使用,否则程序运行会出错,请问用什么方法注册该OCX控件?
  答:提供以下几种方法供参考:
  1.在Windows命令行或DOS下运行:regsvr32 ocxname.OCX
  2.用Install Shield 做安装程序时,在里面选“Self-Registered”,安装程序将自动注册。
  3.在PB程序中调用regsvr32实现,安装程序只需负责将OCX拷贝到相应路径下,这个路径PB程序必须可以得到,建议拷贝到Windows系统目录或者与执行文件同目录下。
  具体代码:
  //首先定义API函数,如果OCX控件在与执行文件同目录下,使用GetCurrentDirectory函数;如果OCX控件放在系统目录下,使用GetSystemDirectory函数。
  Function ulong GetCurrentDirectory(ulong nBufferLength,ref string lpBuffer) Library     ″kernel32.dll″ Alias for ″GetCurrentDirectoryA″
  Function uint GetSystemDirectory(ref string lpBuffer,uint uSize) Library ″kernel32.dll″ Alias for ″GetSystemDirectoryA″
  //假设OCX文件在Windows系统目录下,在PB应用(Application)的Open事件中编写如下代码
  string ls_PathName,ls_Command
        ulong ll_RequiredBufferSize
        ls_PathName = Space(255)
        ll_RequiredBufferSize = GetSystemDirectory(ls_PathName,255)
        IF ll_RequiredBufferSize=0 or ll_RequiredBufferSize>255 THEN
        //报错信息
        else
              ls_Command = ″Regsvr32 /s ″ + ″~″″ + ls_PathName + ″\Myocx.ocx″ + ″~″″
  Run (ls_Command)
            …
        end if
      Regsvr32后面的″/s″执行参数是为了隐藏注册成功消息框。(此方法由张涛提供)
    4.在PB应用程序中注册:
      函数声明:
      Function long DllRegisterServer() Library              ″ocxname.OCX″
      调用:
      LONG ll_RC
      ll_RC = DllRegisterServer()
    四、如何带参数执行SQL的系统储存过程?我想在script中执行系统存储过程Sp_DropUser删除MS SQL Server 7某用户。我是这样写的:execute Sp_DropUser(Sp_DropUser语法),编译提示Sp_DropUser为未定义的系统存储过程。
  答:代码如下:
        string ls_name
        ls_name = ′username′    //要删除的用户名
        //定义存储过程
        dECLARE dropUser_proc PROCEDURE FOR Sp_DropUser
     @name_in_db =:ls_name;
        SQLca.AutoCommit = TRUE
        EXECUTE dropUser_proc ; //执行
        SQLca.AutoCommit = false