hur.cn - 华软网

 热门搜索

  • 授权方式: 免费源码
  • 支付金币: 0个
  • 金币充值: 点击查看
  • 下载方法: 点击查看
  • 源码大小: 51 KB
  • 评分等级: ★★★
  • 源码类别: 国内视频
  • 运行环境: WinXP/NT/Vista/Win7
  • 整理录入: 昕晨
  • 更新时间: 2009/12/3 14:36:06

源码介绍    


PowerBuilder编程俱乐部CHM

 

PowerBuilder编程俱乐部(一)
 

PB编程俱乐部     柯建勋


  大家好!PowerBuilder编程俱乐部今天正式与大家见面了,欢迎各位PB爱好者参与进来!为了方便与大家的交流,俱乐部特开放两个Email信箱:kjx@263.netpb7@990.net,大家如果有PB方面的问题,可以发Email到这两个信箱。当然,更欢迎各位到我的主页http://kjx.126.com或http://pb70.yeah.net的BBS讨论区提交问题或解答问题,以便大家都能从中学到知识。互相学习、共同进步是PB编程俱乐部的宗旨,热切希望爱好PB编程的读者加入到PB编程俱乐部来!
  一、问:一个MIS系统采用C/S的开发模式,前台开发工具用PB6.5,后台数据库Oracle7.3。我通过OBOC却连不上数据库,请问应该如何配置?
  答:PB提供了与当前流行的大型数据库OracleInformixSybase等的专用接口,连接时无需通过ODBC。配置步骤具体如下:
  1. 首先要通过SQL*Net配置数据库别名。
  启动SQL*Net Easy Configuration后,选择“添加数据库别名” ( Add Database Alias),输入数据库别名, 如hello。选择协议TCP/IP,输入TCP/IP主机名(TCP/IP Host Name),可为主机名或IP地址输入数据库名(Database Instance)如ora7。单击“确定”按钮,生成数据库别名(hello)后,按“取消”退出。连接数据库,测试SQL*Net是否连通。运行SQL*PLUS,用自己的用户名,如kukoc进入,在用户名处输入kukoc/kukoc@hello 。若进入远程数据库,则SQL*Net 配置成功。
  2.然后,在PB6.5中配置 DB Profile。
  选择073 Oracle7.3,按Button New,输入Profile Name,如hello。
  输入Server:@hello(此处一定要为@+开始配置的数据库别名)
  输入Login ID:kukoc
  输入Password:kukoc
  单击确定按钮结束。
  我们也可以通过配置文件(.ini)实现数据库连接,如hello.ini文件中数据库配置如下:
  [Database]
  DBMS=O73 ORACLE 7.3
  Database=
  UserId=
  DatabasePassword=
  LogPassword=kukoc
  ServerName=@hello
  LogId=kukoc
  Lock=
  DbParm=
  Prompt=0
 
  二、问:我在编写数据窗口录入程序的时候,若用户录入违反了约束(如关键字重复、非空项没输入等),程序老报一大堆英文出错信息,用户也看不明白。我怎样才能屏蔽它,并显示中文的错误信息?
  答:可以自己编写一个错误信息函数,如f_dwerror_message(),参数为错误信息代码(Long型),返回值为1。函数中根据传入的错误代码给出相应的中文错误信息。在数据窗口的dberror事件中调用它:
  return f_dwerror_message (sqldbcode)
  而且,我们还可以将此数据窗口作成用户对象,要用到的地方继承即可。
 
  三、问:在PB中如何打开一个文件(如.txt,.doc),就像在资源管理器中双击打开文件一样?
  答:可以通过API函数来实现。
  在应用程序的Global External Functions中定义:
  Function long ShellExecuteA (ulong hwnd, string lpOperation, string lpFile, & string
lpParameters, string lpDirectory, long nShowCmd) library “shell32.dll”   调用如下:
  String ls_null
  SetNull (ls_null)
  ShellExecuteA(Handle(Parent), ls_null, “c:\doc\hello.txt”, ls_null, ls_null, 1)
  四、问:PB中数据窗口输入栏目(域)间的切换通过按键盘最左边的Tab 键来实现,既不方便又影响录入速度。如何能用Enter键替代Tab 键切换栏目,实现焦点的转移?
  答:由于按Enter键是Windows直接支持的消息,故我们可以使用用户事件来解决此问题。 在用户事件中,PowerBuilder提供的一条pbm_事件对应Windows的一条或几条消息。我们在数据窗的用户事件中选择pbm_dwnProcessEnter并命名为ue_Enterkeydown。当我们按下Enter键时,将触发此事件。
  提供两种方法(推荐用第二种):
  1.利用数据窗口的SetColumn函数。
  在所定义的ue_Enterkeydown事件下写代码
  long ll_column_count
  long ll_column
  ll_column_count =long(this.Describe(“DataWindow.Column.Count”))
  ll_column = this.GetColumn()
  if ll_column = ll_column_count then
  return
  else
  this.SetColumn(ll_column + 1)
  end if
  用上面脚本,须注意几点:
  (1) 按Enter键,焦点的切换是按所选列的顺序,而不是按设置的Taborder的顺序。
  (2) 若某列的visible属性为false 或 TabOrder = 0, 则以上方法不起作用。
  若不合以上要求,即所选列的顺序与要录入域顺序不一致,或某些列的visible属性为false或 其TabOrder = 0,此时不能用上述代码,但也可用类似方法实现,只是稍繁琐一点,举例如下:
  long ll_column
  string ls_column_name
  ll_column = this.getcolumn()
  ls_column_name = this.Describe(“#”+string(ll_column)+“.Name”)
  choose case ls_column_name //列名
  case ‘no'
  this.SetColumn(‘name')
  case ‘name'
  this.SetColumn(‘age')   case ‘age'
  …
  end choose
  2.把消息传递给Tab键,同时忽略Enter键的处理,这种方法最为方便简洁。在ue_Enterkeydown事件中
  编写脚本如下:
  Send(Handle(this),256,9,Long(0,0))
  Return 1
 
  五、问:Datawindow中要匹配的条件是变化的,如输入一个名字(名字放在变量ls_name中),用dw_name.setfilter(“name = ” + ls_name )不起作用。如何用setfilter将这条记录找出来?
   答:因ls_name 是string型的,filter语句应该这样写:
  dw_name.SetFilter(“name = ‘” + ls_name + “'”)
  dw_name.Filter( )
  当ls_name = “张三”时,脚本实际为:
  dw_name.SetFilter(“name = ‘张三’”)
  dw_name.Filter( )
 
  六、问:怎样得到一个应用程序如Outlook的路径?
  答:可用RegistryGet()函数从系统注册表中获得。具体用法如下:
  li_return = RegistryGet (“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows &
  \CurrentVersion\App Paths\MSIMN.EXE”,“Path" , ls_outlook_path )
  执行此脚本后,Outlook的路径将保存在string型变量ls_outlook_path中。
 


一、问:我想做一个数据窗口的组合条件查询,要得到数据窗口中的所有列名及其text的文字说明,请问怎样才能取得?
  答:Describe()函数可以得到数据窗口的多项属性值,用它实现如下:
  long ll_column_count
  long ll_i
  string ls_column[] //列名
  string ls_column_text[] //text的名字
  //得到数据窗口的总列数
  ll_column_count = long(dw_1.Describe(″DataWindow.Column.Count″))
  //循环依次读取
  for ll_i = 1 to ll_column_count
  ls_column[ll_i] = dw_1.Describe(″#″+string(ll_i)+″.Name″)
  ls_column_text[ll_i] = dw_1.Describe(ls_column[ll_i] + ″_t.text″)
  next
  说明:数组ls_column[]保存当前数据窗中所有列名
  数组ls_column_text[]保存当前数据窗中列对应的text的文字说明。
  注:数据窗口dw_1的对象(DataObject)中text命名须用默认值,即列名+ _t的形式,如列名为“name”,则其对应text应取名为“name_t”,否则返回值不正确。
 
  二、问:在应用程序运行时,数据库Sysbase SQL Anywhere 5.0启动后在系统状态条上会有图标,有时用户会不小心将其关闭,造成系统出错。请问如何隐藏Sysbase SQL Anywhere 5.0在系统状态条上的的图标?
  答:可以通过更改系统注册表来实现。以Powersoft Demo DB V6 为例:
  运行注册程序regedit,找到注册表中HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\Powersoft Demo DB V6中名为Start的项目,如其原值为“C:\Program Files\Sybase\SQL Anywhere 5.0\Win32\dbeng50.exe”,在其后加上参数 -Q,改为“C:\Program Files\Sybase\SQL Anywhere 5.0\Win32\dbeng50.exe -Q”即可。
  对于自己创建的其它Sysbase SQL Anywhere 5.0数据库可用同样方法实现。
 
  三、问:一般用鼠标单击窗口右上角的“X”时,窗口立即关闭,但有的程序在退出时会弹出一个确认窗口供用户确认,这是如何实现的?
  答:可以利用窗口的CloseQuery事件在用户关闭窗口时进行确认。在CloseQuery事件中加入脚本:
  long ll_return
  ll_return = MessageBox(″提示信息″,″确认退出吗?″, Question! , YesNo! , 1 )
  if ll_return = 2 then
  Return 1 //不关闭窗口
  else
  Return 0 //关闭窗口
  end if
 
  四、问:怎样得到程序运行时的路径?
  答:用API函数GetModuleFileNameA()可实现。
  在global external functions声明:
  Function uLong GetModuleFileNameA(long hinstModule, Ref String lpszPath, uLong cchPath) Library ″kernel32.dll″
  使用:
  string ls_AppPath
  int li_ret
  ls_AppPath = Space (128)
  li_ret = GetModuleFileNameA (Handle (GetApplication ()), ls_apppath, 128)
  说明:要编译成可执行文件.exe才可用,否则得到的是Powerbuilder的pb60.exe或PB050.exe的路径。程序路径保存在变量ls_AppPath中。
 
  五、问:我编写的脚本忘了在哪个窗口了,怎么办?总不能让我把几十个窗口逐个打开,每个事件中来查找吧。
  答:同时选中这几十个窗口,点Entry菜单,再点击Serach菜单项,输入你要查找的脚本内容,点确定即可。系统将列出所有符合要求的窗口、控件、事件及脚本所在的行数。
  查找同样适用于函数、菜单、用户对象等。
 
  六、问:请问怎样限制应用程序只运行一次?
  答:提供两种实现方法(用于32位操作系统):
  1.首先在global external functions声明外部函数如下:
  FUNCTION long FindWindowA( ulong Winhandle, string wintitle ) Library ″user32″
  然后在application的 Open 事件中加入如下代码:
  ulong l_handle, lu_class
  string ls_name
  ls_name = ″我的系统″ // 此处ls_name为系统主窗口的标题Title
  l_handle = FindWindowA(lu_class, ls_name)
  if l_handle > 0 then
  MessageBox(″提示信息″, ″应用程序″ + This.AppName + ″已经运行,不能多次启动!″)
  Halt Close
  else
  open(w_main) // 此处为系统主窗口
  end if
  这种方法是PowerBuilder联机帮助中的一个例子,是以系统主窗口的标题Title作为判别依据,若有其它与此Title同名应用程序在运行,再想启动此程序也会报应用程序已经运行。你可以将Title设为“计算器”,然后启动Windows附件中计算器程序,再运行你的PB应用程序试试。
  2.声明外部函数:
  function ulong CreateMutexA (ulong lpMutexAttributes, int bInitialOwner, ref string lpName) library ″kernel32.dll″
  function ulong GetLastError () library ″kernel32.dll″
  然后在application的 Open 事件中加入如下代码:
  ulong ll_mutex, ll_err
  string ls_mutex_name
  if handle (GetApplication (), false) <> 0 then
  ls_mutex_name = this.AppName + char (0)
  ll_mutex = CreateMutexA (0, 0, ls_mutex_name)
  ll_err = GetLastError ()
  if ll_err = 183 then
  // 程序已经运行
  MessageBox (″提示信息″, ″程序已经运行了!″)
  Halt close
  else
  // 程序未运行
  open(w_main)
  end if
  else //开发模式
  open(w_main)
  end if
  这种方法必须在应用程序编译成可执行文件.exe后才有效。
 


一、问:下拉列表(DropDownListBox)中,当选中某一项后,我怎样才能返回当前选中项的索引号?(相当于VB中ComboBox的Index属性)
答:PowerBuilder中下拉列表控件没有Index属性,不能直接引用,得用其它方法实现。现给出两种方法:
1、设一long型实例变量il_index,在下拉列表的SelectionChanged事件中加入:
    il_index = index
以后引用il_index即可
2、假设下拉列表名为ddlb_1,则索引号:
        li_index = ddlb_1.FindItem(ddlb_1.Text,1)
二、我用的数据库是 Sybase SQL Anywhere 5.0 ,数据库文件在本机能用,拷贝到别的机器却连接不上,是否还需其它配置?
答:假设数据库文件为hello.db,将hello.db与hello.log拷贝过去,再配置ODBC数据源。如果还连不上数据库,则须重新连接事务注册文件hello.log,方法如下:
1、运行MS_DOS模式
2、进入Sybase SQL Anywhere5.0\win32目录,如
    C:> cd C:\Program Files\Sybase\SQL Anywhere 5.0\Win32
3、运行命令(假设数据库文件拷贝到D盘根目录下):
    dblog -t d:\hello.log d:\hello.db
三、问: 我在安装好PB之后,以示例Powersoft Demo DB V6连接,打开DATABASE画板,出现Select Table对话框,选择Cancel。 打开FILE菜单中只有:Close、Connect、Configure ODBC、PowerPanel、Print Setup、Exit等菜单项。却没有像书中所讲的Create Database选项,请问这是为什么?
答:这个问题的关键所在是在PowerBuilder所能找到的路径中,必须有dbtl50t.dll这个文件,PB才会出建数据库的选项。 这个文件包含在完整的SQL Anywhere之中,PB安装时只安装SQL Anywhere最基本的引擎部分,不安装这个文件。
解决方法:在PB光盘上有完整的SQL Anywhere 5.0,安装它即可。或者你也可以从其他机上将dbtl50t.dll copy到C:\Windows\System或\SQL Anywhere 5.0\Win32中也可以。
(本题由网易PB版主ilike提供解答)
四、数据窗口中某列的编辑风格设为下拉数据窗口(DropDownDataWindow),有什么办法能得到此列的显示值?用GetItemNumber()函数只能得到实际值。
答:数据窗口中有一个内部函数LookupDisplay()可实现此功能,若列名为"currency",取第1行的值如下:
    dw_1.Describe ( "Evaluate('LookupDisplay(currency)',1)" )
这种方法同样适用于编辑风格为下拉列表(DropDownListBox)、收音机按钮(RadioButtons)等的列。
五、在数据窗口录入数据时,有的域要输英文、有的域要输中文,每次要手工切换,很麻烦,能不能在程序中自动控制切换中英文输入法?
答:可以用API函数实现:
声明API函数:
    function boolean ImmSimulateHotKey (ULong hWnd, ULong dwHotKeyID) library "IMM32.dll"
    function ulong GetKeyboardLayout(ulong dwLayout) LIBRARY "user32.dll"
    function boolean ImmIsIME(uLong hklKeyboardLayout) library "IMM32.DLL"
定义变量:
    constant int IME_THotKey_IME_NonIME_Toggle=112
    ulong hklCurrent
    ulong hnd
切换到英文输入法:
    hklCurrent=GetKeyboardLayout(0)
    if ImmIsIME(hklCurrent) then
        hnd=Handle(parent)
        ImmSimulateHotKey(hnd,IME_THotKey_IME_NonIME_Toggle)
    end if
切换到中文输入法:
    hklCurrent=GetKeyboardLayout(0)
    if not ImmIsIME(hklCurrent) then
        hnd=Handle(parent)
        ImmSimulateHotKey(hnd,IME_THotKey_IME_NonIME_Toggle)
    end if
可根据需要,触发两段不同的脚本以达到动态切换中英文输入法的目的。
六、问:在数据窗口对象画板中可以设定列的编辑风格为下拉数据窗口(DropDownDataWindow),请问在程序中可以动态实现这项功能吗?
答:可以的,假设所设定列为部门号"department_id",相关连的子数据窗口为"d_dddw_dep",显示列为部门名称"dept_name",数据列为部门号"dept_id",实现方法如下:
    dw_1.Modify("department_id.DDDW.Name=d_dddw_dep ")
    dw_1.Modify("department_id.DDDW.DisplayColumn='dept_name' ")
    dw_1.Modify("department_id.DDDW.DataColumn='dept_id' ")
或:
    dw_1.object.department_id.dddw.name = "d_dddw_dep"   
    dw_1.object.department_id.DDDW.DisplayColumn = "dept_name"         dw_1.object.department_id.DDDW.DataColumn = "dept_id"  
注:PowerBuilder有一个小工具DWSyntax(程序名为:dwsyn60.exe),提供了获得及修改数据窗口、列等的各项属性值的语法,对编程非常有帮助。上述脚本在DWSyntax中都能找到。

 



上一源码:PowerBuilder编程技巧CHM
下一源码:PowerBuilder常见问题集CHM

下载地址    

  • PowerBuilder编程俱乐部CHM

下载说明

  • 为防止盗链,本站资源部分有解压密码,解压密码点击查看
  • 如果您发现该资源不能下载,请通知管理员;
  • 为了保证您快速的下载,推荐使用迅雷或网际快车等专业工具下载;
  • 为确保所下资源能正常使用,请使用WinRAR v3.80或以上版本解压本站资源;
  • 本站所收集的下载资源均来源于网络,如果有侵犯您的版权,请来信告知,我们会马上处理;
  • 本站所提供的资源仅供学习和研究,请勿用于商业用途,请在下载后24小时内删除;
  • 本站不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害!