1、用DataWindow设计通用的编码帮助窗口 (深圳:独孤求败 2003-05-16) ---- 一、前言 ---- 用一组数字或键盘字符序列对具有某种相同属性的汉字词组或其它知识信息进行主动编码或被动自动编码,建立相应的编码库,以方便输入或助记,是大多数中文界面应用软件用以解决普通用户与应用软件交互瓶颈的基本方法,为此,设计者必须设计一个编码帮助处理程序,以满足编码信息处理的需要。一个较大的应用软件,该功能代码设计的质量,一方面关系到软件的开发效率,另一方面又关系到人机交互界面的友好程度。我们在许多股票分析软件中所看到的具有良好功能的股票代码帮助处理界面,它既能使用股票名称拼音首字母
2、定位股票名称,又能用股票数字代码查找,就是一个不错的代码帮助处理人机接口 ---- PowerBuilder(以下简称PB)作为C/S环境下的数据库前端开发工具,其面向对象、图形用户界面、可视化,以及方便移植等特点,成为众多程序员的最理想选择之一。笔者在用PB开发应用系统时,用DataWindow设计了一个通用的代码帮助窗口,很好地解决了上述问题。 ---- 二、实现方法及步骤 ---- 1. 用结构画笔新建一结构s_help,其元素列表如下: 序号 变量名 类型 注 释 1 dw_name DataStore 编码
3、和关键词关系对照表DataStore 2 help_nam String DataStore中关键词列名 3 help_code String DataStore中数字编码列名 4 help_pybm String DataStore中拼音编码列名 5 help_now_bm String DataStore当前编码筛选所使用的编码 6 w_title String 编码帮助窗口的title值 ---- 2. 定义全局变量gs_bm、gs_mc: ---- string gs_bm,gs_mc // 用来存放编码帮助处理程
4、序所返回的数字编码列和其对应的关键词列的值。 ---- 3. 定义实例变量istru_help、is_getfocus: ---- s_help istru_help // 入口参数结构变量 ---- string is_getfocus = 'mle_2' // 当前得到焦点的对象名,初始值为多行编辑器mle_2 ---- 4. 用窗口画笔新建一响应式窗口(Response)w_help,并在其内放置如下控件: 序号 控件名 控件类型 属性 值 1 w_help Window TitleBar True
5、 WindowType Response 2 dw_help DataWindow TabOrder 20 3 mle_1 MultiLineEdit Enabled False Text 编码帮助窗口 Width 105 Height 2012 TabOrder 0 4 mle_2 Multi
6、LineEdit Text 0 TabOrder 10 0 5 st_1 StaticText Text 快速定位 ---- 5. 定义用户事件: ---- ①在dw_help对象上点鼠标右键,进入数据窗口脚本编辑器,选菜单"Declare → User Event",定义"Event Name"为"ue_keydown","Event ID"为"pbm_dwnkey",点击OK退出; ---- ②同法为mle_2对象定义用户事件,"Event Nam
7、e"为"ue_keydown","Event ID"为"pbm_char",点出OK退出。 ---- 6. 为窗口w_help编写脚本: ---- ①Open事件脚本: istru_help = message.PowerObjectParm dw_help.dataobject = istru_help.dw_name.dataobject istru_help.dw_name.ShareData(dw_help) if dw_help.RowCount() < 1 then gs_bm = '' gs_mc = '' me
8、ssagebox("错误!","编码表没数据。请先录入!") close(this) return else this.title=istru_help.w_title end if ---- ②Close事件脚本: // 将过虑缓冲区中的数据传回主区 dw_help.SetFilter("") dw_help.Filter() ---- 7. 为数据窗口dw_help编写脚本: ---- ①getfous事件脚本: is_getfocus = "dw_help" ---- ②doubleclicked事件脚本: is_
9、getfocus = "dw_help" gs_bm = this.GetItemString(this.Getrow(),istru_help.help_code) gs_mc = this.GetItemString(this.Getrow(),istru_help.help_name) close(parent) ---- ③itemfocuschanged事件脚本: if row > 0 then this.selectrow(0,false) this.selectrow(row,true) end if ---- ④ue_ke
10、ydown用户事件脚本: integer li_key string ls_key,ls_filter boolean ls_flag = true if keydown(KeyTab!) then if is_getfocus = "dw_help" then mle_2.setfocus() end if return end if if keydown(KeyEnter!) or keydown(KeyEscape!) then if keydown(KeyEnter!) then gs_bm
11、 this.GetItemString(this.Getrow(),istru_help.help_code) gs_mc = this.GetItemString(this.Getrow(),istru_help.help_name) close(parent) return else gs_bm = '' gs_mc = '' close(parent) return end if else // 检测是否有退格键被按下 if keydown(keyback!) then ls_key=
12、left(mle_2.text,len(mle_2.text)-1) ls_flag = false if len(ls_key) < 1 then istru_help.help_now_bm = istru_help.help_code end if end if // 检测是否有数字键 0 ~ 9 被按下 if ls_flag then for li_key = 48 to 57 if keydown(li_key) then ls_key=mle_2.text+char(li
13、key) ls_flag = false exit end if next end if // 检测是否有数字键 A ~ Z 被按下 if ls_flag then for li_key = 65 to 90 if keydown(li_key) then ls_key=mle_2.text+char(li_key) ls_flag = false if len(mle_2.text) < 1 then istru_help.help_now_bm
14、 = istru_help.help_pybm end if exit end if next end if // 检测是否有数字键 a ~ z 被按下 if ls_flag then for li_key = 95 to 122 if keydown(li_key) then ls_key=mle_2.text+char(li_key) ls_flag = false if len(mle_2.text) < 1 then
15、 istru_help.help_now_bm = istru_help.help_pybm end if exit end if next end if if not ls_flag then if is_getfocus = "dw_help" then mle_2.text=ls_key end if this.SetRedraw(false) if len(trim(ls_key)) > 0 then /* 用户键入的字符串序列不为空时,筛选列
16、名不变,否者 以刚输入的第一个字符来判断,为数字则以数字编码列 名作为筛选列,否者以拼音编码列名为筛选列。 */ if istru_help.help_now_bm = istru_help.help_pybm then ls_filter = trim(istru_help.help_now_bm) +" like '%"+ Upper(trim(ls_key)) +"%'" else ls_filter = trim(istru_help.help_now_bm) +" like '"+tri
17、m(ls_key)+"%'" end if else ls_filter = "" end if this.SetFilter(ls_filter) this.Filter() this.SetRedraw(true) if this.rowcount() > 0 then this.selectrow(0,false) this.selectrow(1,true) end if end if end if ---- 8. 为多行编辑器mle_2对象编写脚本: --
18、 ①getfous事件脚本: is_getfocus = "mle_2" send(handle(this),256,35,long(0,0)) // 送End消息键使光标移到编辑区的尾部 ---- ②ue_keydown事件脚本: dw_help.triggerevent("ue_keydown") ---- 三、调用方法: ---- 在调用通用代码帮助窗口w_help之前,应先创建一DataStore对象, 该DataStore对象必须具有数字编码列、拼音编码列和被编码的关键词列,并从与之关联的表中检索出数据,之后,在任一须调用处编写以下代码(以油
19、品名称编码对照表为例,其上述三列分别为ypbm(油品编码)、pybm(拼音字头编码,液代汽编为"YHQ"),ypmc(油品名称,如"液化汽")): s_help ls_help // 局部结构变量 ls_help.dw_name = ids_ypbm // 事先定义并完成了数据检索的一 DataStore实例变量 ls_help.help_name = "ypmc" ls_help.help_code = "ypbm" ls_help.help_pybm = "yp
20、bm" ls_help.help_now_bm = "ypbm" // 默认为首先使用数字编码检索方案 ls_help.w_title = "油品名称编码对照表帮助窗口" OpenWithParm(w_help,ls_help) ---- 四、功能特点 ---- "通用编码帮助窗口"具有以下功能特点: ---- 1.能根据用户键入的字符序列对dw_help对象中的数据行进行筛选,如果键入的第一个字符为0~9间的数字字符,则根据数字编码字段筛选,否则以拼音编码字段筛选,从而实现 快速定位; ---- 2.用户可按Tab键实现从多行编辑器对象mle_2到DataW
21、indow对象dw_help间的焦点切换; ---- 3.无论当前焦点处在对象dw_help上,还是处在对象mle_2上,均使得用户的键入在对象mle_2的Text属性中同步表现,并相应地触发对对象dw_help的数据行进行筛选;任何时候用户都可按Escape键不选择任何数据行而退出并关闭帮助窗口; ---- 4.支持Backspace键按"先进后出"的方式依次删除键入的字符,并同步触发对象dw_help中的数据行的筛选; ---- 5.当当前焦点处在对象dw_help上时,可用上、下光标键让光带在数据行上滚动;按回车键或双击鼠标左键选中数据行退出并关闭帮助窗口。 ----
22、五、总结 ---- "通用编码帮助窗口"的设计,在充分利用PB独特的DataWindow对象特点的同时,巧妙地运用其过滤器函数Filter( ),使DataWindow对象dw_help中的主要缓冲区(Primary Buffer)与过滤缓冲区(Filter Buffer)中的数据行,能根据用户的键入,相应地进行调度,以达到满足用户快速检索的需要;一次性地从后台数据库中检索数据编码对照表,并把数据保存在一DataStore对象(本地内存)中,通过数据共享函数ShareData( )完成其数据行到编码帮助窗口对象dw_help的传递,大大节省了(网络后台)数据库检索的开销,极大地提高了窗口的响应速度。






