PowerBuilder编程俱乐部
大家好!PowerBuilder编程俱乐部自第一期推出以来,受到广大PB爱好者的热烈欢迎,每天都有大量的读者来信,在这里版主真诚感谢朋友们的关心和支持,PB编程俱乐部将一如既往地为大家服务。各位可到俱乐部主页http://kjx.126.com或http://pb70.yeah.net的BBS讨论区去提交问题或解答问题,如你平时编程有何经验与心得,也可拿出来与大家共享,俱乐部的原信箱同时开放。你的支持和参与就是我们前进的动力!
不少网友来信询问有哪些学习PowerBuilder编程的好站点,今后PB编程俱乐部将不定期的向大家推荐一些国内优秀的PowerBuilder网站。今天向大家介绍的是“PB能量建造者”http://pb7.126.com,站长:潘亚、鹿寒。一个非常出色的PB个人主页,新建不久但内容详实,而且更新很快。有PB专题、技巧、文摘、下载和讨论区等栏目,收录优秀的PB专题文章、讲座、教材, 有包括Datawidow、API调用、数据库等在内的大量编程技巧,并且提供文档、数据库驱动和PB例程下载。该站还定期举办PB网友网上聚会,网友见面认识,交流心得,疑难问题嘉宾现场交流解答,是PB爱好者学习、交流的好地方。
一、问:我想做一个数据窗口的组合条件查询,要得到数据窗口中的所有列名及其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后才有效。