实现自适应窗口的用户对象 pb autoResize
应论坛上一位朋友的要求,发段自适应窗口的代码。其实也是从网上下的,稍微做了些改进,尽管不太完善,不过凑合着用用还是可以的。其它朋友有好的代码,也欢迎共同分享!
用 import... 导入 pbl 中,在 n_face_autoresize 的构造事件中有使用说明:
$PBExportHeader$n_face_autoresize.sru
$PBExportComments$自动调整控件的大小和位置
forward
global type n_face_autoresize from n_nvo_base
end type
end forward
global type n_face_autoresize from n_nvo_base
end type
global n_face_autoresize n_face_autoresize
type variables
Protected :
boolean ib_stopped = true
Private:
int ii_oldw = 0, ii_oldh = 0
end variables
forward prototypes
public subroutine of_stop ()
public subroutine of_getminsize (window pwin, ref integer pi_minw, ref integer pi_minh)
public function integer of_start (integer ai_oldw, integer ai_oldh)
public subroutine of_resize (graphicobject pgo_target, unsignedlong pul_type, integer pi_neww, integer pi_newh)
private function integer of_resize (readonly graphicobject pgo, integer pi_oldw, integer pi_oldh, integer pi_neww, integer pi_newh)
end prototypes
public subroutine of_stop ();ib_stopped = true
end subroutine
public subroutine of_getminsize (window pwin, ref integer pi_minw, ref integer pi_minh);int i, li_maxx, li_maxy
object lobj
dragobject ldo
for i = 1 to upperbound(pwin.control[])
lobj = typeof(pwin.control[i])
if lobj = line! or lobj = oval! or lobj = rectangle! or lobj = roundrectangle! then continue
ldo = pwin.control[i]
if ldo.x > li_maxx then li_maxx = ldo.x
if ldo.y > li_maxy then li_maxy = ldo.y
next
pi_minw = li_maxx + ( pwin.width - pwin.workspacewidth() )
pi_minh = li_maxy + ( pwin.height - pwin.workspaceheight() )
end subroutine
public function integer of_start (integer ai_oldw, integer ai_oldh);if ii_oldw > 0 or ii_oldh > 0 then return -1// 避免重复修改
if ib_stopped and ai_oldw > 0 and ai_oldh > 0 then
ii_oldw = ai_oldw
ii_oldh = ai_oldh
ib_stopped = false
return 1
else
return -1
end if
end function
public subroutine of_resize (graphicobject pgo_target, unsignedlong pul_type, integer pi_neww, integer pi_newh);/*
pul_type:
0 - SIZE_RESTORED
1 - SIZE_MINIMIZED
2 - SIZE_MAXIMIZED
3 - SIZE_MAXSHOW
4 - SIZE_MAXHIDE
*/
boolean lb_sheet = false
int li_toolbarHeight = 0
window lw_obj, lw_parent, lw_sheet
if ib_stopped then return // 服务停止
if pul_type = 1 then return // 最小化
if ii_oldw <= 0 or ii_oldh <= 0 then return
if pi_neww <= 0 or pi_newh <= 0 then return
if TypeOf(pgo_target) = window! then
lw_obj = pgo_target
lw_parent = lw_obj.ParentWindow()
if IsValid(lw_parent) then
if lw_parent.windowtype = mdi! or lw_parent.windowtype = mdihelp! then
lw_sheet = lw_parent.GetFirstSheet()
do while IsValid(lw_sheet)
lw_sheet = lw_parent.GetNextSheet(lw_sheet)
if lw_sheet = lw_obj then
lb_sheet = true
exit
end if
loop
if lb_sheet then
if lw_sheet.menuname <> "" and lw_sheet.ToolbarVisible then
li_toolbarheight = -32// 有工具条
else
li_toolbarheight = 32
end if
else
li_toolbarheight = 32
end if
else
if lw_obj.windowtype = main! then
if lw_obj.toolbarvisible then li_toolbarHeight = 128
else
// 非 main 类型窗口不考虑工具条的影响,但需要微调
li_toolbarHeight = 32
end if
end if
else
if lw_obj.windowtype = main! then
if lw_obj.toolbarvisible then li_toolbarHeight = 128
else
// 需要微调
li_toolbarHeight = -128
end if
end if
end if
of_Resize(pgo_target, ii_oldw, ii_oldh, pi_neww, pi_newh - li_toolbarHeight)
ii_oldw = pi_neww
ii_oldh = pi_newh - li_toolbarHeight
end subroutine
private function integer of_resize (readonly graphicobject pgo, integer pi_oldw, integer pi_oldh, integer pi_neww, integer pi_newh);int li_x, li_y, li_w, li_h
int i, li_wDelta, li_hDelta,li_right, li_len
real lf_hRatio, lf_vRatio
string ls_tag, ls_htype, ls_vtype
//Integer li_ScreenH, li_ScreenW
//Environment le_Env
object lobj
window lwin
tab ltab
userobject luo
windowobject lwo, lwoa_controls[]
dragobject ldo
/*
//GetEnvironment(le_Env)
li_ScreenH = PixelsToUnits(le_Env.ScreenHeight, YPixelsToUnits!)/3
li_ScreenW = PixelsToUnits(le_Env.ScreenWidth, XPixelsToUnits!)/6.095
//li_ScreenH = PixelsToUnits(le_Env.ScreenHeight, YPixelsToUnits!)
//li_ScreenW = PixelsToUnits(le_Env.ScreenWidth, XPixelsToUnits!)
*/
if isnull(pgo) or isnull(pi_oldw) or isnull(pi_oldh) or isnull(pi_neww) or isnull(pi_newh) then return -1
if not isvalid(pgo) then return -1
if pi_neww <= 0 or pi_newh <= 0 then return -1
if (pi_neww = pi_oldw) and (pi_newh = pi_oldh) then return 1
lobj = typeof(pgo)
choose case lobj
case window!
lwin = pgo
lwoa_controls[] = lwin.control[]
case tab!
ltab = pgo
lwoa_controls[] = ltab.control[]
case userobject!
luo = pgo
lwoa_controls[] = luo.control[]
case else
return -1
end choose
/*
li_wDelta = pi_neww/1024*li_ScreenW - pi_oldw/1024*li_ScreenW
li_hDelta = pi_newh/768*li_ScreenH - pi_oldh/768*li_ScreenH
lf_hratio = (pi_neww/1024*li_ScreenW) / (pi_oldw/1024*li_ScreenW)
lf_vratio = (pi_newh/768*li_ScreenH) / (pi_oldh/768*li_ScreenH)
*/
li_wDelta = pi_neww - pi_oldw
li_hDelta = pi_newh - pi_oldh
if pi_oldw > 0 then lf_hratio = pi_neww / pi_oldw
if pi_oldh > 0 then lf_vratio = pi_newh / pi_oldh
for i=1 to upperbound(lwoa_controls[])
lwo = lwoa_controls[i]
if not IsValid(lwo) then continue// 调用 API FindWindowEx() 会导致 mdi 窗口的 mdi_1 控件变为无效(controls[] 中仍存在,但不能引用)
ls_tag = Lower(lwo.tag)
li_len = Len(ls_tag)
if li_len < 2 then continue
if li_len > 2 then
do while ls_tag <> ""
if gno_global.of_get_Token(ls_tag, " ") = "autoresize" then
ls_tag = gno_global.of_get_Token(ls_tag, " ")
exit
end if
loop
end if
if not IsNumber(ls_tag) then continue
ls_htype = Mid(ls_tag, 1, 1)
ls_vtype = Mid(ls_tag, 2, 1)
lobj = typeof(lwo)
if lobj = line! or lobj = oval! or lobj = rectangle! or lobj = roundrectangle! then continue
ldo = lwo
li_x = ldo.x
li_y = ldo.y
li_w = ldo.width
li_h = ldo.height
choose case ls_htype
case "0" // 不动
case "1" // 右对齐
li_x += li_wDelta
case "2" // 左右对齐
li_w += li_wDelta
case "3" // 按比例移动
li_x *= lf_hRatio
case "4" // 按比例缩放
li_x *= lf_hratio
li_w *= lf_hratio
case "5" // 左对齐并按比例缩放
li_w *= lf_hratio
case "6" // 右对齐并按比例缩放
li_right = pi_oldw - li_x - li_w
li_w *= lf_hratio
li_x = pi_neww - li_w - li_right
case "7"// 水平居中
li_x = (pi_neww - li_w) / 2
end choose
choose case ls_vtype
case "0"// 不动
case "1"// 下对齐
li_y += li_hDelta
case "2"// 上下对齐
li_h += li_hDelta
case "3"// 按比例移动
li_y *= lf_vRatio
case "4"// 按比例缩放
li_y *= lf_vratio
li_h *= lf_vratio
case "7"// 垂直居中
li_y = (pi_newh - li_h) / 2
end choose
ldo.Move(li_x, li_y)
if lobj = tab! or lobj = userobject! then
of_Resize(ldo, ldo.width, ldo.height, li_w, li_h)
end if
ldo.Resize(li_w, li_h)
next
return 1
end function
on n_face_autoresize.create
call super::create
end on
on n_face_autoresize.destroy
call super::destroy
end on
event constructor;/*
使用方法:
1、设置每个控件的Tag为两位数字。Tag没有设置(或不是两位数字)的控件将被忽略
第一位数字指示水平方向的调整方式:0 不动 1 右对齐 2 左右对齐 3 按比例移动 4 按比例缩放 5 左对齐并按比例缩放 6 右对齐并按比例缩放
第二位数字指示垂直方向的调整方式:0 不动 1 下对齐 2 上下对齐 3 按比例移动 4 按比例缩放 5 上对齐并按比例缩放 6 下对齐并按比例缩放
2、定义窗口实例变量:nvo_fave_autoresize inv_resize
3、窗口的open事件中写上:inv_resize.of_resize(this, 0, width, height)
4、窗口的resize事件中写上:inv_resize.of_resize(this, sizetype, width, height)
停止服务:inv_resize.of_stop()(默认)
恢复服务:inv_resize.of_start(原始宽度, 原始高度)
步骤3,4中,width,height替换为WorkSpaceWidth(),WorkSpaceheight()看起来更合理,
但是他们不按所想的那样工作。。。
窗口变得太小时控件位置会失真,所以需要限制窗口最小尺寸。
需要处理pbm_getminmaxinfo event.待做
不处理DrawObject:Line, Oval, Rectangle, & RoundRectangle。
因为不愿意把大部分代码用在几个从来不使用的控件上。
*/
end event