一.需求: PB的功能非常强大,但有一些小的方面却不尽人意。比如,别的工具早就有的布局、容器功能,直到8.0还没有加入。这样致使用PB开发的界面过强的依赖于开发时的屏幕分辨率。虽然,也有一些解决方法,如与窗口一同以同样的倍数缩放组件等。但效果都不太理想。 本文试图提出一种一揽子的解决方法,希望能够彻底解决上述问题。 二.概念: 容器 :可以放入其他组件的组件。在PB中只有Tab Control,还长着耳朵,不太通用。 布局 :可以管理协调自身内部各个组件的功能,成为布局。 三.实现思路: 顾名思义,带有布局功能的容器,需要实现两个功能。其一:容器功能;其二:布局功能。 1.容器功能的实现: 本组件将采用Win32 API SetParent()来实现。详情如下,使用该方法可以很轻易的将任何一个dragobject组件对象变为容器。
申明方法:function long SetParent(Long hWndChild,long hWndNewParent) library "user32.dll"。
使用方法:SetParent(handle(子对象),handle(容器对象))。 2.布局功能的实现: 对于布局功能,本组件借鉴JAVA和C++ Builder 6.0里Panel组件的运作原理和术语,综合PB中dragobject的x,y,width,height等几个属性,实现了该功能。
因为容器内可以加入任何dragobject对象,包括容器对象本身,所以该组件可以嵌套实现多层布局功能。其中当前对象只管理自己的子对象,由父对象来管理自己和自己的兄弟。 3.布局时机: 窗口和对象constructor事件内实现布局方案和初始布局。
对象和窗口的resize事件里调整布局(该功能可内置于容器)。 四. 实现代码片断: 1. 容器功能实现(int drogobject.of_add_object(dragobject ofuo_dragobject)):
SetParent(handle(uostri_ext_property[ui_objectcount].childobject),handle(this)) 2. 布局功能实现(of_Align()): int li_i
//父容器resize子容器,在当前容器的resize事件里自动调用自己的of_align来align自身的子对象或子容器.
//初始化变量
ui_clienty=0
ui_clientx=0
ui_clientwidth=newwidth
ui_clientheight=newheight
//对齐方式'al_None','al_Top','al_Bottom','al_Left','al_Right','al_Client'
//加入对齐方式为'al_Top'的组件
for li_i=1 to upperbound(uostri_exe_property)
if Lower(uostri_exe_property[li_i].childobject_align)='al_top' then
//重置子对象的位置和大小
uostri_exe_property[li_i].childobject.x=0
uostri_exe_property[li_i].childobject.y=ui_clienty
uostri_exe_property[li_i].childobject.width=newwidth
//重置Client属性
ui_clienty=ui_clienty+uostri_exe_property[li_i].childobject.height
ui_clientheight=ui_clientheight - uostri_exe_property[li_i].childobject.height
end if
next
//加入对齐方式为'al_Bottom'的组件
for li_i=1 to upperbound(uostri_exe_property)
if Lower( uostri_exe_property[li_i].childobject_align)='al_bottom' then
//重置子对象的位置和大小
uostri_exe_property[li_i].childobject.x=0
uostri_exe_property[li_i].childobject.y=ui_clienty+(ui_clientheight - uostri_exe_property[li_i].childobject.height)
uostri_exe_property[li_i].childobject.width=newwidth
//重置Client属性
ui_clientheight=ui_clientheight - uostri_exe_property[li_i].childobject.height
end if
next
//加入对齐方式为'al_Left'的组件
for li_i=1 to upperbound(uostri_exe_property)
if Lower(uostri_exe_property[li_i].childobject_align)='al_left' then
//重置子对象的位置和大小
uostri_exe_property[li_i].childobject.x=ui_clientx
uostri_exe_property[li_i].childobject.y=ui_clienty
uostri_exe_property[li_i].childobject.height=ui_clientheight
//重置Client属性
ui_clientx=ui_clientx+uostri_exe_property[li_i].childobject.width
ui_clientwidth=ui_clientwidth - uostri_exe_property[li_i].childobject.width
end if
next
//加入对齐方式为'al_Right'的组件
for li_i=1 to upperbound(uostri_exe_property)
if Lower(uostri_exe_property[li_i].childobject_align)='al_right' then
//重置子对象的位置和大小
uostri_exe_property[li_i].childobject.x=ui_clientx+(ui_clientwidth - uostri_exe_property[li_i].childobject.width)
uostri_exe_property[li_i].childobject.y=ui_clienty
uostri_exe_property[li_i].childobject.height=ui_clientheight
//重置Client属性
ui_clientwidth=ui_clientwidth - uostri_exe_property[li_i].childobject.width
end if
next
//加入对齐方式为'al_Client'的组件
for li_i=1 to upperbound(uostri_exe_property)
if Lower(uostri_exe_property[li_i].childobject_align)='al_client' then
//重置子对象的位置和大小
uostri_exe_property[li_i].childobject.x=ui_clientx
uostri_exe_property[li_i].childobject.y=ui_clienty
uostri_exe_property[li_i].childobject.height=ui_clientheight
uostri_exe_property[li_i].childobject.width=ui_clientwidth
end if
next
return 0
五. 使用方法: 1. 窗口代码: 在窗口中放置第一个容器时,需要驱动该容器,所以必须在窗口的resize事件中写入如下代码:
this.setredraw(false)
uo_1.resize(newwidth,newheight)
this.setredraw(true) 2. 容器代码: 容器的constructor事件中反复调用如下方法:
int uo_container. of_add_object (dragobject childobject,string ofs_align)
方法说明:
返回值:整型;
传入参数:
childobject:dragobject类型,表容器中的子对象;
可为所有PB中的可拖拽窗口控件。
ofs_align:子对象对齐方式。
对齐方式:
'al_None':无对齐;
'al_Top':上对齐;
'al_Bottom':下

