unit utslvclpage; interface uses utslvclauxiliary,utslvclbase,utslvclgdi; type t_custom_tab_ctl = class(TCustomControl) private fclocker;//锁 FirstViewIndex; //第一个展示的序号 FCurrentid; //当前 FPrevid; //上一个 FTabItems; // [weakref]FOnSelChanged; [weakref]FOnSelChanging; //正在改变 //FOnrclick; FTabPosition; FTabHeight; FTabItemswidth; FScrollBtnRect; Fprevrect; fnextrect; FTabRects; FClientarea; private function SetTabPosition(v); begin if FTabPosition=v then exit; if not(v in array(alTop,alBottom,alLeft,alRight)) then exit; FTabPosition := v; DoControlAlign(); InvalidateRect(nil,false); end function CalcTabs(); //计算区域 begin rec := ClientRect; //区域 FTabItemswidth := array(); for i := 0 to FTabItems.length()-1 do begin wd := FTabItems[i].width; FTabItemswidth[i] := wd; end FMaxsize := 0; if FTabPosition in array(alLeft,alRight) then begin FTabItemswidth := zeros(length(FTabItemswidth))+maxvalue(FTabItemswidth); FMaxsize := length(FTabItemswidth)*FTabHeight; end else begin FMaxsize := sum(FTabItemswidth); end FClientarea := rec; FScrollBtnRect := 0; Fprevrect := 0; fnextrect := 0; FTabRects := array(); case FTabPosition of alLeft: begin if FTabItemswidth then begin FClientarea[0] :=rec[0]+FTabItemswidth[0]; if length(FTabItemswidth)>1 and (FMaxsize>(rec[3]-rec[1])) then begin FScrollBtnRect := array(rec[0],rec[3]-FTabHeight*2,rec[0]+FTabItemswidth[0],rec[3]); Fprevrect := array(rec[0],rec[3]-FTabHeight*2,rec[0]+FTabItemswidth[0],rec[3]-FTabHeight); Fnextrect := array(rec[0],rec[3]-FTabHeight,rec[0]+FTabItemswidth[0],rec[3]); end else begin FirstViewIndex := 0; end ybase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(0,ybase,FTabItemswidth[0],ybase+FTabHeight); ybase+=FTabHeight; if ybase>(rec[3]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end alRight: begin if FTabItemswidth then begin FClientarea[2] :=rec[2]-FTabItemswidth[0]; if length(FTabItemswidth)>1 and (FMaxsize>(rec[3]-rec[1])) then begin FScrollBtnRect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight*2,rec[2],rec[3]); Fprevrect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight*2,rec[2],rec[3]-FTabHeight); Fnextrect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight,rec[2],rec[3]); end else FirstViewIndex := 0; ybase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(rec[2]-FTabItemswidth[0],ybase,rec[2],ybase+FTabHeight); ybase+=FTabHeight; if ybase>(rec[3]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end alTop: begin if FTabItemswidth then begin FClientarea[1] :=rec[1]+FTabHeight; if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0])) then begin FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[1],rec[2],rec[1]+FTabHeight); Fnextrect := array(rec[2]-FTabHeight,rec[1],rec[2],rec[1]+FTabHeight); Fprevrect := array(rec[2]-FTabHeight*2,rec[1],rec[2]-FTabHeight,rec[1]+FTabHeight); end else FirstViewIndex := 0; xbase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(xbase,0,xbase+FTabItemswidth[i],FTabHeight); xbase+=FTabItemswidth[i]; if xbase>(rec[2]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end alBottom: begin if FTabItemswidth then begin FClientarea[3] :=rec[3]-FTabHeight; if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0])) then begin FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[3]-FTabHeight,rec[2],rec[3]); Fnextrect := array(rec[2]-FTabHeight,rec[3]-FTabHeight,rec[2],rec[3]); Fprevrect := array(rec[2]-FTabHeight*2,rec[3]-FTabHeight,rec[2]-FTabHeight,rec[3]); end else FirstViewIndex := 0; xbase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(xbase,rec[3]-FTabHeight,xbase+FTabItemswidth[i],rec[3]); xbase+=FTabItemswidth[i]; if xbase>(rec[2]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end end end function InsureIdxVisible(id); //确保可见 begin if not(id>=0 and idFirstViewIndex then begin FirstViewIndex++; end else begin FirstViewIndex--; end CalcTabs(); end end function setselidx(id); //选择序号 begin if FCurrentid= id then return ; if fclocker.locked then return ; lk := new tcountlocker(fclocker); if id>=0 and id-1 and fOnSelChanging then begin e := new tuieventbase(0,FCurrentid,id,0); //m,w,l,h doonSelChanging(self(true),e); if e.skip then return ; end FPrevid := FCurrentid; FCurrentid := id; InsureIdxVisible(id); InvalidateRect(nil,false); if FOnSelChanged then begin doonSelChange(self(true),new tuieventbase(0,FPrevid,FCurrentid,0)); end end else if FTabItems.length()=0 then begin FPrevid := -1; FCurrentid := -1; end end function PaintTabs();//绘制tab begin lk := new tcountlocker(fclocker); dc := Canvas; dc.font := font; ar := 0->(FTabItems.length()-1); if FTabRects[FCurrentid] then begin ar[FCurrentid] := -100; ar[length(ar)] := FCurrentid; end for ii,i in ar do begin rec := FTabRects[i]; if rec then begin if fownerdraw and fondrawtab then begin e := new teventdrawtab(i,(FCurrentid=i),rec,dc); CallMessgeFunction(fondrawtab,self(true),e); continue; end dc.pen.color := 13158600;//rgb(200,200,200); if FCurrentid=i then begin dc.brush.color := 0xf0f0f0;//rgb(100,192,250);//rgb(230,240,250);//rgb(200,200,200); end else dc.brush.color := 16711422;//rgb(254,254,254); dc.draw("roundrect",array(rec[0:1],rec[2:3],array(2,2))); rec[1]+=2; it := FTabItems[i]; dc.drawtext(it.caption,rec,DT_CENTER .|DT_VCENTER); end end end function PaintScroll(); //绘制滚动 begin dc := Canvas; if FScrollBtnRect then begin case FTabPosition of alTop,alBottom: begin rc1 := array(FScrollBtnRect[0:1]+1,(FScrollBtnRect[0]+FTabHeight-1,FScrollBtnRect[3]-1)); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLLEFT); rc1 := array((FScrollBtnRect[0]+FTabHeight+1,FScrollBtnRect[1]+1),FScrollBtnRect[2:3]-1); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLRIGHT); end else begin rc1 := array(FScrollBtnRect[0:1]+1,(FScrollBtnRect[2]-1,FScrollBtnRect[3]-FTabHeight-1)); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLUP); rc1 := array((FScrollBtnRect[0]+1,FScrollBtnRect[3]-FTabHeight+1),FScrollBtnRect[2:3]-1); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLDOWN); end end end end function ScrollPrev(); //滚动到下一个 begin if FScrollBtnRect and FirstViewIndex>0 then begin FirstViewIndex-- ; CalcTabs(); InvalidateRect(nil,false); end end function scrollnext(); //滚动到上一个 begin if FScrollBtnRect and FirstViewIndex=0 and idx<=len) then begin nidx := len; end else nidx := idx; n := length(nitem); if FCurrentid >=idx then FCurrentid+=n; FTabItems.splices(nidx,0,nitem); lk := new tcountlocker(fclocker); for i:= nidx to nidx+n do measureidx(i); CalcTabs(); InvalidateRect(nil,false); end function deltab(idx,n); virtual;//删除 begin len := FTabItems.length()-1; if not( n>0) then n := 1; nidx := idx; if not(idx>=0 and idx<=len) then begin return 0; end if not(idx>=0 and idx<=len) then begin nidx := len; end else nidx := idx; FTabItems.splice(nidx,n); CalcTabs(); if FCurrentid >(idx+n-1) then begin FCurrentid -=n; InvalidateRect(nil,false); end else if FCurrentid>=idx and FCurrentid<(idx+n-1) then begin FCurrentid := -1; setselidx( max(0,idx-1)); end end function DesigningClick();override; begin return true; end function create(aowner); begin inherited; fownerdraw := 0; tabheight := 25; end function AfterConstruction();override; begin inherited; fclocker := new tcountkernel(); color := 0xffffff; height := 200; width := 200; left := 10; top := 10; FTabPosition := alTop; FirstViewIndex := 0; FCurrentid := -1; FPrevid := -1; FTabItems := new tnumindexarray(); end Function SetCurSel(id); //设置当前序号 begin if ifnumber(id) and id>=0 then begin iid := integer(id); setselidx(iid); end end function paint();override; //绘制 begin PaintTabs(); PaintScroll(); end function MouseUp(o,e);override;//鼠标弹起 begin if csDesigning in ComponentState then return; if e.skip then return ; ps := e.pos(); mb := e.button(); if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,fnextrect) then begin if e.Button() = mbLeft then ScrollNext(); return ; end else if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,Fprevrect) then begin if e.Button() = mbLeft then scrollprev(); return ; end if not FTabRects then return ; for i := 0 to length( FTabRects)-1 do begin v := FTabRects[i]; if v and pointinrect(ps,v) then begin setselidx(i); if Onclick and (mb = mbLeft) then begin CallMessgeFunction(Onclick,o,e); end else if onrclick and (mb = mbRight) then begin CallMessgeFunction(onrclick,o,e); end return ; end // end end function doonSelChange(o,e);virtual; begin CallMessgeFunction(FOnSelChanged,o,e); end function doonSelChanging(o,e);virtual; begin CallMessgeFunction(fOnSelChanging,o,e); end function TabRect(AIndex: Integer); //获取区域 begin r := FTabRects[AIndex]; if r then return r; return array(0,0,0,0); end function DoControlAlign();override;//调整位置 begin CalcTabs(); end function gettabbyidx(idx); begin return FTabItems[idx]; end {** @param(tabindex)(integer) 当前选中序号 %% @param(tabsheet)(tcustomtabsheet) 通过下标获得页面 %% @param(TabCount)(integer) page数量 %% @param(OnSelChange)(function[tcustompagecontrol,tuieventbase]) 标签已经切换 %% @param(OnSelChanging)(function[tcustompagecontrol,tuieventbase]) 标签正在切换 %% **} published property tabs:strings read gettabs write settabs; property tabindex:lazyinteger read FCurrentid write SetCurSel; property OnSelChanged:eventhandler read FOnSelChanged write FOnSelChanged; property OnSelChanging:eventhandler read FOnSelChanging write FOnSelChanging; property ondrawtab:eventhandler read Fondrawtab write fondrawtab; property ownerdraw:bool read fownerdraw write fownerdraw; property onmeasuretabwidth:eventhandler read fonmeasuretabwidth write fonmeasuretabwidth; property tabcount:integer read gettabcount ; property tabheight:integer read ftabheight write settabheight; property TabPosition read FTabPosition write SetTabPosition; property tabwidth read gettabwidth write settabwidth; private function gettabs(); begin r := array(); for i := 0 to FTabItems.length()-1 do begin r[i] := FTabItems[i].caption; end return r; end function gettabcount(); begin return ftabitems.length(); end function settabwidth(idx,w); begin if idx>0 and idx=0 and ftabitems[idx].width<>w then begin ftabitems[idx].width := w; end end function gettabwidth(idx); begin tb := ftabitems[idx]; if tb then return tb.width; return nil; end function settabheight(h); begin if h>0 and h<>FTabHeight then begin ftabheight := h; CalcTabs(); end end function settabs(tbs); begin if not ifarray(tbs) then return 0; if tbs=gettabs() then return 0; mtabitems := new tnumindexarray(); ftw := font.width; for i,v in tbs do begin if not ifstring(v) then return 0; it := new t_tab_item(v); it.width := ftw*length(v)+10; mtabitems.Push(it); end FTabItems := mtabitems; FirstViewIndex := 0; FCurrentid := -1; FPrevid := -1; lk := new tcountlocker(fclocker); for i :=0 to n-1 do begin measureidx(i); end CalcTabs(); InvalidateRect(nil,false); end function measureidx(i);//测量 begin if onmeasuretabwidth then begin e := new tuieventbase(0,0,i,0); CallMessgeFunction(onmeasuretabwidth,e); //wparam 为序号 if e.lparam>=0 then begin FTabItems[i].width := e.lparam; end end end private fownerdraw; [weakref]fondrawtab; [weakref]fonmeasuretabwidth; end type tcustomtabsheet = class(TCustomControl) //控件页面 {** @explan(说明)page控件页面 %% **} private FImageIndex; protected function RealSetText(s);override; begin inherited; p := parent; if ifstring(s) and p and (p is class(tcustompagecontrol)) then begin id := p.GetPageID(self(true)); p.SetTabText(id,s); end end public function paint();override; //设计器模式下绘制网格 begin drawdesigninggrid(); end function DesigningMove();override;//移动 begin return false; end function DesigningSizer();override;//调整大小 begin return false; end function create(AOwner);override; begin inherited; WsDlgModalFrame := true; //p.exstyle := 0x101; Caption := "tab"; Visible := false; end end type tcustompagecontrol = class(TCustomControl) private fclocker;//锁 FirstViewIndex; //第一个展示的序号 FCurrentid; //当前 FPrevid; //上一个 FTabItems; // [weakref]FOnSelChanged; [weakref]FOnSelChanging; //正在改变 //FOnrclick; FTabPosition; FTabHeight; FTabItemswidth; FScrollBtnRect; Fprevrect; fnextrect; FTabRects; FClientarea; private function gettabesheet(idx); begin if idx>=0 then return FTabItems[idx]; end function getactivetabsheet(); begin id := FCurrentid; if id>=0 then return FTabItems[id]; end function SetTabPosition(v); begin if FTabPosition=v then exit; if not(v in array(alTop,alBottom,alLeft,alRight)) then exit; FTabPosition := v; DoControlAlign(); InvalidateRect(nil,false); end function GetTabCount(); begin return FTabItems.length(); end function CreateTableItem(cp); begin r := new tcustomtabitem(); r.caption := cp; return r; end function CalcTabs(); //计算区域 begin rec := ClientRect; //区域 ft := font; fw := ft.width; fh := ft.height; FTabHeight := fh+7; FTabItemswidth := array(); for i := 0 to FTabItems.length()-1 do begin pg := FTabItems[i]; ta := pg.Caption; FTabItemswidth[i] := max(20, length(ta)*fw+10 ); end FMaxsize := 0; if FTabPosition in array(alLeft,alRight) then begin FTabItemswidth := zeros(length(FTabItemswidth))+maxvalue(FTabItemswidth); FMaxsize := length(FTabItemswidth)*FTabHeight; end else begin FMaxsize := sum(FTabItemswidth); end FClientarea := rec; FScrollBtnRect := 0; Fprevrect := 0; fnextrect := 0; FTabRects := array(); case FTabPosition of alLeft: begin if FTabItemswidth then begin FClientarea[0] :=rec[0]+FTabItemswidth[0]; if length(FTabItemswidth)>1 and (FMaxsize>(rec[3]-rec[1])) then begin FScrollBtnRect := array(rec[0],rec[3]-FTabHeight*2,rec[0]+FTabItemswidth[0],rec[3]); Fprevrect := array(rec[0],rec[3]-FTabHeight*2,rec[0]+FTabItemswidth[0],rec[3]-FTabHeight); Fnextrect := array(rec[0],rec[3]-FTabHeight,rec[0]+FTabItemswidth[0],rec[3]); end else begin FirstViewIndex := 0; end ybase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(0,ybase,FTabItemswidth[0],ybase+FTabHeight); ybase+=FTabHeight; if xbase>(rec[3]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end alRight: begin if FTabItemswidth then begin FClientarea[2] :=rec[2]-FTabItemswidth[0]; if length(FTabItemswidth)>1 and (FMaxsize>(rec[3]-rec[1])) then begin FScrollBtnRect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight*2,rec[2],rec[3]); Fprevrect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight*2,rec[2],rec[3]-FTabHeight); Fnextrect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight,rec[2],rec[3]); end else FirstViewIndex := 0; ybase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(rec[2]-FTabItemswidth[0],ybase,rec[2],ybase+FTabHeight); ybase+=FTabHeight; if xbase>(rec[3]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end alTop: begin if FTabItemswidth then begin FClientarea[1] :=rec[1]+FTabHeight; if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0])) then begin FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[1],rec[2],rec[1]+FTabHeight); Fnextrect := array(rec[2]-FTabHeight,rec[1],rec[2],rec[1]+FTabHeight); Fprevrect := array(rec[2]-FTabHeight*2,rec[1],rec[2]-FTabHeight,rec[1]+FTabHeight); end else FirstViewIndex := 0; xbase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(xbase,0,xbase+FTabItemswidth[i],FTabHeight); xbase+=FTabItemswidth[i]; if xbase>(rec[2]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end alBottom: begin if FTabItemswidth then begin FClientarea[3] :=rec[3]-FTabHeight; if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0])) then begin FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[3]-FTabHeight,rec[2],rec[3]); Fnextrect := array(rec[2]-FTabHeight,rec[3]-FTabHeight,rec[2],rec[3]); Fprevrect := array(rec[2]-FTabHeight*2,rec[3]-FTabHeight,rec[2]-FTabHeight,rec[3]); end else FirstViewIndex := 0; xbase := 0; for i,v in FTabItemswidth do begin if i>=FirstViewIndex then begin FTabRects[i] := array(xbase,rec[3]-FTabHeight,xbase+FTabItemswidth[i],rec[3]); xbase+=FTabItemswidth[i]; if xbase>(rec[2]-FTabHeight-FTabHeight) then break; end else FTabRects[i] := nil; end end end end end function InsureIdxVisible(id); //确保可见 begin if FScrollBtnRect and (not FTabRects[id]) then begin tl := (FTabItems.length()-1); if id>FirstViewIndex then begin while(not FTabRects[min(id+1,tl)]) do begin FirstViewIndex++; CalcTabs(); end end else if id=0 and id-1 and fOnSelChanging then begin e := new tuieventbase(0,FCurrentid,id,0); //m,w,l,h doonSelChanging(self(true),e); if e.skip then return ; end FPrevid := FCurrentid; FCurrentid := id; InsureIdxVisible(id); InvalidateRect(nil,false); DoControlAlign(); if FOnSelChanged then begin doonSelChange(self(true),new tuieventbase(0,FPrevid,FCurrentid,0)); end end else if FTabItems.length()=0 then begin FPrevid := -1; FCurrentid := -1; end end function PaintTabs();//绘制tab begin dc := Canvas; dc.font := font; for i := 0 to FTabItems.length()-1 do begin rec := FTabRects[i]; dc.pen.color := 13158600;//rgb(200,200,200); if rec then begin if FCurrentid=i then begin dc.brush.color := 0xf0f0f0;//rgb(100,192,250);//rgb(230,240,250);//rgb(200,200,200); end else dc.brush.color := 16711422;//rgb(254,254,254); dc.draw("roundrect",array(rec[0:1],rec[2:3],array(2,2))); //dc.draw("rectangle",array(rec[0:1],rec[2:3],array(5,5))); rec[1]+=2; dc.drawtext(FTabItems[i].Caption,rec,DT_CENTER .|DT_VCENTER); end end end function PaintScroll(); //绘制滚动 begin dc := Canvas; if FScrollBtnRect then begin case FTabPosition of alTop,alBottom: begin rc1 := array(FScrollBtnRect[0:1]+1,(FScrollBtnRect[0]+FTabHeight-1,FScrollBtnRect[3]-1)); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLLEFT); rc1 := array((FScrollBtnRect[0]+FTabHeight+1,FScrollBtnRect[1]+1),FScrollBtnRect[2:3]-1); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLRIGHT); end else begin rc1 := array(FScrollBtnRect[0:1]+1,(FScrollBtnRect[2]-1,FScrollBtnRect[3]-FTabHeight-1)); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLUP); rc1 := array((FScrollBtnRect[0]+1,FScrollBtnRect[3]-FTabHeight+1),FScrollBtnRect[2:3]-1); dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLDOWN); end end end end function ScrollPrev(); //滚动到下一个 begin if FScrollBtnRect and FirstViewIndex>0 then begin FirstViewIndex-- ; CalcTabs(); InvalidateRect(nil,false); end end function scrollnext(); //滚动到上一个 begin if FScrollBtnRect and FirstViewIndex=0) then return ; FTabItems.splice(id,1); if id = FCurrentid then begin if id = 0 then begin if FTabItems.length()=0 then begin FCurrentid := -1; FPrevid := -1; end end FCurrentid := -1; FPrevid := -1; cid := min(max(0,id-1),FTabItems.length()-1); if cid >=0 then begin return setselidx(cid); end else begin if FOnSelChanged then begin doonSelChange(self(true),new tuieventbase(0,-1,-1,0)); end end end else if id1 then begin if page then begin page.visible := false; end end it.PageSheet := Page; if FCurrentid=-1 then begin setselidx(0); end end public function FontChanged(o);override; begin inherited; DoControlAlign(); end function getsheetrect(); //获得sheet begin {** @explan(说明) 获得sheet可视区域 %% @return(array) array(左,上,右,下) %% **} if not FClientarea then CalcTabs(); return FClientarea; end function DesigningClick();override; begin return true; end function create(aowner); begin inherited; end function AfterConstruction();override; begin inherited; fclocker := new tcountkernel(); color := 0xffffff; height := 200; width := 200; left := 10; top := 10; FTabPosition := alTop; FirstViewIndex := 0; FCurrentid := -1; FPrevid := -1; FTabItems := new tnumindexarray(); end function ControlAppended(AControl);override; begin if not(AControl is class(tcustomtabsheet)) then return; addtabitem(AControl); end function ControlDeleted(AControl);override; begin if not(AControl is class(tcustomtabsheet)) then return; id := GetPageID(AControl); RemovePageTab(id); //fcoolbands.deleteitem(AControl,true); end Function SetCurSel(id); //设置当前序号 begin if id is class(tcustomtabsheet) then begin return SetCurSel(GetPageID(id)); end if ifnumber(id) and id>=0 then begin iid := integer(id); setselidx(iid); end end function paint();override; //绘制 begin PaintTabs(); PaintScroll(); end function MouseUp(o,e);override;//鼠标弹起 begin ps := e.pos(); mb := e.button(); //if mb=mbRight then return ; if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,fnextrect) then begin if e.Button() = mbLeft then ScrollNext(); return ; end else if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,Fprevrect) then begin if e.Button() = mbLeft then scrollprev(); return ; end if not FTabRects then return ; for i := 0 to length( FTabRects)-1 do begin v := FTabRects[i]; if v and pointinrect(ps,v) then begin setselidx(i); if Onclick and (mb = mbLeft) then begin CallMessgeFunction(Onclick,o,e); end else if onrclick and (mb = mbRight) then begin CallMessgeFunction(onrclick,o,e); end return ; end // end end function doonSelChange(o,e);virtual; begin CallMessgeFunction(FOnSelChanged,o,e); end function doonSelChanging(o,e);virtual; begin CallMessgeFunction(fOnSelChanging,o,e); end function TabRect(AIndex: Integer); //获取区域 begin r := FTabRects[AIndex]; if r then return r; return array(0,0,0,0); end function GetTabText(AIndex);//获得caption begin r := ""; if AIndex0 then return FTabItems[AIndex].Caption; return r; end function GetPageID(page);//获得page序号 begin {** @explan(说明)获取page的序号 %% **} r := -1; if page is class(tcustomtabsheet) then begin for it := 0 to FTabItems.length()-1 do begin if FTabItems[it].PageSheet = page then begin return it; end end end return r; end function DoControlAlign();override;//调整位置 begin CalcTabs(); for i := 0 to FTabItems.length()-1 do begin it := FTabItems[i]; pg := it.PageSheet; if it and pg then begin if i=FCurrentid then begin pg.Visible := true; rc := getsheetrect(); if not rc then return ; rc[1]+=1; if csDesigning in ComponentState then begin rc[0]+=2; rc[2]-=2; rc[3]-=2; end pg.SetBoundsrect(rc); end else pg.Visible := false; end end end function SetTabText(i,Value); begin {** @explan(说明)修改tab标签文字 %% @param(i)(integer)序号 %%; @param(Value)(string)文本 %%; **} it := FTabItems[i]; if it and value<>it.caption then begin it.Caption := Value; DoControlAlign(); InvalidateRect(nil,false); end end function SetTabIndex(AIndex,AIndexnew); begin {** @explan(说明) 修改标签的次序 %% @param(AIndex)(integer) 位置 %% @param(AIndexnew)(integer) 新位置 %% **} if (AIndex<>AIndexnew) and (AIndex>=0) and (AIndex=0) and (AIndexnewFVisible then begin FVisible := v; end end function SetCaption(s);//设置标签 begin if ifstring(s) and s<>FCaption then begin FCaption := s; if PageSheet is class(tcustomtabsheet) then PageSheet.Caption := s; end end public function Create();//构造 begin FVisible:= true; FCaption := ""; end published property Caption read FCaption write SetCaption; property PageSheet read FPageSheet Write FPageSheet; end type teventdrawtab = class(tuieventbase) {** @explan(说明)单元格绘制消息对象 %% @param(idx)(integer) 行号 %% @param(sel)(integer) 是否选中 %% @param(rec)(array(左上右下)) 区域 %% @param(canvas)(TCanvas) 画布 %% **} function create(id,s,rc,cvs); begin inherited create(0,0,0,0); idx := id; sel := s; rec := rc; canvas := cvs; end idx; sel; rec; canvas; end type t_tab_item = class() function create(s); begin if ifstring(s) then caption := s; else caption := ""; end _Tag; caption; width; end initialization end.