type t_children_sizer = class() {** @explan(说明) 子控件布局器 %% @param(layout)(bool) 是否布局 %% @param(controlsperline)(integer) 每行控件数 %% @param(horizontalspacing)(integer) 水平间距 %% @param(verticalspacing)(integer) 垂直间距 %% @param(leftrightspacing)(integer) 左右间距 %% @param(topbottomspacing)(integer) 上下间距 %% **} //TControlChildrenLayout //static const cclNone =0; //static const cclLeftToRightThenTopToBottom = 1; // if BiDiMode <> bdLeftToRight then it becomes RightToLeft //static const cclTopToBottomThenLeftToRight = 2; function create(aowner); begin fowner := aowner; fcontrolsperline := 1; flayout := 0; fhorizontalspacing := 10; fverticalspacing := 10; ftopbottomspacing := 5; fleftrightspacing := 20; fautosizing := 0; end function AdjustSize(); //调整 begin if flayout=0 then return ; if fautosizing then return ; fautosizing := true; if not fowner then return ; faownercls := fowner.ClientRect; dolayoutctls(w,h); if fowner.autosize then begin bds := fowner.BoundsRect; cls := faownercls; dw := (bds[2]-bds[0])-(cls[2]-cls[0]); dh := (bds[3]-bds[1])-(cls[3]-cls[1]); bds[2] := bds[0]+w+dw; bds[3] := bds[1]+h+dh; fowner.BoundsRect := bds; end fautosizing := false; end function getsizerinfo(); begin r := array(); r["layout"] := flayout; r["controlsperline"] := fcontrolsperline; r["horizontalspacing"] := fhorizontalspacing; r["verticalspacing"] := fverticalspacing; r["topbottomspacing"] := ftopbottomspacing; r["leftrightspacing"] := fleftrightspacing; return r; end function setsizerinfo(v); begin if not(ifarray(v) and v) then return ; flg := false; for i,vi in v do begin case i of "layout" : begin if vi<>flayout and(vi=0 or vi=1 or vi=2) then begin flayout := vi; if vi then flg := true; end end "controlsperline": begin if vi<>fcontrolsperline and vi>0 then begin fcontrolsperline := vi; flg := true; end end "horizontalspacing": begin if vi<>fhorizontalspacing and vi>0 then begin fhorizontalspacing := vi; flg := true; end end "verticalspacing": begin if vi<>fverticalspacing and vi>0 then begin fverticalspacing := vi; flg := true; end end "topbottomspacing": begin if vi<>ftopbottomspacing and vi>0 then begin ftopbottomspacing := vi; flg := true; end end "leftrightspacing": begin if vi<>fleftrightspacing and vi>0 then begin fleftrightspacing := vi; flg := true; end end end; end if flg then begin AdjustSize(); end end property layout read flayout write setlayout; property controlsperline read fcontrolsperline write setcontrolsperline; property horizontalspacing read fhorizontalspacing write sethorizontalspacing; property verticalspacing read fverticalspacing write setverticalspacing; property leftrightspacing read fleftrightspacing write setleftrightspacing; property topbottomspacing read ftopbottomspacing write settopbottomspacing; property autosizing read fautosizing; private function getwndclass(); begin return class(TWinControl); end function dolayoutctls(w,h); begin if not fowner then return ; ctls := fowner.Controls; r := array(); ridx := 0; cidx := 0; ccount := 0; for i :=0 to fowner.ControlCount-1 do begin ctl := ctls[i]; if not ctl then continue; if not ctl.Visible then continue; if (ctl is getwndclass()) and ctl.WsPopUp then continue; if cidx>=fcontrolsperline then begin ccount := fcontrolsperline; cidx := 0; ridx++; end ctl.GetPreferredSize(wi,hi); if flayout=1 then r[ridx,cidx] := array(ctl,0,0,wi,hi); else r[cidx,ridx] := array(ctl,0,0,wi,hi); cidx++; end ccount := mcols(r); ridx := mrows(r); //ccount := max(ccount,cidx); wsz := zeros(ccount); //hsz := zeros(ridx+1); hsz := zeros(ridx); for i := 0 to length(r)-1 do begin for j := 0 to length(r[i])-1 do //for j := 0 to ccount-1 do begin hsz[i] := max(hsz[i],r[i,j,4]); wsz[j] := max(wsz[j],r[i,j,3]); end end py := ftopbottomspacing+faownercls[1]; lr := length(r)-1; for i := 0 to lr do begin px := fleftrightspacing+faownercls[0]; for j := 0 to ccount-1 do begin vij := r[i,j]; if not vij then continue; vij[1] := px; vij[2] := py; vij[3] := px+wsz[j]; vij[4] := py+hsz[i]; r[i,j] := vij; px+=wsz[j]; if jfleftrightspacing then begin fleftrightspacing := nv; dolayout(); end end function settopbottomspacing(v); begin nv := integer(v); if nv<>ftopbottomspacing then begin ftopbottomspacing := nv; dolayout(); end end function sethorizontalspacing(v); begin nv := integer(v); if nv<>fhorizontalspacing then begin fhorizontalspacing := nv; dolayout(); end end function setverticalspacing(v); begin nv := integer(v); if nv<>fverticalspacing then begin fverticalspacing := nv; dolayout(); end end function setlayout(v); begin if v<>flayout and v in array(0,1,2) then begin flayout := v; if v>0 then begin dolayout(); end end end function setcontrolsperline(v); begin nv := integer(v); if nv>0 and fcontrolsperline<>nv then begin fcontrolsperline := nv; dolayout(); end end function dolayout(); begin AdjustSize(); end private [weakref] fowner; fautosizing; flayout; fcontrolsperline; fhorizontalspacing; fverticalspacing; fleftrightspacing; ftopbottomspacing; faownercls; end