---- PowerBuilder 是大家公认的、 最佳的数据库前端开发工具之一,但一直以来,PB在用户界面的处理上十分单调,最明显的例子是,所有的窗口控件都不支持透明色即transparent 。PowerBuilder 7以前的版本没有提供进度条,造成大多数程序员总是自己在程序中利用两个矩形控件(Rectangle)进行编程产生进度效果。但是这样一来,进度条中的进度百分比就没有了,如果再加上一个静态文本作为百分比显示,由于statictext控件没有透明色,进度条的百分比显示无法与进度条进行重叠,只得在进度条外的其它位置放置一statictext控件用以显示进度情况,这样即浪费了空间,又不美观。
---- 在网上也曾看到过解决的方法,主要是利用了数据窗口中控件可以透明处理的特征,但总感觉美中不足,数据窗口是一种重型控件,要占用大量的系统资源,能不能用其他更简单的方法解决上述问题呢?
---- 上述问题的关键在于文本的输出背景要透明,我们知道:Windows系统本身提供了大量的底层API功能函数供上层的应用程序调用,文本的输出该是最基本的吧,所以Windows一定能够解决文本背景透明输出的问题。仔细查找API帮助,果然找到相关的函数,于是问题迎刃而解。
---- 下面列出主要的声明和对象实现的主要程序段:
---- 新建一可视定制用户对象uo_progressbar,在其中放置两个矩形控件(Rectangle),分别命名为:r_back 和 r_front。定义实例变量如下:
ulong iul_ihDC //保存可视定制用户对象的DC句柄real ir_step //根据对象宽度计算出来的步进值integer ii_x, ii_y//根据对象宽度和高度计算出来的文本输出位置
声明Local external functions如下:
Function ulong GetDC (ulong hWnd) Library "USER32.DLL"
Function boolean TextOut (ulong hdcr, integer stx,integer sty, ref string lpString, long nCount)Library "GDI32.DLL" Alias for "TextOutA"
Function int SetBkMode (ulong hdcr, integer mode)Library "GDI32.DLL"
---- 在对象的constructor事件中输入以下代码:
integer li_width, li_height//根据对象变框计算宽高CHOOSE CASE this.BorderStyleCASE StyleLowered!,StyleRaised!li_width = this.width - PixelsToUnits(4, XPixelsToUnits!)li_height = this.height - PixelsToUnits(4, YPixelsToUnits!)CASE StyleBox!,StyleShadowBox!li_width = this.width - PixelsToUnits(2, XPixelsToUnits!)li_height = this.height - PixelsToUnits(2, XPixelsToUnits!)CASE Elseli_width = this.widthli_height = this.heightEND CHOOSE
r_back.width = li_widthr_front.height = li_heightr_front.width = 0r_back.height = li_height//计算百分比文本输出的位置使其在水平和垂直方向上居中ii_x = UnitsToPixels(li_width, XUnitsToPixels!)/2 - 16ii_y = ( UnitsToPixels(li_height, YUnitsToPixels!) - 16 )/2ir_step = li_width/100 //计算步进值iul_ihDC = GetDC( handle(this) )//获得对象DC句柄,用于API调用SetBkMode (iul_ihdc, 1 ) //设置文本输出背景色透明
return 0为对象写一个函数:of_setposition,//功能:根据参数改变进度显示//参数:integer ai_percent//返回:无string ls_msginteger li_xIf ai_percent <= 100 and ai_percent < 0 then SetRedraw(FALSE) li_x="ai_percent*ir_step" r_back.x="li_x" r_front.width="li_x" ls_msg="string(" ai_percent )+"%" SetRedraw(True) TextOut (iul_ihdc, ii_x, ii_y, ls_msg, len( ls_msg ) ) End If
---- 当然你还可以编写函数改变进度条中的前景色背景色和文本颜色,这里不再赘述。