unit utslvcldpropertytypes; interface {** @explan(说明) 设计器属性编辑库,继承该库,定义属性编辑类 %% **} uses utslvclauxiliary,utslvclbase,utslvclgdi,uvcpropertytypespersistence,tslvcl,utslvcldcomponents; function registereditpropertytodesigner(cls); type TGCellRender = class(TSLUIBASE) //属性编辑器单元格对象基类 {** @explan(说明) gridcell渲染器 %% **} private FActivate; public function CreateEditer(AOwner); begin return createobject(self(true).classinfo(1),AOwner); end function Create(AOwner);override; begin {** @explan(说明) 构造编辑器 %% **} class(TSLuibase).create(); end function CelldbClick(grid,e,d);virtual; //双击 begin end function CellClick(grid,e,d);virtual; //点击 begin {** @explan(说明) 格子点击 %% **} FActivate := true; end function CellDraw(grid,e,d);virtual; //绘制 begin {** @explan(说明) 绘制格子 %% **} end function CellLeave(grid);virtual; //离开 begin {** @explan(说明) 离开编辑格子 %% **} FActivate := false; end; property Activated read FActivate; end type TGridPropertyRender = class(TGCellRender) //属性编辑添加owner function Create(AOwner); begin inherited; Owner := AOwner; end Owner ; end type TGridCellEditWithButton = class(TGridPropertyRender) //带按钮的单元格编辑 {** @explan(说明) 带有按钮的格子% **} private FRbuttonWidth; //按钮宽度 FUpRect; FDownRect; protected function ptinrect(pt,rec);//区域中判断 begin return (pt[0]>rec[0] and pt[0]<=rec[2]) and (pt[1]>rec[1] and pt[1]<=rec[3]); end function splitrect(r,rs);virtual;//拆分区域 begin rs := array(); src := r; wd := FRbuttonWidth?FRbuttonWidth:20; src[0] := src[2]-wd; src[1]+=3; src[3]-=3; rs[0] := src; src := r; src[2]-=wd; rs[1] := src; end public function GetPopRectByHeight(h); //获得弹出区域 begin {** @explan(说明)根据格子获得弹出的区域 %% **} if not(h>10) then h:= 100; dn := GetPopRect(); if dn[3]-dn[1]=h then begin dn[1]:= dn[3]-h; end else begin dn := dna; end end return dn; end function GetPopRect(f); //获得弹出区域 begin {** @explan(说明) 获得弹出区域%% @param(f)(bool) ture获得上方弹出区域,false 获得下方 %% **} if f then return FUpRect; return FDownRect; end function DrawButton(dc,src,d);//绘制按钮 begin {** @explan(说明) 绘制按钮%% **} dc.Draw("framecontrol",array(src[0:1],src[2:3]),DFC_SCROLL,DFCS_SCROLLDOWN); end Function Create(AOwner);override; begin inherited; ButtonWidth := 20; end function CellDraw(grid,e,d);override; begin rec := e.SubItemRect; dc := e.canvas; splitrect(rec,rs); DrawButton(dc,rs[0],d); CellDrawLabel(dc,rs[1],d); end function CellDrawLabel(dc,rect,d);override;//绘制其他部分 begin {** @explan(说明) 绘制标签 %% **} if ifarray(d) then begin //dc.drawtext(self(true).EditType(),rect); end end function CellClick(grid,e,d);override;//点击 begin {** @explan(说明) 格子点击 %% **} inherited; i := e.iitem; j := e.isubitem; pt := e.ptaction; rec := grid.getSubItemRect(i,j); splitrect(rec,rs); btr := rs[0]; lr := rs[1]; x1y1 := grid.ClientToScreen(rec[0],rec[1]); x2y2 := grid.ClientToScreen(rec[2],rec[3]); src := _wapi.GetScreenRect(); FUpRect := array(x1y1[0],src[1],x2y2[0],x1y1[1]); FDownRect := array(x1y1[0],x2y2[1],x2y2[0],src[3]); if ptinrect(pt,btr) then begin ButtonClick(grid,e,d); end else if ptinrect(pt,lr) then begin LabelClick(grid,e,d); end end function CelldbClick(grid,e,d);override;//双击处理 begin {** @explan(说明) 格子点击 %% **} inherited; i := e.iitem; j := e.isubitem; pt := e.ptaction; rec := grid.getSubItemRect(i,j); splitrect(rec,rs); btr := rs[0]; lr := rs[1]; x1y1 := grid.ClientToScreen(rec[0],rec[1]); x2y2 := grid.ClientToScreen(rec[2],rec[3]); src := _wapi.GetScreenRect(); FUpRect := array(x1y1[0],src[1],x2y2[0],x1y1[1]); FDownRect := array(x1y1[0],x2y2[1],x2y2[0],src[3]); if ptinrect(pt,lr) then begin //LabelClick(grid,e,d); end end function ButtonClick(grid,e,d);virtual;//按钮处点击 begin {** @explan(说明) 按钮被点击 %% **} end function LabelClick(grid,e,d);virtual;//非按钮处点击 begin {** @explan(说明)标签被点击 %% **} end function CellLeave(grid);override; //离开 begin {** @explan(说明) 离开编辑格子 %% **} inherited; end; property ButtonWidth read FRbuttonWidth write FRbuttonWidth; {** @param(ButtonWidth)(integer) 按钮宽度 %% **} end type TGCellBoolRender=class(TGCellRender) //bool类型 class Function EditType();override; begin return "bool"; end function CellClick(o,e,d);override; begin if not ifarray(d)then return; i := e.iitem; j := e.isubitem; pt := e.ptaction; indexs := 1; o.getdata(i,j,cp,indexs); dv := d["value"]; o.setvalue(indexs union array("value"),not dv); rec := o.GetSubItemRect(i,j); o.InvalidateRect(rec,true); end function CellDraw(o,e,d);override; begin dc := e.canvas; DrawBoolButton(dc,e.SubItemRect,d["value"]); end function DrawBoolButton(dc,srca,v); begin FRbuttonWidth := 20; src := srca; src[0]:= src[2]-FRbuttonWidth-10; src[2]-= 10; src[1]+= 3; src[3]-= 3; //_wapi.DrawFrameControl(dc.Handle,src,DFC_BUTTON,v?DFCS_CHECKED:DFCS_BUTTONCHECK); dc.Draw("framecontrol",array(src[0:1],src[2:3]),DFC_BUTTON,v?DFCS_CHECKED:DFCS_BUTTONCHECK); end end type TGridCellEditList = class(TGridCellEditWithButton) protected Fi; fj; FGrid; private FDataList; function GetDataList();virtual; begin return FDataList; end function SetDataList(v);virtual; begin FDataList:=v; end public function create(AOwner);override; begin inherited; end function GetItemValue(v);virtual; begin return v; end function CellDrawLabel(dc,rect,d);override; begin v := d["value"]; dc.DrawText(v,rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end function nameFilter();virtual; begin return nil; end function ButtonClick(grid,e,d);override; begin {** @explan(说明) 按钮被点击 %% **} FGrid := grid; i := e.iitem; FI := I; j := e.isubitem; FJ := J; dlist := DataList; if dlist then begin try dlist.filter := nameFilter(); except end ; dn := GetPopRectByHeight(250); dlist.width := dn[2]-dn[0]; dlist.height := 250; dlist.left := dn[0]; dlist.top := dn[1]; dlist.OnClickSelected := thisfunction(OnvSelected); dlist.SetSelectedByValue(d["value"]); //dlist.visible := true; dlist.show(); end end function OnvSelected(o); begin sv:=GetItemValue(o.SelectedValue); Fgrid.CellChanged(fi,fj,"value",sv); o.visible := false; end property DataList read GetDataList write SetDataList; end type TGridCellEventHandleEdit = class(TGridCellEditList,TPropertyTypeEvent) public function create(owner);override; begin inherited; end function CelldbClick(grid,e,d);virtual; begin FGrid := grid; i := e.iitem; FI := I; j := e.isubitem; FJ := J; //处理双击添加回调函数 end end type TGridCellVariableEdit = class(TGridCellEditList,TPropertyVarible) public function create(owner);override; begin inherited; end function nameFilter();virtual; begin return nil; end function GetItemValue(v);override; begin try if v then return v.name; except end ; return v; end end type TListVariable = class(TGridList) {** @explan(说明) 变量选择 %% **} private FOnClickSelected; public function show(f);override; begin inherited; if ifnil(f) or f then begin //echo "width:",Width-11; SetColumnWidth(0,Width-11); end end function create(AOwner);override; begin inherited; WsPopUp := true; OnActivate := thisfunction(GridActivate); ColumnHeader := false; Columns := array( ("text":"variable","width":180) ); end function SetSelectedByValue(v);override; begin if ifnil(v) then return inherited; vi := nil; for i := 0 to List.count-1 do begin if v=list[i].name then begin vi := list[i]; break; end end inherited SetSelectedByValue(vi); end function additem(v);override; begin if not(v is class(TDComponent)) then exit; inherited; end function ClickedGridItem(o,e);override; begin id := e.iitem; inherited; if id<0 or (SelectedValue is class(tnone)) or (SelectedValue = "(none)") then begin UnSelected(); end calldatafunction(FOnClickSelected,o); o.visible := false; end function GridActivate(o,e);virtual; begin if e.wparam = WA_INACTIVE then O.Visible := false; end function DoDrawSubItem(o,e);override; begin {** @explan(说明) 绘制子项 %% **} dc := e.canvas; if not dc.Handle then exit; j := e.subitemid; if j = 0 then begin i := e.itemid; src := e.subItemRect; dc.DrawText(List[i].name,src,DT_VCENTER .| DT_SINGLELINE); end end property OnClickSelected read FOnClickSelected write FOnClickSelected; end type TListStr = class(TListVariable) function create(AOwner);override; begin inherited; Columns := array(("text":"打开编辑器","width":160)); end function additem(v);override; begin if ifstring(v) then class(TGridList).additem(v); end function SetSelectedByValue(v);override; begin return class(TGridList).SetSelectedByValue(v); end function DoDrawSubItem(o,e);override; begin {** @explan(说明) 绘制子项 %% **} dc := e.canvas; if not dc.Handle then exit; j := e.subitemid; if j = 0 then begin i := e.itemid; src := e.subItemRect; dc.DrawText(List[i],src,DT_VCENTER .| DT_SINGLELINE); end end end type TListVariableFilter = class(TListVariable) private FVlist; FFilter; FFirst; type ttypefilter = class FStyle; function filter(o); begin if o is class(TDComponent) then begin if not FStyle then return true; return o.dclassname() =FStyle ; end end end function SetFilter(v); begin FFilter.FStyle:=v; dofilter(); return ; end public function clean(); begin class(TListVariable).clean(); FVlist.clean(); FFirst := true; end function deletebyvalue(v);override; begin idx := FVlist.indexof(v); if idx>=0 then begin FVlist.deli(idx); inherited; end end function cleandestroy();//销毁不存在的控件 begin id := 0; while idd then begin SetValue(indexs union array(index),d); rec := GetSubItemRect(i,j); InvalidateRect(rec,true); end currentLeave(); except end; FInsetvalue := false; end function SetValue(indexs,d); virtual;//修改对象 begin {** @explan(说明) 修改格子的内容,已经控件的内容%% **} if not (FComponent is class(TDComponent)) then exit; n := indexs[0]; {rfocus := false; if n in array("left","top","width","height") then begin ccwnd := FComponent.Cwnd; if ccwnd is class(TWincontrol) then begin if Designer then begin Designer.setcomponentfocus(ccwnd,false); rfocus := true; end end end //inherited; if (n="visible" and not(d)) or (n="wspopup" and d) or (n="align") then begin if Designer then begin Designer.setcomponentfocus(FComponent.Cwnd,false); end end } if FComponent.SetComponentProperties(n,d) then begin //echo "\r\ntrue"; inherited; end {if (n="visible" and d) or (n="wspopup" and not(d)) then begin if Designer then begin Designer.setcomponentfocus(FComponent.Cwnd,true); end end } end function Notification_rename(o,op);override; begin inherited; if {HandleAllocated() and} ifarray(op) and (op["type"]="possize") and (FComponent is class(TDComponent)) and (FComponent.Cwnd = o) then begin dt := TSLData; flg := op["flag"]; if ifarray(dt) then begin for i,v in mrows(dt,1) do begin if (flg .& 1) and v="left" then begin CellChanged(i,1,"value",op["data"][0]); end if (flg .& 2) and v="top" then begin CellChanged(i,1,"value",op["data"][1]); end if (flg .& 4) and v="width" then begin CellChanged(i,1,"value",op["data"][2]); end if (flg .& 8) and v="height" then begin CellChanged(i,1,"value",op["data"][3]); end end return 1; end end end function SetGridValue(index,d,o); begin if (FComponent is class(TDComponent)) and FComponent.Cwnd = o then begin dt := TSLData; if ifarray(dt) then begin for i,v in mrows(dt,1) do begin if v=index then begin CellChanged(i,1,"value",d); return 1; end end end end return o.SetPublish(index,d); end function WMMove(o,e):WM_MOVE;override; begin inherited; currentLeave(); end function CellClick(o,e);virtual; begin i := e.iitem; j := e.isubitem; cellid := array(i,j); if not( i>=0 and j>=0) then begin return currentLeave(); end index := 1; d := getdata(i,j,cp,index); if ifarray(d) and d["type"]="object" then begin editer := GetCellEditer(d["class"]); if (cellid<>FCurrentIndex ) then begin currentLeave(); end if ifobj( editer) then begin FCurrentEditer := editer; FCurrentIndex := cellid; editer.CellClick(o,e,d); end end else begin if (cellid<>FCurrentIndex) then begin currentLeave(); FCurrentIndex := cellid; end end end function create(AOwner);override; begin inherited; ColumnHeader := false; color := rgb(255,255,255); onclick := thisfunction(CellClick); ColumnWidth := 150; FCellEditers := array(); //OndblClick := nil; FDesigner := AOwner; end function Recycling();override; begin FDesigner := nil; inherited; end function CNMEASUREITEM(O,E):CN_MEASUREITEM;override; begin e.height := 26; end function DoDrawSubItem(o,e);override; begin j := e.subitemid; dc := e.canvas; dc.font := font; if j=0 then return inherited; i := e.itemid; d := getdata(i,j); if ifstring(d) or ifnumber(d) then begin return inherited; end else if ifnil(d) then return ; src :=e.SubItemRect; if not(ifarray(d) and (d["type"] = "object" )) then exit; edit := GetCellEditer(d["class"]); if not(edit)then return inherited; edit.CellDraw(o,e,d); end property EventEditer write FEventEditer; property VariabeEditer write FVariabeEditer; property Component read FComponent write SetComponent; property Designer read FDesigner; {** @param(Component)(TDComponent) 控件设计对象 %% @param(Designer)(TVclDesigner) 设计器 %% **} end; implementation type TTSLDataGrid=class(TDrawGrid) {** @ignore(忽略) %% @explan(说明)TSL数组和对象展示 %% **} private FCols; Fdata; FObjectData; FMRWD; FGridControl; FRows; FShowTwo; FCControls; FColumnWidth; FRowHeader; static FGCellRender; FCanEditStr; FEditStr; FControlIndex; FStringAlign; FNumberAlign; FDefAlign; function SetStringAlign(v); begin if v <> FStringAlign then begin FStringAlign := v; InvalidateRect(nil,true); end end function SetNumberAlign(v); begin if v <> FNumberAlign then begin FNumberAlign := v; InvalidateRect(nil,true); end end function SetdefAlign(v); begin if v <> FDefAlign then begin FDefAlign := v; InvalidateRect(nil,true); end end function GetTSLData(); begin if FObjectData then return FObjectData; return FData; end function CreateFedit(); begin if not FEditStr then begin FEditStr := new tedit(self); FEditStr.onkeypress := thisfunction(EditKeyPress); FEditStr.onkillfocus := thisfunction(EditKillFocus); FEditStr.visible := false; FEditStr.parent := self; end return FEditStr; end function StrToNumber(s); begin if pos(".",s)then begin return StrToFloatDef(s,0); end else begin return StrToIntDef(s,0); end end public function GetCellRender(n); begin if not ifarray(FGCellRender)then begin FGCellRender := array(); end return FGCellRender[n]; end private function SetRowHeader(v); begin nv := v?true:false; if FRowHeader <> nv then begin FRowHeader := nv; FD := FData; SetData(array()); SetData(FD); end end function SetTwoD(v); begin if parent is class(TTSLDataGrid)then exit; nv := v?true:false; if nv <> FShowTwo then begin FD := FData; SetData(array()); FShowTwo := nv; SetData(FD); end end function setdatap(); begin if not Fdata then exit; FCols := nil; FRows := mrows(Fdata,1); FCL := mcols(Fdata,1); allFCL := true; for i,v in FData do begin if not ifarray(v)then begin allFCL := false; break; end end fcs := array(); wd := 80; ftwidth := font.width; for i,v in FRows do begin if ifstring(v)then begin wd := max(wd,length(v) * ftwidth+3); if wd>200 then break; end end if RowHeader then begin fcs[0]:= array("text":" ","width":min(200,wd)); end if FCL and allFCL and FShowTwo then begin FCols := FCl; for i,v in FCols do begin fcs[length(fcs)]:= array("text":ifstring(v)?v:inttostr(v),"width":FMRWD); end end else begin fcs[length(fcs)]:= array("text":" ","width":ColumnWidth>20?ColumnWidth:100); end Columns := fcs; ItemCount := length(FRows); end function objecttoarray(d); begin if dep<0 then return 0; if not ifobj(d)then return 0; try di := d.classinfo(); except return 0; end; da := array(); inhs := array(); for i,v in di["inherited"] do begin inhs[v]:= findclass(v,d); end if inhs then da["inherited"]:= inhs; k := 0; for i,v in di["members"] do begin if(v["access"]in array(0,1,4))then begin vn := v["name"]; da[vn]:= invoke(d,vn); end end for i,v in di["properties"] do begin if v["access"]in array(0,1,4)then begin vn := v["name"]; if not(v["read"])then continue; da[vn]:= invoke(d,vn); end end return da; end function SetData(data,f); begin if Fdata=data then return; DeleteAllColumns(); if ifobj(data)then begin FObjectData := data; r := objecttoarray(data); return SetData(r,1); end if not ifarray(data)then return; if f then FObjectData := nil; FData := data; setdatap(); end function itemishow(r,r2); begin return r[2]r2[2]; end function getitemcontrol(d,p,i,j,tp,cp,idexs); begin idx := format("%d*%d",i,j); o := FCControls[idx]; if tp="grid" then begin if not o then begin o := new TTSlDataGrid(self); o.ControlIndexs(idexs); o.height := 500; o.width := 500; o.Twodimensional := Twodimensional; O.CanEditStr := CanEditStr; o.Visible := false; o.wspopup := true; o.WsSysMenu := true; o.WsSizeBox := true; o.parent := self; o.onclose := thisfunction(ShowDataClose); FCControls[idx]:= o; end o.Twodimensional := Twodimensional; if o.wspopup then p := ClientToScreen(p[0],p[1]); o.left := p[0]; o.top := p[1]; o.caption := cp; o.TSLdata := d; o.show(); end end public function create(AOwner);override; begin inherited; FCControls := array(); FRowHeader := true; FixedColumns := 1; caption := ""; FMRWD := 100; FShowTwo := false; //OndblClick := thisfunction(GridCellDblClick); OnClick := thisfunction(CellClick); RegisterRender(new TGCellBoolRender()); FNumberAlign := AL9_CENTERRIGHT; FStringAlign := AL9_CENTERLEFT; FDefAlign := AL9_CENTER; end function InitializeWnd();override; begin inherited; end procedure Notification(AComponent:TComponent;Operation:TOperation);override; begin if Operation=opRemove then begin for i,v in FCControls do begin if v=AComponent then begin reindex(FCControls,array(i:nil)); break; end end end inherited; end function getdata(i,j,cp,indexs); begin {** @explan(说明) 获取数据 **} if not FRows then return nil; if j=0 and FRowHeader then return FRows[i]; r := FRows[i]; if FCols and FShowTwo then begin if FRowHeader then c := FCols[j-1]; else c := FCols[j]; d := FData[r][c]; if cp then cp := "["+tostn(r)+"]"; if cp then cp += "["+tostn(c)+"]"; if indexs then indexs := array(r,c); end else begin d := FData[FRows[i]]; if cp then cp := "["+tostn(r)+"]"; if indexs then indexs := array(r); end return d; end function DoDrawSubItem(o,e);override; begin inherited; if e.skip then exit; dc := e.canvas; i := e.itemid; j := e.subitemid; d := getdata(i,j); src := e.SubItemRect; if j=0 and FRowHeader then begin //_wapi.DrawFrameControl(dc.Handle,src,DFC_BUTTON,DFCS_BUTTONPUSH); dc.Draw("framecontrol",array(src[0:1],src[2:3]),DFC_BUTTON,DFCS_BUTTONPUSH); end ds := ""; dc.font.color := 0; if ifarray(d)then begin if d["type"]="object" then begin rd := GetCellRender(d["class"]); if rd is class(TGCellRender)then begin rd.CellDraw(o,e,d); end end else begin ds := format("",length(d)); //dc.drawtext(ds,src); class(TLabel).CanvasDrawAlignText(dc,src,ds,FDefAlign); end end else if ifstring(d)then begin ds := d; //dc.drawtext(ds,src); class(TLabel).CanvasDrawAlignText(dc,src,ds,FStringAlign); end else if ifobj(d)then begin //dc.drawtext("",src); class(TLabel).CanvasDrawAlignText(dc,src,"",FDefAlign); end else begin ds := tostn(d); if d<0 then dc.font.color := rgb(200,0,0); if ifnumber(d)and j>0 then begin //dc.drawtext(ds,src,DT_RIGHT); class(TLabel).CanvasDrawAlignText(dc,src,ds,FNumberAlign); end else begin //dc.drawtext(ds,src); if not ifnil(d)then class(TLabel).CanvasDrawAlignText(dc,src,ds,FStringAlign); end end end function DoDrawItem(o,e);override; begin dc := e.canvas; rc := e.rcitem; {if SelectedRow = e.id then if ifnumber(SelectRowColor) then dc.brush.color := SelectRowColor; else dc.brush.color := rgb(150,150,150); else } if color then dc.brush.color := color; // else dc.brush.color := rgb(255,255,255); dc.fillrect(rc); inherited; end function CellClick(o,e);virtual; begin i := e.iitem; j := e.isubitem; cellid := array(i,j); if not(i >= 0 and j >= 0)then begin exit; end d := getdata(i,j); if ifarray(d)and d["type"]="object" then begin rd := GetCellRender(d["class"]); if rd is class(TGCellRender)then begin return rd.CellClick(o,e,d); end end else if ifnumber(d)or ifstring(d)or ifnil(d)then begin CreateFedit(); if not CanEditStr then exit; onShowEdit(e); end end function GridCellDblClick(o,e);virtual; begin cp := 1; cl := e.isubitem; if cl<1 and FRowHeader then exit; indexs := 1; d := getdata(e.iitem,cl,cp,indexs); p := e.ptaction; if ifarray(d)then begin if d["type"]="object" then begin rd := GetCellRender(d["class"]); if r then return r.CelldbClick(o,e,d); end getitemcontrol(d,p,e.iitem,cl,"grid",cp,indexs); end else if ifobj(d)then begin return getitemcontrol(d,p,e.iitem,cl,"grid",cp,indexs); end end function ShowDataClose(o,e); begin o.show(false); o.TSLdata := array(); e.skip := true; o.Recycling(); end function Recycling();override; begin FCols := nil; Fdata := nil; inherited; end function SetValue(index,val);virtual; begin if ifobj(FObjectData)then begin p := index[0]; if ifstring(p)then begin try invoke(FObjectData,p,1,val); except end end end if not ifarray(FData)then exit; r := magicsetarray(FData,index,val); if FControlIndex then begin if parent is class(TTSLDataGrid)then begin parent.SetValue(FControlIndex,FData); end end return r; idx := "FData"; for i,v in index do begin if ifnumber(v)then idx += format("[%d]",v); else if ifstring(v)then begin idx += format('["%s"]',v); end end if length(idx)>5 then begin vals := idx+":="+tostn(val)+";"; //FData["c"]["value"]:=0; try eval(&vals); except //echo "===errr"; end; end end function ControlIndexs(dx); begin {** @ignore(忽略) %% **} if dx then FControlIndex := dx; return FControlIndex; end function RegisterRender(it); begin if it is class(TGCellRender)then begin if not ifarray(FGCellRender)then FGCellRender := array(); FGCellRender[it.EditType()]:= it; end else if ifarray(it)then begin for i,v in it do call(thisfunction,v); end end function EditKeyPress(o,e); begin k := e.wparam; if k=VK_ESCAPE or k=13 then begin info := o._tag; if ifarray(info)then begin v := o.text; v2 := info[2]; if ifnumber(v2)then begin vi := StrToNumber(v); if v2 <> vi then begin SetValue(info[3],vi); end end else begin if v2 <> v then begin SetValue(info[3],v2); end end end o.visible := false; end end function EditKillFocus(o,e); begin o.visible := false; end function onShowEdit(e); begin {** @explan(说明) 显示编辑框 %% **} i := e.iitem; j := e.isubitem; rc := GetSubItemRect(i,j); FEditStr.SetBoundsRect(rc); indexs := 1; v := getdata(i,j,nil,indexs); FEditStr._tag := array(i,j,v,indexs); vs := ""; if ifstring(v)then vs := v; else if ifnumber(v)then v := tostn(v); FEditStr.text := v; FEditStr.show(); xy := e.ptaction; pt := makelong(xy[0]-rc[0],xy[1]-rc[1]); FEditStr._send_(WM_LBUTTONDOWN,0,pt,0); end property Twodimensional:bool read FShowTwo write SetTwoD; property TSLdata:variable read GetTSLData write SetData; property ColumnWidth:integer read FColumnWidth write FColumnWidth; property RowHeader:bool read FRowHeader write SetRowHeader; property CanEditStr:bool read FCanEditStr write FCanEditStr; property StringAlign:AlignStyle9 read FStringAlign write SetStringAlign; property NumberAlign:AlignStyle9 read FNumberAlign write SetNumberAlign; property DefAlign:AlignStyle9 read FDefAlign write SetdefAlign; {** @param(Twodimensional)(BOOL) 是否二维强制二维展示 %% @param(TSLdata)(array) tsl数据 %% **} end type TGridList = class(TListView) {** @explan(说明) 用tlistview 模拟 list %% **} function clean(); begin DeleteAllItems(); end function CheckItem(v);override; begin {** @explan(说明) 检查项目 %% **} return List.indexof(v)<0; end function additem(v);virtual; begin appenditem(v); end function additems(v);virtual; begin appenditems(v); end function create(AOwner);override; begin inherited; end function DoDrawSubItem(o,e);override; begin dc := e.canvas; if not dc.Handle then exit; j := e.subitemid; if j = 0 then begin i := e.itemid; src := e.subItemRect; _wapi.DrawFrameControl(dc.Handle,src,DFC_BUTTON,DFCS_BUTTONPUSH); dc.DrawText(inttostr(i),src,DT_VCENTER .| DT_SINGLELINE); end end end //**********属性编辑类*************** ///////////////////////////////////////////////////////////////////////// type TGridCellNaturalEdit = class(TGridPropertyRender,TPropertyNatural) FRow; FCol; FGrid; FEdit; public function create(AOwner);override; begin inherited; FGrid := AOwner; end function numbertotext(num);virtual; begin if ifnumber(num) then return inttostr(num); return ""; end function textonumber(txt);virtual; begin return strtointdef(txt,0); end function Ched(o,e); begin v := textonumber(o.TEXT); FGrid.CellChanged(FRow,FCol,"value",v); //o.parent.CallChanged(o.parent,nil); end function EditKeyPress(o,e);virtual; begin if 13 = e.wparam then begin try ched(o); o.visible := false; except end ; end else begin if not(e.wparam >= ord("0") and e.wparam<= ord("9") or e.wparam = VK_BACK) then e.skip := true; end end function CellClick(grid,e,d);override; begin {** @explan(说明) 格子点击 %% **} i := e.iitem; j := e.isubitem; Frow := i; FCol := j; pt := e.ptaction; rec := grid.getSubItemRect(i,j); if d["class"]=EditType() and (FGrid is class(TDrawGrid)) then begin if not(FEdit is class(TWincontrol)) then begin FEdit := new TPopEditCtrl(FGrid); FEdit.visible := false; FEdit.OnKeyPress := thisfunction(EditKeyPress); FEdit.parent := FGrid; FEdit.OnChanged := thisfunction(Ched); end FEdit.SetBoundsRect(FGrid.clienttoscreen(rec[0],rec[1]) union FGrid.clienttoscreen(rec[2],rec[3])); FEdit.text := numbertotext(d["value"]); FEdit.parent := grid; FEdit.SetFocus(); FEdit.visible := true; end end function CellDraw(grid,e,d);override; begin {** @explan(说明) 绘制格子 %% **} if FGrid is class(TDrawGrid) then e.canvas.drawtext(numbertotext(d["value"]),e.subItemRect,DT_CENTER .| DT_VCENTER .| DT_SINGLELINE); end function CellLeave(grid);virtual; begin {** @explan(说明) 离开编辑格子 %% **} if not(FEdit is class(TEdit)) then exit; FEdit.text := ""; FEdit.visible := false; inherited; end; end type TGridCellIntegerEdit = class(TGridCellNaturalEdit) {** @explan(说明) 整数编辑 %% **} function EditType();override; begin return "integer"; end function FormatEdit(d,modify);override; begin {** @explan(说明)控件数据转换为修改表格数据 %% **} r := inherited; r["class"] := EditType(); if not ifnil(d) then begin r["value"] := d; end return r; end public function Create(AOwner);override; begin inherited; end function EditKeyPress(o,e);override; begin if e.wparam = ord("-") then begin end else inherited; end end type TGridCellStringEdit = class(TGridCellNaturalEdit) {** @explan(说明) 整数编辑 %% **} function EditType();override; begin return "string"; end function FormatEdit(d,modify);override; begin {** @explan(说明)控件数据转换为修改表格数据 %% **} r := inherited; r["class"] := EditType(); if not ifnil(d) then begin r["value"] := d?:""; end return r; end public function Create(AOwner);override; begin inherited; end function textonumber(txt);override; begin return txt; end function numbertotext(num);override; begin return num; end function EditKeyPress(o,e);override; begin if e.wparam <>13 then begin end else inherited; end end type TPopEditCtrl = class(TCustomControl) private FEdit; FOnChanged; FOnKeyPress; function GetText(); begin return FEdit.Text; end function SetText(v); begin FEdit.Text := v; end public function dosetfocus();override; begin FEdit.SetFocus; end function WMACTIVATE(o,e):WM_ACTIVATE;override; begin if e.wparam = 0 then begin CallChanged(o,e); end end function CallChanged(o,e); begin o.visible := false; CallDataFunction(FOnChanged,o,e); //O.text := ""; end function create(AOwner);override; begin inherited; WsPopUp := true; WsDlgModalFrame := false; FEdit := new tedit(self); width := FEdit.Width+2; height := FEdit.Height +2; FEdit.align := alClient; FEdit.parent := self; FEdit.OnKeyPress := function(o,e)begin CallDataFunction(FOnKeyPress,self,e); end end function ReCycling();override; begin FOnChanged := nil; FOnKeyPress := nil; inherited; end property Text read GetText write SetText; //文本 property OnKeyPress read FOnKeyPress write FOnKeyPress; //按下 property OnChanged read FOnChanged write FOnChanged; //改变 end type TGridCellColorEdit = class(TGridCellEditWithButton,TPropertyColor) {** @explan(说明) color edit **} private Fcpok ; FColorChoose; public function create(AOwner);override; begin inherited; FRbuttonWidth := 20; end function ButtonClick(grid,e,d);override; begin Fcpok := true; if not(FColorChoose) then begin FColorChoose := new TColorChooseADlg(grid); FColorChoose.Parent := grid; end FColorChoose.Result := d["value"]; if FColorChoose.OpenDlg() and Fcpok then begin grid.CellChanged(e.iitem,e.isubitem,"value",FColorChoose.Result); end end function CellDrawLabel(dc,rect,d);override; begin {** @explan(说明) 绘制格子 %% **} dc.brush.color := d["value"]; dc.fillrect(rect); end function CellLeave();override; begin Fcpok := false; inherited; end end type TGridCellDirectoryEdit = class(TGridCellEditWithButton,TPropertyDirectory) {** @explan(说明) color edit **} private Fcpok ; FColorChoose; public function create(AOwner);override; begin inherited; end function ButtonClick(grid,e,d);override; begin Fcpok := true; if not(FColorChoose) then begin FColorChoose := new TFolderChooseADlg(grid); FColorChoose.Parent := grid; end if FColorChoose.OpenDlg() and Fcpok then begin grid.CellChanged(e.iitem,e.isubitem,"value",FColorChoose.Folder); end end function CellDrawLabel(dc,rect,d);override; begin {** @explan(说明) 绘制格子 %% **} if ifarray(d) then begin dc.drawtext(d["value"],rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function CellLeave();override; begin Fcpok := false; inherited; end end type TGridCellFileNameEdit = class(TGridCellEditWithButton,TPropertyFileName) {** @explan(说明) color edit **} private Fcpok ; FColorChoose; public function create(AOwner);override; begin inherited; end function ButtonClick(grid,e,d);override; begin Fcpok := true; if not(FColorChoose) then begin FColorChoose := new TOpenFileADlg(grid); FColorChoose.Parent := grid; end if FColorChoose.OpenDlg() and Fcpok then begin grid.CellChanged(e.iitem,e.isubitem,"value",FColorChoose.FileName); end end function CellDrawLabel(dc,rect,d);override; begin {** @explan(说明) 绘制格子 %% **} if ifarray(d) then begin dc.drawtext(d["value"],rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function CellLeave();override; begin Fcpok := false; inherited; end end type TGridCellFontEdit = class(TGridCellEditWithButton,TPropertyFont) {** @explan(说明) font edit **} private Fcpok ; FColorChoose; fparser; public function create(AOwner);override; begin inherited; end function ButtonClick(grid,e,d);override; begin Fcpok := true; if not(FColorChoose) then begin FColorChoose := new TFontChooseADlg(grid); FColorChoose.Parent := grid; end FColorChoose.fontinfo := d["value"]; if FColorChoose.OpenDlg() and Fcpok then begin i := e.iitem; j := e.isubitem; grid.CellChanged(i,j,"value",FColorChoose.fontinfo); end end function CellDrawLabel(dc,rect,d);override; begin dc.SaveDC(); dc.font := d["value"]; dc.drawtext("tfont",rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); dc.RestoreDC(); end function CellLeave();override; begin Fcpok := false; inherited; end end type TGridCellhotkeyEdit = class(TGridPropertyRender,TPropertyHotkey) {** @explan(说明) 自然数编辑 **} FRow; FCol; FGrid; FEdit; function hotchange(o,e); begin if e.wparam = 13 then begin e.skip := true; FGrid.CellChanged(FRow,FCol,"value",FEdit.hotkey); end end public function create(AOwner);override; begin inherited; FGrid := AOwner; end function CellClick(grid,e,d);override; begin {** @explan(说明) 格子点击 %% **} i := e.iitem; j := e.isubitem; Frow := i; FCol := j; pt := e.ptaction; rec := grid.getSubItemRect(i,j); if d["class"]=EditType() and (FGrid is class(TDrawGrid)) then begin if not(FEdit is class(TEdit)) then begin FEdit := new thotkey(FGrid); FEdit.visible := false; FEdit.parent := FGrid; FEdit.onkeydown := thisfunction(hotchange); end FEdit.SetBoundsRect(rec); FEdit.hotkey := d["value"]; FEdit.parent := grid; FEdit.SetFocus(); FEdit.visible := true; end end function CellDraw(grid,e,d);override; begin {** @explan(说明) 绘制格子 %% **} if FGrid is class(TDrawGrid) then if ifarray(d) then e.canvas.drawtext(class(thotkey).hotkeytostr(d["value"]),e.subItemRect,DT_CENTER .| DT_VCENTER .| DT_SINGLELINE); end function CellLeave(grid);override; begin {** @explan(说明) 离开编辑格子 %% **} if not(FEdit is class(thotkey)) then exit; FEdit.visible := false; inherited; FGrid.CellChanged(FRow,FCol,"value",FEdit.hotkey); end; end type TGridCellBoolEdit = class(TGridPropertyRender,TPropertyBool) {** @explan(说明) boolcell编辑 **} private FRbuttonWidth; function DrawButton(dc,srca,v); begin src := srca; src[0] := src[2]-FRbuttonWidth; src[1]+=3; src[3]-=3; _wapi.DrawFrameControl(dc.Handle,src,DFC_BUTTON,v?DFCS_CHECKED:DFCS_BUTTONCHECK); end public function create(AOwner);override; begin inherited; FRbuttonWidth := 20; end function CellClick(grid,e,d);override; begin {** @explan(说明) 格子点击 %% **} if not( grid is class(TDrawGrid)) then exit; i := e.iitem; j := e.isubitem; pt := e.ptaction; rec := grid.getSubItemRect(i,j); if pt[0]<(rec[2]-FRbuttonWidth) then exit; if d["class"]="bool" then begin grid.CellChanged(i,j,"value",not(d["value"])); end end function CellDraw(grid,e,d);override; begin {** @explan(说明) 绘制格子 %% **} src := e.SubItemRect; dv := d["value"]; dc := e.canvas; if src[2]-src[0]>50 then begin src1 := src; src1[2]-=FRbuttonWidth; dc.drawtext(dv?"TRUE":"FALSE",src1,DT_CENTER .| DT_VCENTER .| DT_SINGLELINE); end DrawButton(dc,src,dv); end end type TGridCellSysCursorEidt=class(TOneSelectCell,TPropertyTypeSysCursor) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyTypeSysCursor).Create(); end private function SelPalRange();virtual; begin return SelRange; end end //属性编辑表格 type TGridCellVariableTactionEdit = class(TGridCellVariableEdit) function nameFilter();override; begin return EditType(); end function IfComponent();virtual; begin {** @explan(说明) 是否为控件%% **} return true; end Function EditType();override; begin return "taction"; end function CellDrawLabel(dc,rect,d);override; begin v := d["value"]; if v is class(tcomponent) then begin dc.DrawText(v.name,rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end else inherited; end function create(owner);override; begin inherited; end end type TGridCellVariableTrayEdit = class(TGridCellVariableTactionEdit) Function EditType();override; begin return "ttray"; end function create(owner);override; begin inherited; end end type TGridCellVariabletpopupmenuEdit = class(TGridCellVariableTactionEdit) Function EditType();override; begin return "tpopupmenu"; end function create(owner);override; begin inherited; end end type TGridCellVariabletmainmenuEdit = class(TGridCellVariableTactionEdit) Function EditType();override; begin return "tmainmenu"; end function create(owner);override; begin inherited; end function FormatTMF(d);override; begin if d is class(tcomponent) then begin r := d.name; if r then return r; end return false; end function GetItemValue(V);override; begin if v is class(TDComponent) then r := v.GetTrueComponent(); return r; end end type TGridCellVariabletimagelistEdit = class(TGridCellVariableTactionEdit) Function EditType();override; begin return "tcontrolimagelist"; end function CellDrawLabel(dc,rect,d);override; begin v := d["value"]; if v is class(tcomponent) then begin dc.DrawText(v.name,rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function FormatTMF(d);override; begin if d is class(tcomponent) then begin r := d.name; if r then return r; end return false; end function GetItemValue(V);override; begin if v is class(TDComponent) then r := v.GetTrueComponent(); return r; end function create(owner);override; begin inherited; end end type TGridCellVariablehgtEdit = class(TGridCellVariabletimagelistEdit) Function EditType();override; begin return "thighlighter"; end function create(owner);override; begin inherited; end end type TBtnCellDrawVTtype = class(TGridCellEditWithButton) function Create(AOwner);override; begin inherited; end function CellDrawLabel(dc,rect,d);override; begin {** @explan(说明) 绘制标签 %% **} if ifarray(d) then begin dc.drawtext(self(true).EditType(),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end end type TGridCellImagesEdit = class(TBtnCellDrawVTtype,TPropertyImagesData) private FGrid; FEdit; FImageEditer; function GetImagesEdit(); begin if not FImageEditer then begin FImageEditer := new TIconsEditer(FGrid); FImageEditer.parent := FGrid; end FImageEditer.clean(); return FImageEditer; end public function CellDrawLabel(dc,rect,d);override; begin if not(d and ifarray(d)) then exit; dv := d["value"]; if ifarray(dv) and dv["type"]="bmps" then begin its := dv["items"]; if ifarray(its) then dc.DrawText("imgs:"+inttostr(length(its)),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; FRbuttonWidth := 20; FGrid := AOwner; end function ButtonClick(grid,e,d);override; begin GetImagesEdit(); if FImageEditer then begin FImageEditer.seticons(d["value"]["items"]); FImageEditer.showmodal(); if self.Activated then begin dd := FImageEditer.GetIcons(); //echo tostn(dd); grid.CellChanged(e.iitem,e.isubitem,"value",array("type":"bmps","items":dd)); end end end end type TGridCellBitmapEdit = class(TBtnCellDrawVTtype,TPropertyBitmap) private FGrid; FEdit; FImageEditer; function GetImagesEdit(); begin if not FImageEditer then begin FImageEditer := new TOpenFileADlg(FGrid); FImageEditer.parent := FGrid; end return FImageEditer; end public function CellDrawLabel(dc,rect,d);override; begin {** @explan(说明) 绘制格子 %% **} if ifarray(d) and (d["value"] is class(TcustomBitmap) )then inherited; end function create(AOwner);override; begin inherited; FRbuttonWidth := 20; FGrid := AOwner; end function ButtonClick(grid,e,d);override; begin i := e.iitem; j := e.isubitem; pt := e.ptaction; rec := grid.getSubItemRect(i,j); GetImagesEdit(); if FImageEditer.opendlg() then begin inherited; bmp := new tbitmap(); bmp.id := FImageEditer.FileName; if bmp.HandleAllocated() then grid.CellChanged(i,j,"value",bmp); else grid.CellChanged(i,j,"value",nil); end else grid.CellChanged(i,j,"value",nil); end end type TGridCellIconEdit = class(TBtnCellDrawVTtype,TPropertyIcon) private FGrid; FEdit; FImageEditer; function GetImagesEdit(); begin if not FImageEditer then begin FImageEditer := new TOpenFileADlg(FGrid); FImageEditer.parent := FGrid; end return FImageEditer; end public function CellDrawLabel(dc,rect,d);override; begin {** @explan(说明) 绘制格子 %% **} if ifarray(d) and (d["value"] is class(tcustomicon)) then inherited; end function create(AOwner);override; begin inherited; FRbuttonWidth := 20; FGrid := AOwner; end function ButtonClick(grid,e,d);override; begin i := e.iitem; j := e.isubitem; pt := e.ptaction; rec := grid.getSubItemRect(i,j); GetImagesEdit(); if FImageEditer.opendlg() then begin inherited; ic := new Ticon(); ic.id := FImageEditer.FileName; if ic.HandleAllocated() then grid.CellChanged(i,j,"value",ic); else grid.CellChanged(i,j,"value",nil); end else grid.CellChanged(i,j,"value",nil); end end type TGridCellStatusItemsEdit = class(TBtnCellDrawVTtype,TPropertyStatusItems) private FGrid; FStatus; function GetWnd(); begin if (not FStatus) and (FGrid is class(TWincontrol)) then begin FStatus := new TListStatusEdit(FGrid); FStatus.parent := FGrid; end return FStatus; end public function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) and ifarray(d["value"]) then begin dc.DrawText("item:"+inttostr(length(d["value"])),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(owner);override; begin inherited; FGrid := owner; end function OnApplay(o,e);virtual; begin o.EndModalCode := true; o.EndModal(); end function ButtonClick(grid,e,d);override; begin if GetWnd() then begin inherited; FStatus.OnApplay := thisfunction(OnApplay); FStatus.setitems(d["value"]); FStatus.EndModalCode := false; if FStatus.showmodal() then begin grid.CellChanged(e.iitem,e.isubitem,"value",FStatus.ListControl.ListValues); end end end end type TGridCellFileFilterEdit = class(TGridCellEditWithButton,TPropertyFileFilter) private FGrid; FStatus; function GetWnd(); begin if (not FStatus) and (FGrid is class(TWincontrol)) then begin FStatus := new TListStatusEdit2(FGrid); FStatus.SetLable(0,"显示"); FStatus.SetLable(1,"条件"); FStatus.SetColoumn(1,"文本"); FStatus.SetColoumn(2,"筛选"); FStatus.parent := FGrid; FStatus.FCheckNumber := false; end return FStatus; end public function create(owner);override; begin inherited; FGrid := owner; end function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) and ifarray(d["value"]) then begin dc.DrawText("item:"+inttostr(length(d["value"])),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function OnApplay(o,e);virtual; begin o.EndModalCode := true; o.EndModal(); end function ButtonClick(grid,e,d);override; begin if GetWnd() then begin inherited; FStatus.OnApplay := thisfunction(OnApplay); dv := array(); dvi := 0; for i,v in d["value"] do begin dv[dvi]["width"] := i; dv[dvi++]["text"] := v; end FStatus.setitems(dv); FStatus.EndModalCode := false; if FStatus.showmodal() then begin vs := FStatus.ListControl.ListValues; dv := array(); for i,v in vs do begin dv[v["width"]] := v["text"]; end grid.CellChanged(e.iitem,e.isubitem,"value",dv); end end end end type TGridCellLazyIntegerEdit = class(TGridCellIntegerEdit) function EditType();override; begin return "lazyinteger"; end function LazyProperty();override; begin return true; end function create(AOwner);override; begin inherited; end end type TGridCellLazystrEdit = class(TGridCellStringEdit) //后处理信息 function EditType();override; begin return "lazystr"; end function LazyProperty();override; begin return true; end function create(AOwner);override; begin inherited; end end //*****************选择list******************************************* type UniCheckList = class(TTreeView) //单选 private Fdata; FOnSelChanged; public function Create(AOwner);override; begin inherited; hasline := false; Fdata := array(); OnActivate := function(o,e) begin if e.lowparam = WA_INACTIVE then begin Visible := false; end end ; end function DoOnSelChang(v); begin Calldatafunction(FOnSelChanged,self(true),v); end function MouseUp(o,e);override; begin it := CurrentNode; nit := GetItemIndexByYpos(e.ypos); if nit >=0 then begin inherited; if CurrentNode<>nit then begin DoOnSelChang(CurrentNode._tag); end end else begin DoOnSelChang(nil); end end function hasFocus();override; begin return true; end function SetList(lst); begin clean(); //清空 rnd := RootNode; Fdata := array(); for i,v in lst do begin nd := CreateTreeNode(self); nd.Caption := v[0]; nd._tag := v[1]; nd.Parent := rnd; Fdata[v[1]] := nd; end end function SetSelValue(v); begin for i,vi in FData do begin if vi._tag = v then return SetSel(vi); end end property OnSelChanged read FOnSelChanged write FOnSelChanged; end //*************zh**property******************************* type tGridCellAlignPos3BoxEdit=class(TOneSelectCell ,TPropertyAlign3) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyAlign3).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type tGridCellDayOfWeekBoxEdit=class(TOneSelectCell,TPropertyDayOfWeek) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyDayOfWeek).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type TGridCellPairIntEdit=class(TGridPropertyRender,TPropertyPairInt) private FGrid; FeditWindow; Fi; Fj; type PairWindow=class(tpanel) private ts1; ts2; edit1; edit2; btn; ari; FonOK; function is_valid_int(str);begin arr:=array('0','1','2','3','4','5','6','7','8','9'); if r:=length(str) then begin if r=1 then return not (r='-'); if str[1] in arr or str[1]='-' then begin for i:=2 to r do if not(str[i] in arr) then return 0; return 1; end end return 0; end public function initializewnd();override;begin inherited; ts1.caption:="下限:"; ts2.caption:="上限:"; ts1.left:=8; ts1.top:=8; ts2.left:=8; ts2.top:=40; edit1.top:=8; edit1.left:=50; edit2.top:=40; edit2.left:=50; btn.top:=68; btn.left:=30; btn.caption:="确定"; ts1.parent:=self; ts2.parent:=self; edit1.parent:=self; edit2.parent:=self; btn.parent:=self; end function create(aowner);override;begin inherited; height:=132; width:=152; caption:="设置"; wscaption := true; wssysmenu := true; wspopup := true; visible := false; ari:=array(0,0); ts1:=new tstext(self); ts2:=new tstext(self); edit1:=new tedit(self); edit2:=new tedit(self); btn:=new tbtn(self); btn.onclick:=function(o,e)begin if(is_valid_int(edit1.text) and is_valid_int(edit2.text)) then begin i:=strtoint(edit1.text); j:=strtoint(edit2.text); if i<=j then begin ari:=array(i,j); calldatafunction(FonOK,o,e); visible:=0; setarr(array("","")); return; end end _wapi.MessageBoxA(self.handle,"非法范围","错误",0); end end function WMCLOSE(o,e):WM_CLOSE;override; begin o.visible := false; e.skip := true; inherited; end function getarr();begin return ari; end function setarr(ari);begin edit1.text:=ari[0]; edit2.text:=ari[1]; end property onOK read FonOK write FonOK; end type Tstext = class(TGraphicControl) FCaption ; function create(owner); begin inherited; FCaption := "tstext"; height:=16; width:=50; end procedure Paint(); override; begin rect := clientrect; Canvas.font.height := 16; // Canvas.font.SetValues(array("height":-18,"width":0,"escapement":0,"orientation":0,"weight":400,"italic":0,"underline":0,"strikeout":0,"charset":134,"outprecision":3,"clipprecision":2,"quality":1,"pitchandfamily":2,"facename":"宋体","color":0)); Canvas.drawtext(FCaption,rect); end function SetCaption(v);override; begin inherited; if not(ifstring(v) and (FCaption<>v)) then exit; FCaption := v; end property caption read FCaption write SetCaption; end public function create(AOwner);override;begin inherited; FGrid := AOwner; FeditWindow:=nil; end function CellClick(grid,e,d);override;begin Fi := e.iitem; Fj := e.isubitem; if ifnil(FeditWindow) then begin FeditWindow:=new PairWindow(FGrid); FeditWindow.onOK:=function(o,e)begin Fgrid.CellChanged(Fi,Fj,"value",FeditWindow.getarr()); end end if ifnil(FeditWindow.parent) then begin FeditWindow.parent :=FGrid; end rec := grid.getSubItemRect(Fi,Fj); r:=grid.ClientToScreen(rec[0],rec[3]); FeditWindow.left:=r[0]; FeditWindow.top:=r[1]; FeditWindow.show(); end function CellDraw(grid,e,d);override;begin {** @explan(说明) 绘制格子 %% **} if FGrid is class(TDrawGrid) then begin str:=inttostr(d["value"][0])+":"+inttostr(d["value"][1]); e.canvas.drawtext(str,e.subItemRect,DT_CENTER.|DT_VCENTER); end end function CellLeave(grid);override;begin {** @explan(说明) 离开编辑格子 %% **} _wapi.PostMessageA(FeditWindow.handle,WM_CLOSE,0,0); end end type TGridCellPairSpliterTypeEdit=class(TOneSelectCell,TPropertySpliterType) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertySpliterType).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type TGridCellTreeViewDataEdit=class(TGridCellEditWithButton,TPropertyTreeViewData) private FeditWindow; Fgrid; fi; fj; FnodeNum; type tPopupEditorWindow=class(tpanel) private FtreeViewBox; FnewItemBtn; FnewSubItemBtn; FmoveUpBtn; FmoveDownBtn; FdeleteBtn; FclearBtn; Fstatictxt0; Fstatictxt1; Fstatictxt2; Fedit0; Fedit1; Fedit2; Fokbtn; Fcancelbtn; mok; editingNode; function setwindow(window,l,t,w,h);begin if l then window.left:=l; if t then window.top:=t; if h then window.height:=h; if w then window.width:=w; window.parent:=self; end type TreeViewEditorClass=class(TTreeView) private currentSelection; counter; fSelectionChanged; function createNode(aname,img,selimg);begin n:=new TTreeNode(self); n.caption:=aname; n.imgid:=img; n.selimgid:=selimg; return n; end type nameCounter=class private countNumber; countUp; public function create();begin countNumber:=0; countUp:=0; end function getName();begin if countUp<>1000000 then begin ++countNumber; return "项目"+inttostr(countUp++); end return "项目"; end function deleteName(n);begin if "项目"+inttostr(countUp-1)=n then --countUp; --countNumber; end function reset(n);begin countNumber:=n?:0; countUp:=n?:0; end end function getlastnode(node);begin t:=node.itemcount; if t then return getlastnode(node.indexof(t-1)); return node; end function setCurrentSelection(n,b);begin if b then currentSelection:=n; else setsel(n); end function getCurrentSelection();begin if ifnil(currentSelection) then currentSelection:=rootItem; return currentSelection; end public function initializewnd();override;begin inherited; getCurrentSelection(); end function create(aOwner);override;begin inherited; // counter:=new nameCounter(); self.OnSelChanged:=function(o,e)begin if e.itemnew is class(tTreeNode) then begin setCurrentSelection(e.itemnew,1); calldatafunction(fSelectionChanged,getCurrentSelection()); end end end function addNewItem();begin //添加新项 // if not currentSelection then currentSelection := RootItem; if getCurrentSelection()=RootItem then return addNewSubItem(); // d:=createNode(counter.getName(),-1,-1); d:=createNode("item",-1,-1); // p:=currentSelection.parent; getCurrentSelection().insertsibling(d); setCurrentSelection(d); end function addNewSubItem();begin //添加新子项 // d:=createNode(counter.getName(),-1,-1); d:=createNode("item",-1,-1); getCurrentSelection().insertNode(d); setCurrentSelection(d); end function move(b);begin //0下移,1上移。 if getCurrentSelection()=RootItem then return; t:=getCurrentSelection(); if b then getCurrentSelection().moveUp(); else getCurrentSelection().moveDown(); setCurrentSelection(t); end function deleteThis();begin if getCurrentSelection()=RootItem then return; // t:=currentSelection.getsibling(-1)?:currentSelection.parent; getCurrentSelection().recycling(); if RootItem.ItemCount<1 then setCurrentSelection(nil,1); // setCurrentSelection(t); end function clear();begin clean(); // counter.reset(); setCurrentSelection(nil,1); end function setTreeviewFigureData(arr,n);begin lazyitems:=arr; // counter.reset(n); setCurrentSelection(nil,1); end property selectionChanged read fSelectionChanged write fSelectionChanged; property selectedNode read currentSelection; end function flushInfo(n);begin if n then begin Fedit0.text:=n.caption; Fedit1.text:=tostn(n.imgid); Fedit2.text:=tostn(n.selimgid); return; end Fedit0.text:=""; Fedit1.text:=""; Fedit2.text:=""; end function charProc(o,e)begin ac:=e.wparam; if ac=VK_RETURN then return 1; if not((ac>=48 and ac<58) or ac=VK_BACK or (not length(o.text) and ac=45)) then e.skip:=1; return 0; end function saveEditingNode(o,e);begin editingNode:=FtreeViewBox.selectedNode; end public function create(aOwner);override;begin inherited; caption:="TreeViewEditor"; left:=300; top:=300; FtreeViewBox:=new TreeViewEditorClass(self); FtreeViewBox.selectionChanged:=function(n)begin flushInfo(n); end FnewItemBtn:=new tbtn(self); FnewItemBtn.onclick:=function(o,e)begin FtreeViewBox.addNewItem(); end FnewSubItemBtn:=new tbtn(self); FnewSubItemBtn.onclick:=function(o,e)begin FtreeViewBox.addNewSubItem(); end FmoveUpBtn:=new tbtn(self); FmoveUpBtn.onclick:=function(o,e)begin FtreeViewBox.move(1); end FmoveDownBtn:=new tbtn(self); FmoveDownBtn.onclick:=function(o,e)begin FtreeViewBox.move(); end FdeleteBtn:=new tbtn(self); FdeleteBtn.onclick:=function(o,e)begin FtreeViewBox.deleteThis(); end FclearBtn:=new tbtn(self); FclearBtn.onclick:=function(o,e)begin FtreeViewBox.clear(); flushInfo(nil); end Fedit0:=new tedit(self); Fedit0.onSetFocus:=thisfunction(saveEditingNode); // Fedit0.onKillFocus:=function(o,e)begin // if editingNode then // editingNode.caption:=o.text; // end FEdit0.onkeypress:=function(o,e)begin if e.wparam=VK_RETURN then if editingNode then editingNode.caption:=o.text; end Fedit1:=new tedit(self); Fedit1.onSetFocus:=thisfunction(saveEditingNode); // Fedit1.onKillFocus:=function(o,e)begin // if editingNode then // editingNode.ImgId:=strtoint(o.text); // end FEdit1.onkeypress:=function(o,e)begin if call("charProc",o,e) then editingNode.ImgId:=strtoint(o.text); end // Fedit1.onkeypress:= thisfunction(charProc); Fedit2:=new tedit(self); Fedit2.onSetFocus:=thisfunction(saveEditingNode); // Fedit2.onKillFocus:=function(o,e)begin // echo "[KillFocus]\n"; // if editingNode then // editingNode.SelImgId:=strtoint(o.text); // end Fedit2.onkeypress:=function(o,e)begin if call("charProc",o,e) then editingNode.SelImgId:=strtoint(o.text); end // Fedit2.onkeypress:=thisfunction(charProc); Fokbtn:=new tbtn(self); Fokbtn.onclick:=function(o,e)begin calldatafunction(mok,o,e); _send_(WM_CLOSE,0,0); end Fcancelbtn:=new tbtn(self); Fcancelbtn.onclick:=function(o,e)begin _send_(WM_CLOSE,0,0); end Fstatictxt0:=new TLabel(self); Fstatictxt1:=new TLabel(self); Fstatictxt2:=new TLabel(self); height:=358;//经过计算的完美尺寸。 width:=570; wscaption := true; wssysmenu := true; wspopup := true; visible := false; end function initializewnd();override;begin inherited; setwindow(FtreeViewBox,24,24,216,280); setwindow(FnewItemBtn,270,24,112); FnewItemBtn.caption:="新建项"; setwindow(FnewSubItemBtn,270,73,112); FnewSubItemBtn.caption:="新建子项"; setwindow(FmoveUpBtn,270,122,112); FmoveUpBtn.caption:="选中项上移"; setwindow(FmoveDownBtn,270,171,112); FmoveDownBtn.caption:="选中项下移"; setwindow(FdeleteBtn,270,220,112); FdeleteBtn.caption:="删除选中项"; setwindow(FclearBtn,270,270,112); FclearBtn.caption:="删除所有项"; Fstatictxt0.caption:="name:"; setwindow(Fstatictxt0,400,24,128,20); setwindow(Fedit0,400,47,128); Fstatictxt1.caption:="imageid:"; setwindow(Fstatictxt1,400,78,128,20); setwindow(Fedit1,400,101,128); Fstatictxt2.caption:="selimageid:"; setwindow(Fstatictxt2,400,132,128,20); setwindow(Fedit2,400,155,128); Fokbtn.caption:="确定"; setwindow(Fokbtn,400,269,65); Fcancelbtn.caption:="取消"; setwindow(Fcancelbtn,475,269,65); end function WMCLOSE(o,e):WM_CLOSE;override; begin o.visible:=false; e.skip:=1; inherited; end function getlazyitems();begin n:=FtreeViewBox.lazyitems; // echo ">>Origin Lazyitems:",tostn(n); if ifnil(n) then return array("type":"treenodes"); return n; end function updateEditorData(arr,n);begin if ifnil(arr) then arr:=array("type":"treenodes"); //echo ">>UPDATENUM:",n,"\n"; FtreeViewBox.setTreeviewFigureData(arr,n); flushInfo(nil); end property ok read mok write mok; end function getnodenum(arr);begin r:=mrows(arr); for i:=0 to r-1 do if arr[i]["nodes"] then r+=getnodenum(arr[i]["nodes"]["items"]); return r; end public function create(AOwner);override;begin inherited; Fgrid:=aOwner; FeditWindow:=nil; end function CellClick(grid,e,d);override;begin Fi := e.iitem; Fj := e.isubitem; inherited; end function CellLeave(grid);override;begin if FeditWindow then _wapi.PostMessageA(FeditWindow.handle,WM_CLOSE,0,0); end function ButtonClick(grid,e,d);override;begin if ifnil(FeditWindow) then begin FeditWindow:=new tPopupEditorWindow(FGrid); FeditWindow.ok:=function(o,e)begin t := FeditWindow.getlazyitems(); Fgrid.CellChanged(Fi,Fj,"value",t); end end if ifnil(FeditWindow.parent) then begin FeditWindow.parent :=FGrid; end rec := grid.getSubItemRect(Fi,Fj); FeditWindow.updateEditorData(d["value"],ifnil(FnodeNum)?0:FnodeNum); FeditWindow.show(); end function CellDrawLabel(dc,rect,d);override; begin // FnodeNum:=getnodenum(d["value"]["items"]); // str:="itemstats:"+(ifnil(d["value"])?"0":inttostr(FnodeNum)); str:="itemstrings"; dc.drawtext(str,rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end type tGridCellAlignPosBoxEdit = class(TOneSelectCell,TPropertyAlign9) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyAlign9).Create(); end private function SelPalRange();virtual; begin return SelRange; end end //////////////////////多选list////////////////////////////// type TMultiSelList = class(TCustomControl) function Create(AOwner); begin inherited; FList := new TListBox(self); FList.Multisel := 2; //FList.Appenditems(array("a","b","c")); FList.setCurrentSelection(array(0,1)); FList.parent := self; FOkBtn := new TBTN(self); FBtnWidth := 80; FOkBtn.width := FBtnWidth; FOkBtn.caption := "确定"; FOkBtn.parent := self; FCanceBtn := new TBTN(self); FCanceBtn.width := FBtnWidth; FCanceBtn.caption := "取消"; FCanceBtn.parent := self; FCanceBtn.onclick := thisfunction(CancelClick); FOkBtn.onclick := thisfunction(okClick); end function GetSelectdata(); begin idx := FList.getSelectedIndexes(); r := array(); for i,v in idx do begin r[i] := Fdata[v,1]; end return r; end function SetSelectData(d); begin idxs := array(); for i,v in d do begin for j,vj in Fdata do begin if v=vj[1] then begin idxs[i] := j; break; end end end FList.setCurrentSelection(idxs); end function SetListData(d); begin if ifarray(d) then begin FList.SetData(d[:,0]); Fdata := d; end end function Recycling();override; begin fOnokclick := 0; FOnCancelclick := 0; Fdata := 0; FBtnWidth:=0; FList:=0; FOkBtn:=0; FCanceBtn:=0; end function DoControlAlign();override; begin if FList and FOkBtn AND FCanceBtn then begin r := ClientRect; h := FOkBtn.height; c := r; c[3]-=h+4; FList.SetBoundsRect(c); bt := r[3]-h-1; FOkBtn.Top := bt; FOkBtn.Left := r[2]-FBtnWidth-5; FCanceBtn.top := bt; FCanceBtn.Left := r[2]-FBtnWidth-FBtnWidth-10; end end function CancelClick(o,e); begin calldatafunction(FOnCancelclick,self(true),e); end function okClick(o,e); begin calldatafunction(fOnokclick,self(true),e); end property OnCancelclick read FOnCancelclick write FOnCancelclick; property Onokclick read FOnokclick write fOnokclick; private fOnokclick; FOnCancelclick; Fdata; FBtnWidth; FList; FOkBtn; FCanceBtn; end type TMultiSelectCell = class(TGridCellEditWithButton) FListSel; private FPanel; FI; FJ; FCellv; function GetSelPanel();virtual; begin if not FPanel then begin FPanel := new TMultiSelList(Owner); FPanel.OnCancelclick := function(o,e)begin o.visible := false; end FPanel.wspopup := true; FPanel.SetListData(SelPalRange()); FPanel.Onokclick := thisfunction(SelChanged); end end function SelPalRange();virtual; public function SelChanged(o,e); begin if fi>=0 and fj>=0 and ifarray(FCellv) then begin o.visible := false; v := o.GetSelectdata(); Owner.CellChanged(FI,FJ,"value",V); end end function create(AOwner);override; begin inherited; end function ButtonClick(grid,e,d);override; begin {** @explan(说明) 格子点击 %% **} inherited; fi := e.iitem; fj := e.isubitem; FCellv := array(); GetSelPanel(); rec := GetPopRectByHeight(160); rec[3] := rec[1]+160; FPanel.SetBoundsRect(rec); FPanel.SetSelectData(FListSel); FPanel.Show(); end function CellLeave(grid);override; begin {** @explan(说明) 离开编辑格子 %% **} if FPanel then FPanel.visible := false; end; end //************red**propery********************************** type TOneSelectCell = class(TGridCellEditWithButton) private FPanel; FI; FJ; FCellv; function GetSelPanel();virtual; begin if not FPanel then begin FPanel := new UniCheckList(Owner); FPanel.wspopup := true; FPanel.SetList(SelPalRange()); FPanel.OnSelChanged := thisfunction(SelChanged); end end function SelPalRange();virtual; public function SelChanged(o,v); begin if fi>=0 and fj>=0 and ifarray(FCellv) then begin o.visible := false; Owner.CellChanged(FI,FJ,"value",v); end end function create(AOwner);override; begin inherited; end function ButtonClick(grid,e,d);override; begin {** @explan(说明) 格子点击 %% **} inherited; fi := e.iitem; fj := e.isubitem; FCellv := array(); GetSelPanel(); rec := GetPopRectByHeight(160); rec[3] := rec[1]+160; FPanel.SetBoundsRect(rec); FPanel.Show(); end end type TGridCellAnchorsEdit = class(TMultiSelectCell,TPropertyAnchors) {** @explan(说明)设置align属性%% **} function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin FListSel := d["value"]; dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyAnchors).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type TGridCellAlignEdit = class(TOneSelectCell,TPropertyAlign) {** @explan(说明)设置align属性%% **} function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyAlign).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type TGridCellTabAlignEdit = class(TOneSelectCell,TPropertyTabAlign) {** @explan(说明)设置align属性%% **} function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyTabAlign).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type TtextEditor = class(tpanel) {** @explan(说明)memo编辑器%% **} protected btn1; btn2; function SetItemStr(v);virtual; begin memo.text := v; end function GetItemStr();virtual; begin memo.text; end public itemData; memo; function DoControlAlign();override; begin if btn1 and btn2 and memo then begin rc := ClientRect; rc2 := rc; rc2[3]-=38; memo.SetBoundsRect(rc2); btop := rc[3]-34; rt := rc[2]-5; btn2.top := btop; btn1.Top := btop; btn2.Left := rc2[0]+(rt-btn2.width); btn1.Left := rc2[0]+(rt-btn2.width*2-20); end end function create(AOwner);override; begin inherited; height := 400; width := 400; left := 500; top := 200; wspopup := true; wscaption := true; wssysmenu := true; caption := "text Editor Dialog"; memo := new tmemo(self); memo.OnKeyPress := thisfunction(MemoKeyPress); memo.parent :=self; btn1 := new tbtn(self); btn1.parent := self; btn2 := new tbtn(self); btn2.parent := self; btn1.caption := "取消"; btn2.caption := "确认"; btn1.onclick := thisfunction(cancelEdit); btn2.onclick := thisfunction(comfirmEdit); itemData:= ""; end function MemoKeyPress(o,e);virtual; begin end function textonumber(v);virtual; begin return v; end function comfirmEdit(o,e);virtual; begin itemData := memo.text; EndModalCode := 1; return EndModal(); end function WMClose(o,e):WM_CLOSE;override; begin memo.text := " "; e.skip := true; EndModalCode := 0; o.EndModal(); end function cancelEdit(o,e);virtual; begin //把memo上的数据清除,同时记录的数据设置到memo //关闭editor memo.text := " "; EndModalCode := 0; return EndModal(); end property ItemStr read GetItemStr write SetItemStr; end type TGridCellTextEdit = class(TGridCellEditWithButton,TPropertyText) {** @explan(说明)编辑字符串文本属性%% **} private isShow; FRbuttonWidth; screenbottom; protected Fowner; Fpanel; rowNum; colNum; Fgrid; public function create(AOwner);override; begin inherited; Fowner := AOwner; Fpanel := nil; FRbuttonWidth := 20; screenArr := _wapi.getscreenrect(); screenbottom := screenArr[3]; isShow := true; end function createEditObj();virtual; begin Fpanel := new TtextEditor(Fowner); end function ButtonClick(grid,e,d);override; begin {** @explan(说明) 格子点击 %% **} inherited; rowNum := e.iitem; colNum := e.isubitem; Fgrid := grid; pt := e.ptaction; rec := grid.getSubItemRect(rowNum,colNum); if pt[0]>=(rec[2]-FRbuttonWidth) then begin if ifnil(Fpanel) then begin createEditObj(); Fpanel.parent := Fowner; Fpanel.OnActivate := function(o,e) begin if e.lowparam = WA_INACTIVE then begin CellLeave(Fgrid); end end; end clickToText(d); if Fpanel.showmodal()=1 then begin textChange1(Fpanel.itemData); end end end function clickToText(d);virtual; begin if d["value"] <> " " then begin Fpanel.ItemStr := d["value"]; end end function CellName();virtual; begin return "text"; end function textChange1(data);virtual; begin Fgrid.CellChanged(rowNum,colNum,"value",data); end function CellDrawLabel(dc,rect,d);override; begin {** @explan(说明) 绘制格子 %% **} dc.drawtext(cellName(),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end type TGridCellStringsEdit = class(TGridCellTextEdit) {** @explan(说明)编辑字符串数组属性%% **} protected function createEditObj();override; begin Fpanel := new TstringsEditor(Fowner); end function clickToText(d);override; begin if length(d["value"]) = 0 then Fpanel.ItemStr := ""; else Fpanel.ItemStr := Array2Str(d["value"],"\r\n"); end function CellName();Override; begin return ""; end public function EditType();override; begin return "strings"; end function Create(AOwner); begin inherited; end end type TstringsEditor = class(TtextEditor) {** @explan(说明)memo编辑器%% **} protected function textonumber(v);override; begin return v; end function comfirmEdit(o,e);override; begin itemData := array(); linecount := memo.getlinecount(); if linecount > 0 then begin for i:= 1 to linecount do begin str := memo.getline(i); itemData[i-1] := textonumber(str); end end EndModalCode := 1; return EndModal(); end public function create(AOwner);override; begin inherited; caption := "Strings Editor Dialog"; end end type TGridCellIntegersEdit = class(TGridCellStringsEdit) {** @explan(说明)编辑整形数组属性%% **} protected function createEditObj();override; begin Fpanel := new TIntegersEditor(Fowner); end function CellName();override; begin return "integers"; end public function Create(AOwner);override; begin inherited; end function EditType();override; begin return "integers"; end end type TIntegersEditor = class(TstringsEditor) {** @explan(说明)memo编辑器%% **} protected function textonumber(txt);override; begin return strtointdef(txt,0); end function MemoKeyPress(o,e);override; begin if e.wparam = ord("-") then begin end else begin if not(e.wparam >= ord("0") and e.wparam<= ord("9") or e.wparam = VK_BACK or e.wparam = 13) then e.skip := true; end end public function create(AOwner);override; begin inherited; caption := "Integers Editor Dialog"; end end type TGridCellEsAlignEdit = class(TOneSelectCell,TPropertyEsAlign) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyEsAlign).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type TGridCellColorBoxEdit = class(TOneSelectCell,TPropertyColorList) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertyColorList).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type tGridCellMbbtnstyleEdit=class(TOneSelectCell,TPropertymbbtnstyle) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertymbbtnstyle).Create(); end private function SelPalRange();virtual; begin return SelRange; end end type tGridCellMbiconstyleEdit=class(TOneSelectCell,TPropertymbicostyle) function CellDrawLabel(dc,rect,d);override; begin if ifarray(d) then begin dc.drawtext(FormatTMF(d["value"]),rect,DT_VCENTER.|DT_LEFT .|DT_SINGLELINE); end end function create(AOwner);override; begin inherited; class(TPropertymbicostyle).Create(); end private function SelPalRange();virtual; begin return SelRange; end end //属性编辑表格 type TListEidter = class(TPanel) {** @explan(说明) list编辑器 %% **} private FListControl; FBadd; FBdelete; FBup; FBdown; FBAplay; FOnApplay; FListWidth; public function WMCLOSE(o,e):WM_CLOSE;override; begin e.skip := true; inherited; end function ListCheck(v);virtual; begin {** @explan(说明) 检查 list类型 %% @param(v)(TWincontrol) %% **} return v is class(TGridList); end function SetListControl(v); begin if ifnil(v) then begin if FListControl then begin FListControl.Recycling(); FListControl:= nil; end end if ifnil(FListControl) and (ListCheck(v)) and v.parent = self then begin FListControl := v; DoControlAlign(); end end function SetListWidth(v); begin if v>100 and v<> FListWidth then begin FListWidth := v; DoControlAlign(); end end function Buttons();virtual; begin {** @explan(说明) 右侧 按钮 %% **} return array(FBadd,FBdelete,FBup,FBdown,FBAplay); end function DoControlAlign();override; begin if not HandleAllocated() then exit; sz := clientrect; if FListControl and FListControl.parent = self then begin sz[2] := FListWidth; FListControl.SetBoundsRect(sz); BTS := Buttons(); y := 30; x := FListWidth+10; for i,v in BTS do begin if v and (v is class(tcontrol)) and (v.parent=self) and v.visible then begin v.left := x; v.top := y; y+=v.height+10; end end end end function create(AOwner);override; begin inherited; caption := "Imagelist Editer"; minmaxbox := false; left := 400; height := 600; width := 350; FListWidth:=250; WsCaption := true; WsPopUp := true; WsSysmenu := true; wsSizeBox := false; FBadd := new tbtn(self); FBup := new tbtn(self); FBdown := new tbtn(self); FBAplay := new tbtn(self); FBdelete := new tbtn(self); FBadd.caption := "添加"; FBup.caption := "上移"; FBdown.caption := "下移"; FBAplay.caption := "应用"; FBdelete.caption := "删除"; FBAplay.onclick := thisfunction(applay); FBadd.parent := self; FBup.parent := self; FBdown.parent := self; FBAplay.parent := self; FBadd.onclick := thisfunction(addclick); FBdelete.onclick := thisfunction(delselect); FBup.onclick := thisfunction(moveup); FBdown.onclick := thisfunction(movedown); for i,v in Buttons() do begin if (v is class(tcontrol)) and v.visible then v.parent := self; end end function moveup(o,e);virtual; begin if FListControl then FListControl.moveup(); end function movedown(o,e);virtual; begin if FListControl then FListControl.movedown(); end function delselect(o,e);virtual; begin if FListControl then FListControl.deleteselect(); end function addclick(o,e);virtual; begin end function applay(o,e);virtual; begin calldatafunction(OnApplay,self(true)); end property ListWidth read FListWidth write SetListWidth; property OnApplay read FOnApplay write FOnApplay; property ListControl read FListControl write SetListControl; {** @param(OnApplay)(function[TListEidter]) 应用按钮回调 %% **} end //*************设计器********************************* type TBitmapGrid = class(TGridList) {** @explan(说明) imagelist编辑 %% **} public function CheckItem(v);override; begin return (v is class(TcustomBitmap)) and inherited; end function create(AOwner);override; begin inherited; cls := array(( "text":"id", "width":30 ), ( "text":"bmp", "width":60 ), ( "text":"size", "width":100 )); Columns := cls; end function CNMEASUREITEM(O,E):CN_MEASUREITEM;override; begin e.height := 40; end function DoDrawSubItem(o,e);override; begin dc := e.canvas; if not dc.Handle then exit; i := e.itemid; j := e.subitemid; src := e.subItemRect; it := List[i]; if not it then exit; if j = 0 then begin return inherited; end else if j = 1 and it.HandleAllocated() then begin src[2] := src[0]+40; dc.StretchDraw(src,it); end else if j = 2 then begin if it.HandleAllocated() then begin dc.DrawText(format("%d*%d",it.bmwidth, it.bmheight),src,DT_VCENTER .| DT_SINGLELINE); end end end end type tnone = class() function create(); begin name := "(none)"; end name; end type TListStatusbarItem = class(TGridList) public FCheckNumber; function create(AOwner);override; begin inherited; Columns := array( ("text":"id","width":40), ("text":"width","width":60) ,("text":"text","width":100) ); end function CheckItem(v);override; begin if FCheckNumber then r := ifarray(v) and (v["width"]>0) and ifstring(v["text"]); else r := true; return r; end function MouseUp(o,e);override; begin inherited; y := GetRowIndexByPos(e.ypos); if y<0 then begin UnSelected(); CallDataFunction(self.SelectedChanged,self,e); end end function DoDrawSubItem(o,e);override; begin {** @explan(说明) 绘制子项 %% **} dc := e.canvas; if not dc.Handle then exit; j := e.subitemid; if j = 0 then begin return inherited; end else begin i := e.itemid; src := e.subItemRect; di := list[i]; if j=1 then begin wd := di["width"]; if ifstring(wd) then begin di := wd; end else di := tostn(wd); end else di := di["text"]; dc.DrawText(di,src,DT_VCENTER .| DT_SINGLELINE); end end end type TListStatusEdit = class(TListEidter) {** @explan(说明) 函数编辑器 %% **} private FEDITS; e1; e3; ed; e2; e4; public FCheckNumber; function clean(); begin if ListControl then ListControl.clean(); end function setitems(v); begin if not ListControl then exit; ListControl.clean(); ListControl.additems(v); end function Buttons();override; begin if FEDITS then return FEDITS union inherited; return inherited; end function addclick(o,e);virtual; begin if not ListControl then exit; v1 := FEDITS[1].text; FCurrentIndx := -1; if FCheckNumber then begin ListControl.FCheckNumber := true; v1 := StrToIntDef( v1,0) ; if not(v1>0) then begin return _wapi.MessageBoxA(self.Handle,"宽度错误!","错误",0); end end else ListControl.FCheckNumber := false; v2 := FEDITS[3].text ; FEDITS[1].text := ""; FEDITS[3].text := ""; ListControl.additem(array("width":v1,"text":v2)); end function Create(AOwner);override; begin inherited; caption := "statusbar 编辑器"; top := 300; height := 400; width := 430; FCheckNumber := true; ed := new TListStatusbarItem(self); e1 := new TGraphicControl(self); e1.caption := "宽度:"; e2 := new TEdit(self); e2.Width := 150; e3 := new TGraphicControl(self); e3.caption := "文本:"; e4 := new Tedit(self); e4.Width := 150; FEDITS := array(e1,e2,e3,e4); for i,v in FEDITS do v.parent := self; ed.parent := self; ListControl := ed; ListControl.SelectedChanged := thisfunction(onlistchanged); e2.OnChange := thisfunction(EditChanged); e4.OnChange := thisfunction(EditChanged); end function EditChanged(o,e); begin if not(FCurrentIndx>=0) then return ; if o=e4 then begin ListControl.SetsubItem(FCurrentIndx,"text", formatText1(O.text)); end else if o= e2 then begin ListControl.SetsubItem(FCurrentIndx,"width",formatText2(o.text)); end end function formatText1(txt);virtual; begin return txt; end function formatText2(txt);virtual; begin return strtointdef(txt,100); end function onEditClick(o,e);virtual; begin if not ListControl then exit; end function onlistchanged(o,e); begin v := o.SelectedValue; if ifarray(v) and v then begin FCurrentIndx := -1; e2.text := ifstring(v["width"])?v["width"]:tostn(v["width"]); e4.text :=v["text"]; FCurrentIndx := o.SelectedId; end else begin FCurrentIndx := -1; end end function SetColoumn(i,v); begin ed.SetColumnText(i,v); end function SetLable(id,v); begin if id =0 then begin e1.caption := v; end else e3.caption := v; end FCurrentIndx; end type TListStatusEdit2 = class(TListStatusEdit) function Create(AOwner); begin inherited; end function formatText2(txt);override; begin return txt; end end type TIconsEditer = class(TListEidter) private FFileopen; FIcons; FImage; public function clean(); begin if not ListControl then exit; ListControl.clean(); end function Create(AOwner);override; begin inherited; top := 400; left := 300; height := 400; ListWidth := 230; FFileopen := new TOpenFileADlg(self); FFileopen.wndowner := self; FFileopen.filter := array("all":"*.bmp;*.ico;*.png;*.jpg;*.jpeg","bmp":"*.bmp","ico":"*.ico","png":"*.png");; list := New TBitmapGrid(self); List.parent := self; List.border := true; ListControl := list; FImage := new timage(); end function addclick(o,e);override; begin if not ListControl then exit; if FFileopen.ChooseDlg() then begin fn := FFileopen.FileName; r := FImage.LoadFromFile(fn); if r=0 then begin ico := new tbitmap(); ico.handle := FImage.ToHBitmap; ListControl.additem(ico); end else _wapi.MessageBoxA(self.Handle,"打开文件失败","类型错误",0); end end function seticons(icons); begin //if FIcons=icons then exit; FIcons := icons; ListControl.clean(); for i,v in icons do begin ListControl.additem(v); end end function GetIcons(); begin r := ListControl.ListValues; return r; end function showmodal();override; begin inherited; return 1; end function applay(o,e);override; begin WMCLOSE(self,e); end function WMCLOSE(o,e):WM_CLOSE;override; begin e.skip := true; o.visible := false; o.EndModal(); end end function registereditpropertytodesigner(cls); begin {** @explan(说明) 注册编辑属性 %% @param(cls)(TDComponent) 设计控件 %% **} if ifarray(cls) then return registerproperties(cls); return registerproperties(array(cls)); end function registerproperties(ps); begin o := class(TPropGrid); for i,v in ps do begin it := createobject( v,0); o.RegCellRender(it); end end function staticinit(); begin psi := (array( class(TGridCellBoolEdit), class(TGridCellColorEdit), class(TGridCellDirectoryEdit), class(TGridCellFileNameEdit), class(TGridCellNaturalEdit), class(TGridCellIntegerEdit), class(TGridCellLazyIntegerEdit), class(TGridCellLazystrEdit), class(TGridCellStringEdit), class(TGridCellEventHandleEdit), class(TGridCellVariableEdit), class(TGridCellVariableTactionEdit), class(TGridCellVariableTrayEdit), class(TGridCellVariabletimagelistEdit), class(TGridCellVariablehgtEdit), class(TGridCellVariabletmainmenuEdit), class(TGridCellVariabletpopupmenuEdit), class(TGridCellImagesEdit), class(TGridCellBitmapEdit), class(TGridCellIconEdit), class(TGridCellFontEdit), class(TGridCellhotkeyEdit), class(TGridCellSysCursorEidt), class(TGridCellStatusItemsEdit), class(TGridCellFileFilterEdit), class(TGridCellEsAlignEdit), class(TGridCellTextEdit), class(TGridCellAlignEdit), class(TGridCellAnchorsEdit), class(TGridCellTabAlignEdit), class(TGridCellStringsEdit), class(TGridCellIntegersEdit), class(TGridCellColorBoxEdit), class(tGridCellMbbtnstyleEdit), class(tGridCellMbiconstyleEdit), class(tGridCellDayOfWeekBoxEdit), class(TGridCellPairIntEdit), class(TGridCellPairSpliterTypeEdit), class(tGridCellAlignPosBoxEdit), class(TGridCellTreeViewDataEdit) )); registerproperties(psi); end initialization staticinit(); end.