PowerBuilder编程俱乐部 柯建勋 1999年 第43期 13版   大家好!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后才有效。