unit UtslCodeEditor; { 编辑器相关的代码20220217修改 } interface uses cstructurelib,tslvcl,UTslmemo,UTslSynMemo; { 1. page标签 TPagees; TPageItem 2. TMemoPages ,TMemoPageItem 3. TEchoWnd 4. TFindResultWnd 5. FindStringWnd 查找框 5. TGotoLineWnd 跳转 } function tdbgcallback(); //调试回调 function gettslexe(); type TPageItem=class //标签项 function Create(AOwner); begin FCaption := ""; FOwner := AOwner; end function Recycling();virtual; begin FBitmapA := nil; FBitmapB := nil; Tag := nil; end published property Caption read FCaption write SetCaption; property BitmapA read FBitmapA write SetBitmapA; property BitmapB read FBitmapB write SetBitmapB; tag; Rect; protected function SetCaption(s); begin if s and ifstring(s)then begin FCaption := s; if FOwner then FOwner.ItemCaptionChenged(self); end end private function SetBitmapA(Bmp); begin if FBitmapA <> Bmp then begin FBitmapA := Bmp; if FOwner then FOwner.ItemBitmapAChenged(self); end end function SetBitmapB(Bmp); begin if FBitmapB <> Bmp then begin FBitmapB := Bmp; if FOwner then FOwner.ItemBitmapBChenged(self); end end FBitmapB; FBitmapA; FCaption; FOwner; end type TPage=class(TCustomControl) //标签 function Create(AOwner) begin Inherited; FCloseBtn := false; FPageItems := new TMyarrayB(); FMultiLine := 1; FLineHeight := 16; //font.Height+6; FLines := 0; FItemIndex :=-1; FWill_Drag := true; font := array("height":16,"width":8,"escapement":0,"orientation":0,"weight":400,"italic":0,"underline":0,"strikeout":0, "charset":0,"outprecision":0,"clipprecision":0,"quality":1,"pitchandfamily":1,"facename":"Courier New","color":0); end function GetPageRect(); //获得标签区域 begin GetClientRect(); return FPageRect; end function PosInCurrentItemSection(xy); //点击部分 begin if not FCurrentITem then return 0; rc := FCurrentItem.Rect; if not rc then return 0; rc1 := rc; rc1[2]:= rc1[0]+20; if PointInrect(xy,rc1)then return 1; rc1 := rc; rc1[0]:= rc[2]-20; if PointInrect(xy,rc1)then return 3; if PointInRect(xy,rc)then return 2; end function DoControlAlign();override; begin CalcPageItemRect(); end function CreateApageItem();virtual; begin return new TPageItem(self); end function itemcaptionchenged(it); begin if GetItemIndex(it)>= 0 then begin DoControlAlign(); InValidateRect(nil,false); end end function ItemBitmapAChenged(it); begin if GetItemIndex(it)>= 0 then InValidateRect(it.Rect,false); end function ItemBitmapBChenged(it); begin if GetItemIndex(it)>= 0 then InValidateRect(it.Rect,false); end function FontChanged();override; begin FLineHeight := font.Height+6; DoControlAlign(); end function IncPaintLock(); begin BeginUpdate(); end function DecPaintLock(); begin EndUpdate(); end function DoEndUpDate();override; begin DoControlAlign(); inherited; end function GetClientRect();override; begin r := inherited; FPageRect := R; r[1]+= FLineHeight * FLines; //FLabelsheight; FPageRect[3]:= r[1]; return r; end function Paint();override; begin dc := Canvas; ps := PAINTSTRUCT().rcPaint; //dc.Pen.Color := rgb(180,180,100); dc.Pen.Color := rgb(250,250,250); dc.Pen.Width := 1; dc.font := font; for i := 0 to FPageItems.Length()-1 do begin it := FPageitems[i]; rc := it.Rect; if not rc then continue; if Intersectrect(it.Rect,ps)then begin if FItemIndex=i then begin //dc.Brush.Color := rgb(244,205,205); dc.Brush.Color := 0xFa901E; end else begin dc.Brush.Color := rgb(238,238,228) //rgb(244,244,244); end dc.draw("roundrect",array(rc[0:1],rc[2:3],array(5,5))); if it.BitmapB then begin rc1 := rc; rc1[0]:= rc[2]-20; rc1[2]-= 2; rc1[1]+= 4; rc1[3]-= 4; dc.Stretchdraw(rc1,it.BitmapB); end if it.BitmapA then begin rc1 := rc; rc1[2]:= rc1[0]+20; rc1[0]+= 2; rc1[2]-= 2; rc1[1]+= 2; rc1[3]-= 2; dc.Stretchdraw(rc1,it.BitmapA); end rc[0]+= 20; dc.DrawText(it.caption,rc,DT_nOPREFIX .| DT_LEFT .| DT_SINGLELINE .| DT_VCENTER); end end if FCloseBtn and((FPageItems.Length()>0))then begin Closebmp(); rc := ClientRect; FBmpClose.Draw(dc,rc[2]-25,3,SRCAND); //rc := ClientRect; //rc := array(rc[2]-25,1,rc[2]-1,19); //dc.Stretchdraw(rc,FBmpClose); end end function SetSel(it); begin idx := GetItemIndex(it); if idx >= 0 and idx <> FItemIndex then begin ItemIndex := idx; end end function CloseAllItem(it); begin FItemINdex :=-1; FCurrentITem := nil; saveit := nil; for i,v in FPageItems.Data do begin if v=it then begin saveit := it; continue; end end FPageItems.Splice(0,FPageItems.Length()); if saveit then begin FItemINdex := 0; FCurrentITem := it; FPageItems.push(it); end //InValidateRect(nil,false); DoControlAlign(); InValidateRect(nil,false); end function DeleteItemByIndex(idx);virtual; begin if idx >= 0 and idx= 0 and FItemIndex <> idx then begin if FItemIndex=0 then begin e._Tag := FPageitems[idx]; callDatafunction(fOnbmpbclick,o,e); idx := GetItemIndex(FCurrentItem); ItemIndex := idx; return ; end end if e.shiftdouble() then //处理新建 begin idx := GetItemIndexByPos(e.pos); if idx=-1 then begin callDatafunction(OnDblClick,o,e); end return ; end if e.button=mbLeft then begin cidx := posinitembmpb(e.pos); if cidx>=0 then begin e._Tag := FPageitems[cidx]; callDatafunction(fOnbmpbclick,o,e); idx := GetItemIndex(FCurrentItem); ItemIndex := idx; return ; end end idx := GetItemIndexByPos(e.pos); itemindex := idx; FCloseBtnClicked := false; if e.button=mbLeft and idx >= 0 then begin nxy := clienttowindow(e.xpos,e.ypos); if FCanDraged and FWill_Drag then begin IncPaintLock(); FWill_Drag := false; FIs_Draging := true; CreateImageList(); _wapi.ImageList_BeginDrag(FDRageimglist,0,12,12); FNot_DragLive := true; //_wapi.ImageList_DragEnter(self.Handle,nxy[0],nxy[1]); crect := GetPageRect(); ps := array(clienttoscreen(crect[0],crect[1]),clienttoscreen(crect[2],crect[3])); _wapi.clipcursor(ps); end end else begin rc := ClientRect; rc := array(rc[2]-25,1,rc[2]-1,19); if PointInRect(e.pos,rc)then begin FCloseBtnClicked := true; end end FCanDraged := true; return inherited; //if 3=PosInCurrentItemSection(e.pos) then FCurrentITem.Caption := datetimetostr(now()); end FCanDraged; //修正提示导致修改后提示导致drage 体验问题 function PostInCloseRect(ps); begin rc := ClientRect; rc := array(rc[2]-25,1,rc[2]-1,19); return PointInRect(ps,rc); end function GetItemIndexByPos(xy); begin for i := 0 to FPageItems.Length()-1 do begin if PointInrect(xy,FPageItems[I].Rect)then return i; end return -1; end function posinitembmpb(xy); begin for i := 0 to FPageItems.Length()-1 do begin it := FPageItems[I]; if not it.BitmapB then continue ; ri := it.Rect; ri[0] := ri[2]-18; ri[1]+=2; ri[3]-=2; ri[2]-=2; if PointInrect(xy,ri)then return i; end return -1; end Function GetItemIndex(it); begin for i := 0 to FPageItems.length()-1 do begin if it=FPageitems[i]then begin return i; end end return -1; end function Recycling();override; begin FPageItems.Splice(0,FPageItems.Length()); FOnSelChanged := nil; FOnSelchanging := nil; FCurrentItem := nil; FItemIndex :=-1; FOnCloseClick := nil; fOnbmpbclick := nil; inherited; end property CurrentItem read FCurrentItem; property OnSelChanged read FOnSelChanged write FOnSelChanged; property OnSelChanging read FOnSelChanging write FOnSelChanging; property OnCloseClick read FOnCloseClick write FOnCloseClick; property Onbmpbclick read FOnbmpbclick write fOnbmpbclick; property MultiLine read FMultiLine write SetMultiLine; property CloseBtn read FCloseBtn write SetCloseBtn; property Lines read FLines; property PageItems read FPageItems; property ItemIndex read FItemIndex write SetItemIndex; protected function CallSelChanged();virtual; begin if not OnSelChanged then return false; e := new tuieventbase(); callDatafunction(OnSelChanged,self(true),e); end function CallSelChanging();virtual; begin if not FOnSelchanging then return false; e := new tuieventbase(); CallDatafunction(FOnSelchanging,self(true),e); return e.skip; end function CalcPageItemRect(); begin li := 0; cw := Font.Width; r := class(TCustomControl).ClientRect; x := 0; xct := 0; for i := 0 to FPageitems.Length()-1 do begin it := FPageitems[i]; itwidth := length(it.Caption) * cw+40; if xct>0 and(r[2]-(FCloseBtn?20:0)) FCloseBtn then begin FCloseBtn := nv; DoControlAlign(); end end function SetItemIndex(idx); begin if idx >= 0 and idx FItemIndex then begin if CallSelChanging()then return; FItemIndex := idx; FCurrentItem := FPageItems[idx]; InValidateRect(nil,false); CallSelChanged(); end end FMultiLine; FLineHeight; FLines; FOnSelChanged; FOnCloseClick; FOnSelchanging; function SetMultiLine(); begin end end type TEditerAuxiliary=class(TPage) //辅助窗口 function Create(AOwner); begin inherited; Caption := "message:"; Ftimer := new TTimer(self); Ftimer.Interval := 200; Ftimer.Ontimer := thisfunction(BdownTimeOut); Ftimer.Enabled := false; //FEchoItem := CreateApageItem(); //FFileFindeItem := CreateApageItem(); OnSelChanged := thisfunction(OnSelChangedCall); CloseBtn := true; end function WMNCLBUTTONDOWN(o,e):WM_NCLBUTTONDOWN;override; begin FIgnoreSize := true; Ftimer.Enabled := true; end function BdownTimeOut(o,e); begin if(_wapi.GetAsyncKeyState(VK_LBUTTON).& 0xFF00)>0 then begin end else begin FIgnoreSize := false; o.Enabled := false; p := Parent; if p then p.DoControlAlign(); end end {function MouseDown(o,e);override; begin if CloseBtn then begin rc := ClientRect; rc := rc := array(rc[2]-25,1,rc[2]-1,19); if PointInRect(e.pos,rc) then begin callDatafunction(FOnCloseClick,o,e); end end inherited; end } //property OnCloseClick read FOnCloseClick write FOnCloseClick; function DoControlAlign();override; begin if FIgnoreSize then begin end inherited; rc := ClientRect; //单独处理linux的情况 {$ifdef linux} rc[0]+= 2; rc[2]-= 2; rc[3]-= 2; {$endif} if CurrentItem then wnd := CurrentItem.Tag; if wnd then wnd.SetBoundsRect(Rc); end function ShowPopUp(); begin if not WSpOPUp then begin WSpOPUp := true; Parent.DoControlAlign(); end if not Visible then Visible := true; end function MouseDown(o,e);override; begin if e.shiftdouble()and e.button()=mbLeft then begin WSpOPUp := not WSpOPUp; Parent.DoControlAlign(); if not WSpOPUp then begin _wapi.SetWindowPos(self.Handle,0,0,0,0,0,SWP_NOMOVE .| SWP_NOSIZE .| SWP_NOREDRAW .| SWP_NOSENDCHANGING); end end else if GetItemIndexByPos(e.pos)>= 0 then begin inherited; end else if PostInCloseRect(e.pos)then begin //echo "------------\r\n"; inherited; end else begin if WSpOPUp then _send_(WM_SYSCOMMAND,0xF012,0); end end function Recycling();override; begin Ftimer := nil; FEchoWnd := nil; FFileFindWnd := nil; FOnCloseClick := nil; inherited; //FOnCloseClick := nil; end function ShowByTag(tg); //显示 begin its := Pageitems; for i := 0 to its.Length()-1 do begin if its[i].tag=tg then begin ItemIndex := i; //visible := true; return; end end end function OnSelChangedCall(o,e); begin if not CurrentItem then Caption := "--"; rc := ClientRect; its := PageItems; for i := 0 to its.Length()-1 do begin it := its[i]; if CurrentItem=it then begin it.tag.SetboundsRect(rc); it.tag.Visible := true; caption := it.Tag.Caption; end else it.tag.Visible := false; end end function AddWnd(wnd); begin if wnd is class(TWincontrol)then begin its := PageItems; for i := 0 to its.Length()-1 do begin it := its[i]; if it.tag=wnd then return; end IncPaintLock(); it := CreateApAgeItem(); it.Caption := wnd.Caption; it.tag := wnd; wnd.visible := 0; wnd.Parent := self; PageItems.Push(it); if PageItems.Length()=1 then begin itemIndex := 0; end DecPaintLock(); end end FEchoWnd; FFileFindWnd; FOnCloseClick; private Ftimer; FIgnoreSize; end type TExecuteEditer=class(TCustomControl) //执行编辑器 Protected Type TExecuteMemoComp=class(TSynCompletion) function Create(AOwner); begin inherited; IgnoreCase := false; end function PrepareCompletion(c);override; //获得数据 begin //通过SetCompData 设置数据 if Not Memo then return; d := array(); for i,v in array("FULL_CURRENT_PATH","CURRENT_DIRECTORY","SEARCH_PATH","TSL_EXE") do begin d[i,"caption"]:= v; d[i,"value"]:= v; d[i,"lvalue"]:= lowercase(v); cl := length(v); d[i,"clen"]:= cl; d[i,"vlen"]:= cl; end SetCompData(d); end end type TListBoxb=class(TListBOx) function Create(AOwner); begin inherited; end function CheckListItem(it);override; begin return ifobj(it); end function GetItemText(i);override; begin it := GetItem(i); if it then return it.FCaption; return ""; end function InsureItemVisible(idx); //移动当前的格子 begin rc := GetIdxRect(idx); c := ClientRect; if rc[1]c[3]then begin SetYpos(1+GetYPos()+(rc[3]-c[3]+1)/GetYScrollDelta()); end end function GetItemIndex();virtual; begin return inherited; end function SetItemIndex(idx);virtual; begin inherited; FListBox.InsureItemVisible(idx); end end type TComboBoxb=class(TCombobox) function Create(AOwner); begin INherited; end function CreateAlist();override; begin return new TListBoxb(self); end end type TCobItem=class function Create(d); begin FCaption := ""; FExe := ""; if not ifarray(d)then return; FCaption := d["caption"]; FExe := d["exe"]; end FCaption; FExe; end public function showexeediter(); begin FMemo.ExecuteCommand(FMemo.ecGotoXY,array(1,1)); FMemO.SetFocus(); show(); end function Create(AOwner); begin inherited; WSsYSMenu := true; WsDlgModalFrame := true; WsSizeBox := true; WSpOPUp := true; FItems := new TMyArrayB(); caption := "编辑 Execute....."; SetBoundsRect(array(50,50,930,201)); FMemo := new TSynMemoNorm(self); FMemo.OnKeyPress := function(o,e) begin if 13=e.charcode then begin e.skip := true; doSaveCurrentName(); end end {FMemo.OnKeyDown := function(o,e) begin case e.charcode of VK_DOWN: begin e.skip := true; FChooser.ItemIndex += 1; end VK_UP: begin e.skip := true; FChooser.ItemIndex -= 1; end end; end} FMemo.Border := true; FMemo.parent := self; FChooser := new TComboBoxb(self); //new TEditList(self); FChooser.ReadOnly := false; FChooser.parent := self; FOkBtn := new TBtn(self); FCancelBtn := new TBtn(self); FEgnorBtn := new TBtn(self); cp := new TExecuteMemoComp(self); FMemo.Completion := cp; cp.PrepareCompletion(); OnClose := function(o,e) begin e.skip := true; o.visible := false; end FOkBtn.Caption := "保存/添加"; FCancelBtn.Caption := "删除当前"; FEgnorBtn.caption := "取消"; FOkBtn.parent := self; FCancelBtn.parent := self; FEgnorBtn.parent := self; FMemo.parent := self; FChooser.OnSelChanged := thisfunction(OnChooserChanged); FCancelBtn.OnClick := thisfunction(DeleteCurrent); FOkBtn.OnClick := thisfunction(doSaveCurrentName); FEGnorBtn.OnClick := thisfunction(OnIgnore); end function Recycling();override; begin inherited; FMemo := nil; FChooser := nil; FCancelBtn := nil; FOkBtn := nil; FEgnorBtn := nil; Fonsaveclk := nil; end function DeleteCurrent(); begin if length(FChooser.Items)<2 then return ; FChooser.DeleteItem(FChooser.ItemIndex); end function DoControlAlign();override; begin if FMemo and FChooser and FCancelBtn and FOkBtn and FEgnorBtn then begin r := clientRect; r1 := r; r1[3]-= 30; FMemo.SetBoundsRect(r1); tp := r1[3]+2; wd := 200; x := 50; FChooser.SetBoundsRect(array(x,tp,x+200,tp+26)); x += 200; FCancelBtn.SetBoundsRect(array(x+20,tp,x+20+100,tp+26)); x += 120; FOkBtn.SetBoundsRect(array(x+20,tp,x+100,tp+26)); x += 120; FEgnorBtn.SetBoundsRect(array(x+20,tp,x+100,tp+26)); x += 120; end end function OnIgnore(); begin idx := FChooser.ItemIndex; if idx >= 0 then begin it := FChooser.GetItem(idx); FChooser.Editer.Text := it.FCaption; FMemo.Text := it.FExe; end Visible := false; end function GetCurrentExuteparams(f); begin return ParserCommandLine(GetCurrentExuteString(f)); end function getcurrentcommandline(); begin idx := FChooser.ItemIndex; if not(idx >= 0)then return ""; s := FChooser.GetItem(idx).fexe; if not ifstring(s)then return ""; return s; end function GetCurrentExuteString(f); //获得当前的执行字符串 begin if not ifstring(f)then return ""; if not fileexists("",f)then return ""; idx := FChooser.ItemIndex; if not(idx >= 0)then return ""; s := FChooser.GetItem(idx).fexe; if not ifstring(s)then return ""; s := replacetext(s,"$(FULL_CURRENT_PATH)",f); dir := ""; sp := ioFileseparator(); for i := length(f)downto 1 do begin if f[i]=sp then begin dir := f[1:i-1]; break; end end s := replacetext(s,"$(CURRENT_DIRECTORY)",dir); s := replacetext(s,"$(SEARCH_PATH)",owner.getlibpathstr()); s := replacetext(s,"$(TSL_EXE)",gettslexe()); return s; end function doSaveCurrentName(); begin Visible := false; s := FChooser.Editer.Text; its := FChooser.Items; len := Length(its); for i,v in its do begin if v.FCaption=s then begin v.FExe := FMemo.Text; return callDatafunction( Fonsaveclk,self,self); end end if cannotadd then return ; FChooser.InsertItem(new TCobItem(array("caption":s,"exe":FMemo.Text)),0); FChooser.ItemIndex := 0; callDatafunction( Fonsaveclk,self,self); end function OnChooserChanged(o,e); begin idx := o.ItemIndex; if idx >= 0 then begin it := O.GetItem(idx); FMemo.Text := it.fexe; end else FMemo.Text := ""; FMemo.ClearUndo(); end function GetData(); //获得数据 begin r := array(); its := FChooser.Items; if not(its)then return r; r["itemindex"]:= FChooser.ItemIndex; for i,v in its do begin r["items"][i]:= array("caption":v.FCaption,"exe":v.FExe); end return r; end function SetData(d); //设置数据 begin if ifarray(d)then begin SetItems(d["items"]); FChooser.ItemIndex := d["itemindex"]; end end property Items read FItems Write SetItems; property onsaveclk read Fonsaveclk write Fonsaveclk; property cannotadd read FCannotadd write FCannotadd; private FCannotadd; Fonsaveclk; FMemo; FChooser; FCancelBtn; FOkBtn; FItems; FEgnorBtn; private function GetItemIndex(); begin return FChooser.Items; end function SetItems(its); //设置信息 begin vs := array(); for i,v in its do begin if ifarray(v)and ifstring(v["caption"])and ifstring(v["exe"])then begin vi := new TCobItem(v); vs[length(vs)]:= vi; end end FChooser.Items := vs; end end type TEditList=class(TComboBox) function Create(AOwner);override; begin inherited; width := 280; maxListItemShow := 30; FMaxCoder := 20; ReadONly := false; Editer.OnKeyDown := function(o,e) begin case e.charcode of VK_UP: begin ItemIndex -= 1; e.skip := true; end VK_DOWN: begin ItemIndex += 1; e.skip := true; end 13: begin Calldatafunction(OnEnterUp,self(true),e); e.skip := true; end VK_ESCAPE: begin oer := o.owner.owner; if oer then oer.Visible := false; end ord("A"): begin if ssCtrl in e.Shiftstate()then begin e.skip := true; o.SetSel(0,length(o.text)); end end end; end end function Recycling();override; begin inherited; FOnEnterUp := nil; end function Pushitem(s); begin if not ifstring(s)and s then return; if s in Items then return 0; insertItem(s,0); if getItemCount()>FMaxCoder then begin deleteItem(FMaxCoder); end end property OnEnterUp read FOnEnterUp write FOnEnterUp; property MaxCoder read FMaxCoder write FMaxCoder; private FMaxCoder; FOnEnterUp; end type TFindWnd=class(TPage) type TFindBtn=class(TBtn) function Create(AOwner); begin inherited; left := 425; width := 160; height := 25; end end type TFindCheck=class(TCheckBtn) function Create(AOwner); begin inherited; left := 25; width := 160; height := 25; end end function CreateWndInfo(btn,sec); //触发 begin r := GetInfo(); if sec then r["section"]:= sec; r["btn"]:= btn; end function Create(AOwner);override; begin inherited; OnClose := function(o,e) begin Parent.EndFind(); o.visible := false; e.Skip := true; end WsDlgModalFrame := true; Visible := false; WsPopUp := true; WsCaption := true; WSsYSMenu := true; //WsSizeBox := true; caption := "查找"; SetBoundsRect(array(300,300,920,680)); IncPaintLock(); for i,v in array("查找","替换","文件查找") do begin it := CreateApageItem(); it.Caption := v; PageItems.Push(it); end DecPaintLock(); lg := 30; FEdit_Target := new TEditList(self); FEdit_repace := new TEditList(self); FEdit_Type := new TEditList(self); FEdit_dir := new TEditList(self); FDirChooser := new TFolderChooseADlg(self); FEdit_dir_btn := new TBtn(self); flabels := array(); for i,v in array("查找目标:"," 替换为:","文件类型:"," 目录:") do begin lb := new TLabel(self); lb.TextAlign := AL9_CENTERRIGHT; lb.caption := v; lb.Top :=(i+1) * lg; lb.Height := 25; lb.Left := 20; lb.Width := 120; lb.Parent := self; //lb.border := true; flabels[i]:= lb; end FEdit_Target.left := 140; FEdit_Target.top := lg; FEdit_target.parent := self; FEdit_target.Editer.OnKeyPress := thisfunction(EditerEnter); FEdit_repace.left := 140; FEdit_repace.top := lg+lg; FEdit_repace.parent := self; FEdit_type.left := 140; FEdit_type.top := lg+lg+lg; FEdit_type.Editer.Text := "*.tsf;*.tsl;"; FEdit_type.parent := self; FEdit_dir.left := 140; FEdit_dir.Width := FEdit_dir.Width-20; FEdit_dir_btn.Caption := ".."; FEdit_dir_btn.top := lg+lg+lg+lg; FEdit_dir_btn.Width := 18; FEdit_dir_btn.left := 140+FEdit_dir.Width+2; FEdit_dir_btn.height := 24; FEdit_dir.top := lg+lg+lg+lg; FEdit_dir.parent := self; FEdit_dir_btn.OnClick := function(o,e) begin if FDirChooser.OpenDlg()then begin FEdit_dir.Editer.text := FDirChooser.Folder; end end FBtn_Find := new TFindBtn(self); FBtn_replace := new TFindBtn(self); FBtn_Count := new TFindBtn(self); // 计数 FBtn_replaceall := new TFindBtn(self); FBtn_Find.caption := "查找"; FBtn_replace.caption := "替换"; FBtn_Count.caption := "全部查找"; FBtn_replaceall.caption := "全部替换"; FBtn_Find.top := lg; FBtn_Find.parent := self; FBtn_replace.top := lg+lg; FBtn_replace.parent := self; FBtn_replaceall.top := lg+lg+lg; FBtn_replaceall.parent := self; FBtn_Find.OnClick := thisfunction(FindBtnClick); FBtn_replace.OnClick := thisfunction(FindBtnClick); FBtn_Count.OnClick := thisfunction(FindBtnClick); FBtn_replaceall.OnClick := thisfunction(FindBtnClick); FBtn_Count.top := lg+lg+lg+lg; FBtn_Count.parent := self; FDirChooser.parent := self; FCheck_revers := new TFindCheck(self); FCheck_wrap := new TFindCheck(self); FCheck_case := new TFindCheck(self); FCheck_cycle := new TFindCheck(self); FCheck_reg := new TFindCheck(self); FCheck_subdir := new TFindCheck(self); FCheck_gt := new TFindCheck(self); FCheck_subdir.checked := true; FCheck_subdir.Left := 425; FCheck_subdir.top := lg+lg+lg+lg; FCheck_subdir.Caption := "包含子目录"; FCheck_revers.caption := "反向查找"; FCheck_revers.top := lg * 5; FCheck_revers.parent := self; FCheck_wrap.caption := "全词匹配"; FCheck_wrap.top := lg * 6; FCheck_wrap.parent := self; FEdit_dir_btn.parent := self; FCheck_case.caption := "忽略大小写"; FCheck_case.Checked := true; FCheck_case.top := lg * 7; FCheck_case.parent := self; FCheck_cycle.caption := "循环查找"; FCheck_cycle.Checked := true; FCheck_cycle.top := lg * 8; FCheck_cycle.parent := self; FCheck_reg.caption := "正则匹配"; FCheck_reg.Enabled := false; FCheck_reg.top := lg * 9; FCheck_reg.parent := self; FCheck_gt.caption := "\\t转义tab"; FCheck_gt.Checked := false; FCheck_gt.top := lg * 9; FCheck_gt.Left := FCheck_reg.width+FCheck_reg.Left+10; FCheck_gt.parent := self; FCheck_subdir.parent := self; FCheck_reg.OnClick := function(o,e) begin FCheck_revers.Enabled := not(o.Checked); FCheck_wrap.Enabled := not(o.Checked); FCheck_case.Enabled := not(o.Checked); end FStatus := new TStatusBar(self); //FStatus.Align := alNone; FStatus.Items := array(("text":"","width":700)); FStatus.Parent := self; OnSelChanged := thisfunction(DoSelChanged); ItemIndex := 0; //SetStatusText("查找"); end function FindBtnClick(o,e); begin r := GetInfo(); r["btn"]:= o.Caption; Owner.DoFind(r,self); end function EditErEnter(o,e); begin if e.CharCode=13 then begin e.skip := true; r := GetInfo(); r["btn"]:= "查找"; OWner.DoFind(r,self); end end function GetInfo(); begin r := array(); r["section"]:= CurrentITem.Caption; s := FEdit_target.Editer.Text; if FCheck_gt.Checked then begin s := Replacestr(s,"\\t","\t"); end r["target"]:= s; s := FEdit_repace.Editer.Text; if FCheck_gt.Checked then begin s := Replacestr(s,"\\t","\t"); end r["replace"]:= s; r["filetype"]:= FEdit_type.Editer.Text; r["dir"]:= FEdit_dir.Editer.Text; r["c_revers"]:= FCheck_revers.Checked; r["c_cycle"]:= FCheck_cycle.Checked; r["c_wrap"]:= FCheck_wrap.Checked; r["c_case"]:= FCheck_case.Checked; r["c_reg"]:= FCheck_reg.Checked; r["c_dir"]:= FCheck_subdir.Checked; return r; end function SetStatusText(s); begin if ifstring(s)then FStatus.SetItemText(s,0); end function OpenFind(); begin ItemIndex := 0; end function OpenReplace(); begin ItemIndex := 1; end function Show(f);override; begin it := Owner.GetCurrentEditer(); if it then begin s1 := it.SelText; if s1 and length(s1)<20 and not(pos("\n",s1))then begin s := s1; end else s := it.CaretWords(); if s then SetFindText(s); FEdit_target.Editer.SetFocus(); end inherited; end Function SetFindText(s); //设置查找的字符串 begin FEdit_target.Editer.Text := s; FEdit_target.Editer.SetSel(0,length(s)); end function SaveCurrentEditer(); //保存一下数据 begin for i,v in array(FEdit_target,FEdit_dir,FEdit_type,FEdit_repace) do begin v.PushItem(v.Editer.Text); end //if e then e.PushItem(e.Editer.Text); end function DoSelChanged(o,e); begin if CurrentItem then Caption := CurrentItem.Caption; case Caption of "查找": begin for i := 1 to 3 do flabels[i].Visible := false; FEdit_dir.visible := false; FEdit_dir_btn.visible := false; FEdit_type.visible := false; FEdit_repace.visible := false; FBtn_replace.visible := false; FBtn_count.Visible := true; FBtn_Replaceall.Visible := false; FCheck_subdir.visible := false; FCheck_Revers.visible := true; FCheck_cycle.Visible := true; end "替换": begin flabels[1].Visible := true; for i := 2 to 3 do flabels[i].Visible := false; FEdit_dir.visible := false; FEdit_dir_btn.visible := false; FEdit_type.visible := false; FEdit_repace.visible := true; FBtn_replace.visible := true; FBtn_count.Visible := false; FBtn_Replaceall.Visible := true; FCheck_subdir.visible := false; FCheck_Revers.visible := false; FCheck_cycle.Visible := true; end "文件查找": begin for i := 1 to 3 do flabels[i].Visible := true; FEdit_dir.visible := true; FEdit_dir_btn.Visible := true; FEdit_type.visible := true; FEdit_repace.visible := true; FBtn_replace.visible := false; FBtn_count.Visible := false; FBtn_Replaceall.Visible := true; FCheck_subdir.visible := true; FCheck_Revers.visible := false; FCheck_cycle.Visible := false; end end end function DoControlAlign();override; begin inherited; if not FStatus then return; rc := ClientRect; rc[1]:= rc[3]-30; FStatus.SetBoundsRect(rc); end function recycling();override; begin inherited; FStatus := nil; end function GetHistory(); begin r := array(); r["finds"]:= FEdit_Target.Items; r["repalces"]:= FEdit_repace.Items; r["dirs"]:= FEdit_dir.items; r["findfiletyps"] := FEdit_Type.items; return r; end function SetHistory(d); begin if not ifarray(d)then return; fds := d["finds"]; if ifarray(fds)then begin FEdit_Target.Items := fds; end rps := d["repalces"]; if ifarray(rps)then begin FEdit_repace.Items := rps; end dirs := d["dirs"]; if ifarray(dirs)then begin FEdit_dir.items := dirs; end dirs := d["findfiletyps"]; if ifarray(dirs)then begin FEdit_Type.items := dirs; end end private FStatus; FDirChooser; //查找 FEdit_Target; FEdit_repace; FEdit_type; FEdit_dir; FEdit_dir_btn; FBtn_Find; FBtn_replace; FBtn_Replaceall; FBtn_Count; // 计数 flabels; FCheck_revers; FCheck_wrap; FCheck_case; FCheck_cycle; FCheck_reg; FCheck_subdir; FCheck_gt; end type TListPages=class(TListBox) function Create(AOwner);override; begin inherited; Visible := false; WsPopUp := true; end function PaintIdx(idx,rc_,cvs);override; begin {** @explan(说明)绘制项 %% @param(item)(TCustomListItem) 项 %% @param(rc)(array) 绘制区域%% @param(cvs)(tcanvas) 画布 %% **} inherited; if idx=getCurrentSelection()then begin rc := rc_; rc[2:3]-= 1; cvs.pen.Color := rgb(30,144,255); cvs.draw("Polyline",array(rc[0:1],(rc[2],rc[1]),(rc[2],rc[3]),(rc[0],rc[3]),rc[0:1])); end end function MouseUp(o,e);override; begin inherited; visible := false; end function SetData(d);override; begin if not ifarray(d)then return; height := ItemHeight * (1+min(15,length(d))); x := 10; for i,v in d do begin x := max(x,length(v)); end width := font.Width * (x+3); inherited; end function InsureItemVisible(idx); //移动当前的格子 begin rc := GetIdxRect(idx); c := ClientRect; if rc[1]c[3]then begin SetYpos(1+GetYPos()+(rc[3]-c[3]+1)/GetYScrollDelta()); end end function GetSelFileName; begin r := GetItem(getCurrentSelection()); if pos("*",r)then begin return r[2:]; end return r; end function IncIndex(f); begin if ifnil(f)then f :=-1; idx := getCurrentSelection(); ct := ItemCount; nidx := idx-f; if idx=ct-1 then nidx := 0; else if idx=-1 then nidx := 1; SetCurrentSelection(nidx); InsureItemVisible(nidx); end end type tagCOMPOSITIONFORM=class(tslcstructureobj) private static SSTRUCT; class function getstruct() begin if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array( ("dwstyle","int",4), ("ptcurrentpos","intptr",0), ("rcarea","int[4]",array(0,0,0,0))),nil,nil,1); return SSTRUCT; end public function create() begin inherited create(getstruct(),ptr); FPonter := new TCPoint(); _setvalue_("ptcurrentpos",FPonter._getptr_()); end property dwstyle index "dwstyle" read _getvalue_ write _setvalue_; property ptcurrentpos read FPonter; property rcarea index "rcarea" read _getvalue_ write _setvalue_; private FPonter; end type TFTSLScriptMemo=class(TSYNmemoNorm) function Create(AOwner);override; begin inherited; WsDlgModalFrame := true; FChangedFlag := false; FChangedLock := false; Lineinterval := 3; FCOMPOSITIONFORM := new tagCOMPOSITIONFORM(nil); font := array("height":18,"width":9,"escapement":0,"orientation":0,"weight":400,"italic":0,"underline":0,"strikeout":0, "charset":0,"outprecision":0,"clipprecision":0,"quality":1,"pitchandfamily":1,"facename":"Courier New","color":0); //134 //font := array("facename":"Courier New"); end function DoCaretPosChanged();override; begin if HandleAllocated()then calldatafunction(FOnCaretChanged,self(true),new tuieventbase(0,0,0,0)); //echo tostn(self.CaretXY); end function WMIMESTARTCOMPOSITION(o,e):WM_IME_STARTCOMPOSITION;virtual; begin ime := ImmGetContext(self.Handle); FCOMPOSITIONFORM.ptcurrentpos.cx := 200; FCOMPOSITIONFORM.ptcurrentpos.cy := 200; ImmSetCompositionWindow(ime,FCOMPOSITIONFORM._getptr_()); ImmReleaseContext(self.Handle,ime); end {$ifdef linux} function ImmReleaseContext(); begin end; function ImmGetContext(); begin end; function ImmSetCompositionWindow(); begin end; function ImmSetStatusWindowPos(); begin end; {$else} function ImmReleaseContext(h:pointer;ime:pointer):integer;stdcall;external "Imm32.dll" name "ImmReleaseContext"; function ImmGetContext(h:pointer):pointer;stdcall;external "Imm32.dll" name "ImmGetContext"; function ImmSetCompositionWindow(h:pointer;s:pointer):integer;stdcall;external "Imm32.dll" name "ImmSetCompositionWindow"; function ImmSetStatusWindowPos(h:pointer;s:pointer):integer;stdcall;external "Imm32.dll" name "ImmSetStatusWindowPos"; {$endif} function InvalidateLines(FirstLine,LastLine:integer);override; begin //return inherited; if not HandleAllocated()then return; if HighLighter is class(TTslSynHighLighter)then begin fy :=(FirstLine-TopLine) * TextHeight; r := ClientRect; if fyr[3]then return; r[0]:= GutterWidth; r[1]:= max(0,fy); InvalidateRect(r,false); end else return inherited; end function MouseUp(o,e);override; begin inherited; end function InsertChars(s);override; begin if(s="\r\n")then begin y := CaretY; x := CaretX; sl := Lines.GetStringByIndex(y-1); if ifstring(sl)and sl then begin ins := ""; for i := 1 to x-1 do begin si := sl[i]; if si="\t" or si=" " then begin ins += si; end else break; end if ins then begin return inherited InsertChars(s+ins); end end end return inherited; end function KeyUp(o,e);override; begin e.Result := 1; if Calldatafunction(FQuckKeys,self,e)then return; inherited; end function ContextMenu(o,e);override; begin inherited; e.skip := true; end function SwitchMarkLine(L); //此处处理断点问题 begin if not(L >= 0)then begin L := self.CaretY-1; end it := Lines[L]; if it then begin it.FMarked := not(it.FMarked); r := ClientRect; r[2]:= GutterWidth()-1; InValidateRect(r,false); if _Tag then _Tag.markline(L,it.FMarked); end end function KeyDown(o,e);override; begin e.Result := 0; qc := Calldatafunction(FQuckKeys,self,e); if qc then return; if e.CharCode=VK_F5 then begin L := self.CaretY-1; SwitchMarkLine(L); return; end if e.CharCode=VK_F2 and(ssCtrl in e.shiftState())then begin L := self.CaretY-1; SwitchMarkLine(L); return; end if not(ssCtrl in e.shiftstate())and not(ssShift in e.shiftstate())then begin if e.CharCode=VK_F2 then begin y := CaretY-1; len := Lines.length(); for i := y+1 to len+y-1 do begin idx :=(i+len)mod len; it := Lines[idx]; if it and it.FMarked then begin return ExecuteCommand(ecGotoXY,array(idx+1,1)); end end return; end end inherited; end function WMSYSKEYUP(o,e):WM_SYSKEYUP;override; begin e.Result := 1; if CallDatafunction(FQuckKeys,self,e)then return; inherited; end Function WMSYSKEYDOWN(o,e):WM_SYSKEYDOWN;override; begin e.Result := 0; if CallDatafunction(FQuckKeys,self,e)then return; inherited; end function WMSETFOCUS(o,e):WM_SETFOCUS;override; begin inherited; CallDataFunction(FOnTextSetFocus,self(true),e); end function DoTextChanged(p);override; begin n := Lines.Length(); ccnt := GutterCharCnt; nccnt := max(integer(n~10)+3,4); if ccnt <> nccnt then begin GutterCharCnt := nccnt; end inherited; SetChangeFlag(true); end function Recycling();override; begin FQuckKeys := nil; FOnTextChanged := nil; FOnTextSetFocus := nil; FPageItem := nil; FOnCaretChanged := nil; inherited; end published property OnCaretChanged read FOnCaretChanged write FOnCaretChanged; property PageItem read FPageItem write FPageItem; property OnTextChanged read FOnTextChanged write FOnTextChanged; //文本改变 property QuckKeys read FQuckKeys write FQuckKeys; //快捷键 property ChangedFlag read FChangedFlag write SetChangeFlag; property ChangedLock read FChangedLock write FChangedLock; property OnTextSetFocus read FOnTextSetFocus write FOnTextSetFocus; private function SetChangeFlag(v); begin nv := v?true:false; if nv <> FChangedFlag then begin FChangedFlag := nv; if FChangedLock then return; calldatafunction(OnTextChanged,self(true),nv); end end FPageItem; FChangedLock; FChangedFlag; FOnTextChanged; FOnTextSetFocus; FQuckKeys; FCOMPOSITIONFORM; FOnCaretChanged; end type TPageEditerItem=class(TPageItem) FPageOrderId; //序号有调用者使用 FEditer; //编辑器 FSynType; FInitCompletion; FDebuger; fisnewfile; function create(AOwner);override; begin inherited; FSynType := ""; FEnCode := "ANSI"; FGetInfoText := ""; FLastVersion := ""; FEditer := new TFTSLScriptMemo(AOwner); FEditer.Visible := false; FEditer._Tag := self; end function Recycling();override; begin FDebuger := nil; inherited; FEditer.Recycling(); FEditer := nil; end function markline(l,f); //标记被调用 begin if FDebuger then begin if f then begin FDebuger.addbreak(self,l); end else begin FDebuger.removebreak(self,l); end end end function ScriptPathIs(v); begin return filenameIsTheSame(v,FScriptPath); end published property ScriptPath read FScriptPath write SetScriptPath; //文件名 property OrigScriptPath read FOrgScriptPath; property TslSynText read FTslSynText write FTslSynText; property LastText read FLastVersion; //最新的版本 property EnCode read FEnCode; RepreComple; FISstm; ///////////////////设计器相关////////////////////////////////////// public function Addfiled(fld); //添加成员变量 begin if not FTslParser then return 0; if not(fld and ifstring(fld))then return; nfld := lowercase(fld); nt := str2array(nfld,":"); nfld := nt[0]; nfldt := nt[1]; d := GetClassInfo(); if not(d and ifarray(d))then return 0; for i,v in d["filed"] do begin if v["name"]=nfld then return 1; end crec := GetCreateFunctionRec(d); if crec then begin p := crec[0]; if ifarray(p)then begin FEditer.ExecuteCommand(FEditer.ecGotoXY,p); FEditer.ExecuteCommand(FEditer.ecString,fld+";\r\n "); end end end function GetCreateFunctionRec(d); //获得插入函数为位置 begin fi := d["funcsinfo"]; for i,v in fi do begin if v["name"]="create" then begin return GetInfoRowCol(v); end end return 0; end function Delfiled(fld,nn); //删除成员变量 begin if not FTslParser then return 0; if not(fld and ifstring(fld))then return; if not ifstring(nn)then nn := ""; nfld := lowercase(fld); d := GetClassInfo(); if not(d and ifarray(d))then return 0; for i,v in d["filed"] do begin if v["name"]=nfld then begin frec := GetInfoRowCol2(v); if ifarray(frec[0])and ifarray(frec[1])then begin FEditer.ExecuteCommand(FEditer.ecGotoXY,frec[0]); FEditer.ExecuteCommand(FEditer.ecSelGotoXY,frec[1]); FEditer.SelText := nn?(nn+";"):""; end end end end function GoToFunction(fn); begin if not(ifstring(fn))then return false; nfld := lowercase(fn); d := GetClassInfo(); if not ifarray(d)then return 0; for i,v in d["funcsinfo"] do begin if v["name"]=nfld then begin crec := GetInfoRowCol(v); if ifarray(crec)and ifarray(crec[0])then begin FEditer.ExecuteCommand(FEditer.ecGotoXY,crec[0]); end return true; end end end function AddFunction(fn,finfo); //添加函数 begin if not FTslParser then return 0; if not(ifstring(fn)and fn and ifstring(finfo))then return 0; nfld := lowercase(fn); d := GetClassInfo(); if not ifarray(d)then return 0; for i,v in d["funcsinfo"] do begin if v["name"]=nfld then begin crec := GetInfoRowCol(v); if ifarray(crec)and ifarray(crec[0])then begin FEditer.ExecuteCommand(FEditer.ecGotoXY,crec[0]); end return true; end end crec := GetCreateFunctionRec(d); if crec then begin p := crec[1]; if ifarray(p)then begin FEditer.ExecuteCommand(FEditer.ecGotoXY,p); FEditer.ExecuteCommand(FEditer.ecString,"\r\n"+finfo+"\r\n "); end end return true; end function GetLastLoadTime(); //最新时间 begin return FLastFileTime; end function ReGetLastLoadTime(); //重新获得时间 begin fi := FileList("",FScriptPath); FLastFileTime := fi[0,"Time"]; return FLastFileTime; end function PrePareSave(); //准备保存 begin if not FEditer.ChangedFlag then begin if RepreComple then itemPareCompletion(); return false; end if FEditer.ReadOnly then begin if RepreComple then itemPareCompletion(); return false; end t := FEditer.Text; if FLastVersion=t then begin FEditer.ChangedFlag := false; if RepreComple then itemPareCompletion(); return false; end FLastVersion := t; itemPareCompletion(); //FEditer.PrePareCompletion(t); //准备自动完成 FEditer.ChangedFlag := false; return true; end function itemPareCompletion(); begin t := caption; cp := FEditer.Completion; if cp then cp.PrePareCompletion(t); RepreComple := false; end function IsTextUTF8(str) begin {utf8规则 单字节: 0xxxxxxx 二字节 110xxxxx 10xxxxxx 三字节 1110xxxx 10xxxxxx 10xxxxxx 四字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 五字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 刘字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx } // 0 为ansi 编码,1 为utf8编码 -1 不能确定什么编码 nBytes := 0; //UFT8可用1-6个字节编码,ASCII用一个字节 DY := 0; chr := ""; bAllAscii := TRUE; //如果全部都是ASCII, 说明不是UTF-8 for i := 1 to length(str) do begin chr := ord(str[i]); if((chr .& 0x80)<> 0)then begin // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx bAllAscii := FALSE; end if(nBytes=0)then //如果不是ASCII码,应该是多字节符,计算字节数 begin if(chr >= 0x80)then begin if(chr >= 0xFC and chr <= 0xFD)then nBytes := 6; else if(chr >= 0xF8)then nBytes := 5; else if(chr >= 0xF0)then nBytes := 4; else if(chr >= 0xE0)then nBytes := 3; else if(chr >= 0xC0)then nBytes := 2; else return 0; DY := MAX(nBytes,DY); nBytes--; end end else //多字节符的非首字节,应为 10xxxxxx begin if((chr .& 0xC0)<> 0x80)then return-1; nBytes--; end end; if(nBytes>0)then //违返规则 return-1; if(bAllAscii)then //如果全部都是ASCII, 说明不是UTF-8 return 0; //return 1; return DY>2; end function ToUnicode_big(); begin if FEnCode="UCS2-big" then return; FEnCode := "UCS2-big"; FEditer.ChangedFlag := true; FLastVersion := ""; end function ToUniocode_little(); begin if FEnCode="UCS2-little" then return; FEnCode := "UCS2-little"; FEditer.ChangedFlag := true; FLastVersion := ""; end function ToUTF8(); begin if FEnCode="UTF8" then return; FEnCode := "UTF8"; FEditer.ChangedFlag := true; FLastVersion := ""; return; end function ToUTF8BOM(); begin if FEnCode="UTF8 BOM" then return; FEditer.ChangedFlag := true; FEnCode := "UTF8 BOM"; FLastversion := ""; end function ToANSI(); begin if FEnCode="ANSI" then return; FEditer.ChangedFlag := true; FEnCode := "ANSI"; FLastversion := ""; end function CurrentCodeIsUtf8(); begin if FEnCode="ANSI" then begin s := FEditer.Text; try s := UTF8toansi(s); FEditer.Text := s; FEnCode := "UTF8"; except end end end function CurrentCodeIsAnsi(); begin if FEnCode="UTF8" then begin FEnCode := "ANSI"; end end function SetLoadScript(s); //保存文件 begin if not ifstring(s)then return; strcode := 0; FEnCode := "ANSI"; if(length(s)>= 2)and ord(s[1])=0xFE and ord(s[2])=0xFF then //ucs2-big begin strcode := 2; FEnCode := "UCS2-big"; //要转换 if length(s)=2 then s := ""; else begin s1 := ""; setlength(s1,length(s)-2); for i := 3 to length(s)-1 step 2 do begin s1[i-2]:= s[i+1]; s1[i-1]:= s[i]; end s := unicodetomultibyte(s1,936); end end else if(length(s)>= 2)and ord(s[1])=0xFF and ord(s[2])=0xFE then //ucs2-little begin strcode := 4; FEnCode := "UCS2-little"; if length(s)=2 then s := ""; else begin s := unicodetomultibyte(s[3:],936); end end else if(length(s)>= 3)and ord(s[1])=0xEF and ord(s[2])=0xBB and ord(s[3])=0xBF then begin FEnCode := "UTF8 BOM"; if length(s)=3 then s := ""; else s := utf8toansi(s[4:]); strcode := 1; end if(0=strcode)then begin if IsTextUTF8(s)=1 then begin FEnCode := "UTF8"; strcode := 1; s := utf8toansi(s); end end FLastVersion := s; FEditer.Text := s; FEditer.ExecuteCommand(FEditer.ecGotoXY,array(1,1)); FEditer.ClearUndo(); FEditer.ChangedFlag := false; if not FTslSynText then return; if not(s)then return; r := tsl_tokenizeex_2_(s,1); cs := r["class"]; if ifarray(cs)and cs[0]then begin lcs1 := lowercase(cs[0]); if lcs1 in array("tdcreateform","tdcreatepanel")then begin try if not FTslParser then FTslParser := new unit(UDesignerProject).tslparser(); #! end except end; return; //返回 end end FTslParser := nil; end function GetClassInfo(); //获得信息 begin if not FTslParser then return array(); txt := FEditer.Text; if txt <> FGetInfoText then begin FGetInfoText := txt; FTslParser.Script := txt; FGetInfoChace := FTslParser.GetClassInfo(1); end return FGetInfoChace; end private FEnCode; FLastFileTime; FTslSynText; function GetInfoRowCol(v); //获得行列 begin rs := PosToRowCol(FGetInfoText,array(v["startpos"]-1,v["endpos"])); return rs; end function GetInfoRowCol2(v); //获得行列结尾 begin rs := PosToRowCol(FGetInfoText,array(v["beg"]-1,v["end"])); return rs; end function PosToRowCol(s,ps); //位置换算 begin r := array(); idx := 0; pi := ps[idx]; ri := ci := 1; for i := 1 to length(s) do begin vi := s[i]; if vi="\n" then begin ri++; ci := 1; end else ci++; if i=pi then begin r[idx]:= array(ri,ci); idx++; pi := ps[idx]; end end return r; end FTslParser; // FGetInfoChace; //class 信息 FGetInfoText; //文本 FLastVersion; //脚本 FScriptPath; //路径 FOrgScriptPath; //原始路径 function SetScriptPath(v); begin sp := ioFileseparator(); if ifstring(v)then begin for i := length(v)downto 1 do begin if v[i]=sp then begin Caption := v[i+1:]; break; end if v[i]="." then begin if lowercase(v[i:])in array(".tsl",".tsf")then FTslSynText := true; end end FScriptPath := v; FOrgScriptPath := v; FEditer.Caption := v; end end end type TPageEditer=class(TPage) //多页编辑 function Create(AOwner);override; begin inherited; end function MouseUp(o,e);override; begin inherited; if e.button()=mbRight then begin return CallDatafunction(FPageItemOnRClick,self,e); end end function CallSelChanged();override; begin it := Currentitem; if it then begin it.FEditer.SetBoundsRect(self.ClientRect); it.FEditer.Visible := true; it.FEditer.SetFocus(); end inherited; end function CallSelChanging();override; begin inherited; it := CurrentItem; if it and it.FEditer then it.FEditer.Visible := false; end function Recycling();override; begin inherited; FCliper := nil; FMenu := nil; FPageItemOnRClick := nil; end function DoControlAlign();override; begin inherited; it := CurrentItem; if it then begin it.FEditer.SetBoundsRect(self.ClientRect); end end property PageItemOnRClick read FPageItemOnRClick write FPageItemOnRClick; private FPageItemOnRClick; end type TTslChmHelp=class function SearchWord(s); begin if not s then return; pm := format('%s::/%s.htm',FTSLinterpPath+FChmName,s); //>mainwin HtmlHelpA(GetDesktopWindow(),pm,0,nil); return; end function ShowTslLangChm(); begin return HtmlHelpA(GetDesktopWindow(),FTSLinterpPath+FChmName,0,nil); end function Create(); begin FChmName := "help\\LANGUAGEGUIDE.CHM"; FTSLinterpPath := ""; n := pluginpath(); for i := length(n)-1 downto 3 do begin if n[i]="\\" then begin FTSLinterpPath := n[1:i]; break; end end end property ChmName read FChmName write FChmName; private FTSLinterpPath; FHanle; FChmName; end type TEditerEchoWnd=class(TSynMemoNorm) // function Create(AOwner);override; begin inherited; FDoLockTime := 0; FIsLocked := false; height := 250; ReadOnly := true; WsSizeBox := true; WsSysMenu := true; OnClose := function(o,e) begin o.visible := false; e.skip := true; end m := new TPopUpMenu(self); m1 := new TMenu(self); m1.Caption := "清空"; m1.parent := m; {m2 := new TMenu(self); m2.Caption := "选中字符高亮"; m2.Checked := false; m2.OnClick := function(o,e)begin o.Checked := not(o.Checked); self.HighLighter := (o.Checked) ?F_Highlighter :false; end m2.Parent := m;} PopUpMenu := m; m1.OnClick := function(o,e) begin ClearAll(); AppendString("ctrl+z 停止;ctrl+c 复制选择\r\n"); end; FProcess := new TCreateProcessA(); FProcess.BufSize := 1024 * 5; FProcess.OnEcho := thisfunction(TEchoToString); AppendString("ctrl+z 停止;ctrl+c 复制选择\r\n"); F_Highlighter := new TSynHighLighter(self); //Highlighter := new TSynHighLighter(self); end function TEchoToString(o,s); begin //t := now(); {if (t-FDoLockTime)>(0.3E-5) then begin FDoLockTime := t; if FIsLocked then begin FIsLocked := false; DecPaintLock(); end else begin FIsLocked := true; IncPaintLock(); end end } AppendString(s); //Visible := true; return true; end function Exec(exe,cmd,h); begin //AppendString(format('"%s" %s\r\n',exe,cmd)); self.HighLighter := nil; AppendString(format('%s %s\r\n',exe,cmd)); //EndExe(); r := FProcess.CreateProcessWaitRead(exe,cmd,h); AppendString(format("\r\n执行结束:endcode:%d\r\n",r)); {if FIsLocked then begin FIsLocked := false; DecPaintLock(); end } self.HighLighter := F_Highlighter; h := 0; return r; end function Exeing(); begin return FProcess.LastExeHandle; end function EndExe(); begin if FProcess.LastExeHandle then begin r := 1; SysTerminate(r,FProcess.LastExeHandle); end end function KeyDown(o,e);override; begin if ssCtrl in e.shiftstate then begin case e.charcode of ord("Z"): begin EndExe(); return; end ord("C"): begin ExecuteCommand(ecCopy); return; end end end inherited; end function AppendString(s); begin if not(ifstring(s)and s)then return; ct := Lines.Length(); if ct>0 then begin ExecuteCommand(ecGoToXY,array(ct,1)); ExecuteCommand(ecLineEnd); ExecuteCommand(ecString,s); end end FExeHandle; FProcess; FIsLocked; FDoLockTime; F_Highlighter; end type TTslDebug=class(TCustomControl) private //成员变量 FRuningfile; //执行脚本文件名 FRuningItem; //执行的pageitem FCurrentgotoitem; //当前运行到的pageitem FDebughandle; //调试的句柄 FDebugExe; //调试功能的exe FConnectchannel; //调试的 通道 FDebugaddr; //地址 FDebugport; //调试的端口 FDebugUsr; //用户名 FDebugPwd; //密码 FDebugtsfs; //当前工程对应的tsf文件 FBtns; FAttchedid; FDebugtype; fdbgselwnd; FRemoteWait; //远程调试等待 FValewnd; FCmdHistory; FCmdHistoryid; FCmdHistorycount; //////////////////// Fdbgssybs; Fdbgsybs; Fdbgstack; fdefaultdbger; //编辑器的调试器 type tdbgwnd=class(TPanel) uses tslvcl; function Create(AOwner); begin inherited; WsDlgModalFrame := false; p1 := new TPairSplitter(self); p1.Position := 310; p2 := new TPairSplitter(self); p2.Position := 310; sd1 := new TPairSplitterSide(self); sd2 := new TPairSplitterSide(self); sd3 := new TPairSplitterSide(self); sd3 := new TPairSplitterSide(self); sd4 := new TPairSplitterSide(self); p1.Align := alClient; sd1.WsDlgModalFrame := false; sd2.WsDlgModalFrame := false; sd3.WsDlgModalFrame := false; sd4.WsDlgModalFrame := false; p1.WsDlgModalFrame := false; p2.WsDlgModalFrame := false; p1.parent := self; sd1.parent := p1; sd1.Border := false; sd2.parent := p1; p2.Align := alClient; p2.parent := sd2; sd3.parent := p2; sd4.parent := p2; sd4.Border := false; fside1 := sd1; fside2 := sd3; fside3 := sd4; end function addwnds(stk,vlist,cmd,cmdshow); begin stk.Align := alClient; stk.parent := fside1; vlist.Align := alClient; vlist.parent := fside2; cmd.Align := alBottom; cmd.parent := fside3; cmdshow.Align := alClient; cmdshow.parent := fside3; end function Recycling();override; begin inherited; fside1 := nil; fside2 := nil; fside3 := nil; end fside1; fside2; fside3; end function cmdkeyup(o,e); begin case e.charcode of VK_UP: begin //return ; if FCmdHistoryid <= 0 then return o.text := ""; FCmdHistoryid--; txt := FCmdHistory[FCmdHistoryid]; if ifstring(txt)and txt then o.text := txt; end VK_DOWN: begin if FCmdHistoryid >= Length(FCmdHistory)then return o.text := ""; FCmdHistoryid++; txt := FCmdHistory[FCmdHistoryid]; if ifstring(txt)and txt then o.text := txt; end 13: begin //return ExecuteCommand("docmd"); txt := trim(o.Text); if txt then begin if length(FCmdHistory)>FCmdHistorycount then begin for i := 0 to FCmdHistorycount-1 do begin FCmdHistory[i]:= FCmdHistory[i+1]; end end FCmdHistory[length(FCmdHistory)]:= txt; FCmdHistoryid := length(FCmdHistory); ExecuteCommand("docmd"); end e.skip := true; end end end function getvalewnd(cp); begin if not FValewnd then begin FValewnd := new TTSLDataGrid(self); FValewnd.Visible := false; FValewnd.Caption := "Value"; FValewnd.left := owner.left+100; FValewnd.Width := 600; FValewnd.Height := 500; FValewnd.WSpOPUp := true; FValewnd.WSsYSMenu := true; FValewnd.WsSizeBox := true; FValewnd.Parent := self; FValewnd.OnClose := function(o,e) begin o.Visible := false; o.TSLdata := array(); end end if ifstring(cp)then FValewnd.Caption := cp; return FValewnd; end function deletefuncacheini(); begin plg := pluginpath(); {$ifdef linux} sp := "/"; {$else} sp := "\\"; {$endif} for i := length(plg)-1 downto 1 do begin if plg[i]=sp then begin fn := plg[1:i]+"FunCache.ini"; r := filedelete("",fn); return r; end end end public function addbtns(btns); //添加菜单 begin FBtns := btns; for i,v in Fbtns do begin v.onClick := thisfunction(Dbgtooldo); if v.Caption="添加/删除断点F5" then continue; v.Visible := false; end end function DbgNextLine(); //下一行 begin ExecuteCommand("dbgstepover"); end function serwnd_cclk(o,e); //取消 begin FRemoteWait := false; cancelremotedbg(o,e,"取消调试"); return; end function serwnd_oclk(o,e); //远程连接按钮 begin d := fdbgselwnd.GetData(); addr := d["addr"]; port := d["port"]; if not(addr and port)then return MessageboxA("远程服务器信息不全","提示",0,self.Handle); port := StrToIntDef(port,443); usr := d["usr"]; pwd := d["pwd"]; //连接判断 if checkconnected()then begin disconnectserver(); end if FDebugtype="remotewait" then //远程等待 begin FDebugaddr := addr; FDebugport := port; FDebugUsr := usr; FDebugPwd := pwd; FRemoteWait := true; fdbgselwnd.Visible := false; return _send_(WM_USER,0,0,1); end if 0 <> connectserver(addr,port)then return MessageboxA("远程服务器连接失败","提示",0,self.Handle); if(usr and pwd)and 0 <> dbglogin(usr,pwd)then begin return MessageboxA("登陆用户失败","提示",0,self.Handle); end ExecuteCommand("dbgcreatechannel"); //构造channel if FConnectchannel then begin dbglist(FConnectchannel); end end function dbg_clk(o,e); begin file := o.getstartfilename(d); item := nil; if file=0 then //不存在脚本 begin if 1 <> MessageboxA("没找到本地对应的tsl\r\n是否继续调试","提示",1,self.Handle)then begin return serwnd_cclk(); end end else begin item := owner.OpenAndGotoFileByName(file,1); end o.Visible := false; FRuningItem := item; FCurrentgotoitem := item; parsercurrentitem(item); FAttchedid := d; dbgattach(FConnectchannel,d["id"]); //echo tostn(d); end function Debugremote(flg); begin {$ifdef linux} return MessageboxA("linux目前不支持调试","提示",0,self.Handle); {$endif} if FRemoteWait then begin if flg then begin if 1=MessageboxA("远程调试等待中...\r\n点击确定停止等待..","提示",1,self.Handle)then begin FRemoteWait := false; disconnectserver(); end return; end else begin return MessageboxA("远程调试等待中...","提示",0,self.Handle); end end else begin //if flg then return ; if FConnectchannel then begin return MessageboxA("正在调试中...","提示",0,self.Handle); end end if not fdbgselwnd then begin fdbgselwnd := new tdbgselwnd(self); fdbgselwnd.Parent := self; fdbgselwnd.FHistoryDir := owner.FHistoryDir; fdbgselwnd.loaddata(); fdbgselwnd.OnClose := thisfunction(serwnd_cclk); fdbgselwnd.save_clk := thisfunction(serwnd_oclk); fdbgselwnd.cancel_clk := thisfunction(serwnd_cclk); fdbgselwnd.dbg_clk := thisfunction(dbg_clk); end fdbgselwnd.setlist(); if flg then begin FDebugtype := "remotewait"; fdbgselwnd.setattachwait(true); end else begin FDebugtype := "remote"; fdbgselwnd.setattachwait(false); end fdbgselwnd.show(); return; end function Debuglocal(item); //调试脚本 begin {$ifdef linux} return MessageboxA("linux目前不支持调试","提示",0,self.Handle); {$endif} if not item then return 0; if FConnectchannel then return MessageboxA("正在调试中","提示",0,self.Handle); if FRemoteWait then return MessageboxA("远程调试等待中...","提示",0,self.Handle); FDebugtype := "local"; if checkconnected()then disconnectserver(); //断开连接 FAttchedid := 0; FDebugport := randomfrom(1 -> 600)+20000; FDebugaddr := '127.0.0.1'; FRuningItem := item; FCurrentgotoitem := item; dirs := owner.getlibpathstr(); parsercurrentitem(item); fio := ioFileseparator(); FDebugUsr := 0; FDebugPwd := 0; deletefuncacheini(); getdebuger(pms); exestr := format('"%s" "%s" -DEBUGSERVER -DEBUGLOGIN 0 -WAITATTACH -DEBUGPORT %d -libpath "%s" ',FDebugExe,FRuningfile,FDebugport,dirs); exestr += pms; FDebughandle := sysexec(FDebugExe,exestr,nil,0,rcode,0); if FDebughandle then begin ExecuteCommand("dbgcreatechannel"); ExecuteCommand("showeval","调试程序:"+FDebugExe); if FConnectchannel then begin dbgattachwait(FConnectchannel); end end end function wmuser(o,e):WM_USER;virtual; begin if FRemoteWait and not(checkconnected())then begin if(0 <> connectserver(FDebugaddr,FDebugport))then begin FRemoteWait := false; messageboxa("连接服务器失败","错误",0,self); return; //sleep(100); //_send_(WM_USER,0,0,1); end else begin FRemoteWait := false; FConnectchannel := dbgcreatechannel(); setgdbcallback(); if(FDebugUsr and FDebugPwd)and(0 <>(lgg := dbglogin(FDebugUsr,FDebugPwd)))then begin messageboxa("登陆失败\r\n用户名或者密码错误","登陆失败",0,self); return disconnectserver(); end dbgattachwait(FConnectchannel); FBtns["终止"].Visible := true; end end end function Create(AOwner); begin inherited; FCmdHistory := array(); FCmdHistoryid := 0; FCmdHistorycount := 10; FDebugExe := ""; Caption := "tsl debug ..."; {fimgelist := new tcontrolimagelist(self); fimgelist.Width := 24; fimgelist.height := 24; fimgelist.DrawBimpFirst := true; FToolbar := new TToolBar(self); FToolbar.Visible := false; idx := 0; for i,v in dbugicos() do //工具条 begin bmp := new TBitmap(); bmp.ReadVcon(HexformatStrToTsl( v)); fimgelist.addbmp(bmp); iti := new TToolButton(self); iti.OnClick := thisfunction(Dbgtooldo); iti.Caption := i; iti.imageid := idx; iti.Parent := FToolbar; idx++; end FToolbar.ImageList := fimgelist; FToolbar.Parent := self; } dbwnd := new tdbgwnd(self); dbwnd.Align := alClient; dbwnd.Parent := self; FStackList := new TListView(self); // new TListBox(self); //new tmemo(self);// FStackList.ItemHeight := 23; FStackList.Columns := array(("text":"line","width":40), ("text":"function","width":250) //,("text":"type","width":70) ); //FStackList.ReadOnly := true; //FStackList.Width := 300; FStackList.Border := true; //FStackList.Align := alLeft; //FStackList.Parent := self; FVaraiblesList := new TGroupGridA(self); FVaraiblesList.Border := false; FVaraiblesList.ItemHeight := 23; FVaraiblesList.Columns := array(("text":"name","width":95), ("text":"value","width":135), ("text":"type","width":50) ); FCommandtext := new TEdit(self); //FCommandtext.Border := true; FCommandtext.placeholder := "命令输入框"; FCommandtext.Height := 23; //FCommandtext.Align := alBottom; //FCommandtext.Parent := self; FCommandtext.onkeyup := thisfunction(cmdkeyup); FShowText := new tmemo(self); FShowText.ReadOnly := true; FShowText.Border := true; //FShowText.Align := alClient; //FShowText.Parent := self; pmenu := new TPopUpMenu(self); cmu := new TMenu(self); cmu.OnClick := function(o,e) begin FShowText.Text := ""; end; cmu.Caption := "清除"; cmu.Parent := pmenu; FShowText.PopUpMenu := pmenu; dbwnd.addwnds(FStackList,FVaraiblesList,FCommandtext,FShowText); ExecuteCommand("clearall"); getdefaultdbger(); end function addbreak(item,idx,n); //添加断点 begin if not FConnectchannel then return; parseriteminfo(item,idx,n,usr); if n then begin //echo "\r\n====add:",usr,"====",n,"===",idx; dbgsetbreak(FConnectchannel,usr,n,idx+1); end end function removebreak(item,idx); //移除断点 begin if not FConnectchannel then return; parseriteminfo(item,idx,n,usr); if n then begin //echo "\r\n====remove:",usr,"====",n,"===",idx; dbgunsetbreak(FConnectchannel,usr,n,idx+1); end end function Dbgtooldo(o,e) begin cp := o.Caption; case cp of "调试运行": begin //echo "调试运行"; it := Owner.GetCurrentItem(); //Owner.GetAllPageItems(); Debuglocal(it); end "添加/删除断点F5": begin it := Owner.GetCurrentItem(); if it then begin it.FEditer.SwitchMarkLine(); end end "暂停": begin ExecuteCommand("dbgpause"); end "进入": begin ExecuteCommand("dbgstep") end "单步": begin //dbgstep(); end "下一行(F8)": begin ExecuteCommand("dbgstepover"); end "跳出": begin ExecuteCommand("dbgstepout"); end "继续": begin toolbtnState("继续"); if FCurrentgotoitem and FCurrentgotoitem.FEditer then FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil); ExecuteCommand("dbgrun"); end "终止": begin ExecuteCommand("dbgreset"); end "单步": begin end "刷新符号表": begin ExecuteCommand("dbggetallvalue"); end "刷新当前符号": begin ExecuteCommand("dbggetcurrentnode"); end "清除文本框": begin FShowText.Text := ""; end end; end function dbgeventcall(d); //回调 begin global g_tsldbgcallback_handle; if not ifarray(d)then return; if d["channel"]<> FConnectchannel then return; recvtype := d["recvtype"]; if recvtype=0 then begin FRemoteWait := 0; ExecuteCommand("showeval","调试结束"); if FConnectchannel then dbgdeletechannel(FConnectchannel); FConnectchannel := 0; g_tsldbgcallback_handle := nil; if FCurrentgotoitem and FCurrentgotoitem.FEditer then FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil); FDebughandle := 0; toolbtnState("停止"); return; end //echo "\r\nrectype",format("0x%x",recvtype); if 0x0401=recvtype then begin owner.echoAppendString(d["errmsg"]); return; end if recvtype <> 0x402 then begin return; end case magicgetarray(d,array("result","CmdType"))of "attachlist": begin r := magicgetarray(d,array("result","CmdData")); r :: begin if mcol="createtm" then begin mcell := datetimetostr(mcell); end end return fdbgselwnd.setlist(r); //return echo tostn(r); end "attachwaitok","attachok": // 连接,默认 begin debuginitok(); FVaraiblesList.SetNodeData(array()); FStackList.DeleteAllItems(); //dbgeval(FConnectchannel,getobjtransfunc()); return; end "DebugInfo": //调试信息 begin if "dbgdetach"=remotewaitinit(d)then return; toolbtnState("暂停"); stk := magicgetarray(d,array("result","CmdData","CallStack")); //深度 sybs := magicgetarray(d,array("result","CmdData","SymbolInfo")); //符号 ssybs := magicgetarray(d,array("result","CmdData","EnvInfo")); //系统参数 {if (ssybs = Fdbgssybs) and (sybs = Fdbgsybs) and (stk=Fdbgstack) then //值没变 begin return ; end } if(ssybs <> Fdbgssybs)or(sybs <> Fdbgsybs)then begin FVaraiblesList.SetNodeData(array()); ddd := formatsysvlist(ssybs,nil); FVaraiblesList.SetNodeData(ddd,true); Fdbgssybs := ssybs; ddd := formatvlist(sybs); FVaraiblesList.SetNodeData(ddd,true); Fdbgsybs := sybs; end if stk <> Fdbgstack then begin FStackList.DeleteAllItems(); FStackList.appendItems(stk[:,array("LINE","NAME","USER")]); //FStackList.text := array2str(stks,"\r\n"); Fdbgstack := stk; end if ifarray(stk)then begin FVaraiblesList.celldbclk := thisfunction(vdbclk); FVaraiblesList.celledit := thisfunction(vdoedit); FVaraiblesList.Showarray := thisfunction(vdoshowarray); FStackList.OnDblClick := thisfunction(stkdbclk); it := opengoto(stk[0]); //if not it then return; if it and it <> FCurrentgotoitem then begin if FCurrentgotoitem and FCurrentgotoitem.FEditer then begin FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil); end FCurrentgotoitem := it; end if FCurrentgotoitem then begin FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",stk[0,"LINE"]-1); end end return; end "detached": begin if FConnectchannel then begin dbgdeletechannel(FConnectchannel); FConnectchannel := 0; g_tsldbgcallback_handle := nil; FAttchedid := 0; end FRemoteWait := 0; if FCurrentgotoitem and FCurrentgotoitem.FEditer then FCurrentgotoitem.FEditer.ExecuteCommand("ecruningto",nil); ExecuteCommand("showeval","调试结束"); toolbtnState("停止"); return; end "DebugSysParamValue": begin CmdTypeAux := magicgetarray(d,array("result","CmdTypeAux")); ev := magicgetarray(d,array("result","CmdData")); cp := magicgetarray(d,array("result","CmdParam")); len :=-1; if ifnumber(CmdTypeAux)and(CmdTypeAux .& 0x80000000)then begin len := _shr((int(CmdTypeAux).& 0xFFF0),4); end //echo "\r\n***",len," ",cp," ",tostn(ev); if(cp="#DebugEval")or(cp="#Error")then begin return showevaldata(nil,ev); end if ifarray(ev)then begin ddd := formatsysvlist(array(cp:ev),len); FVaraiblesList.SetNodeData(ddd,true); for i,v in ev do begin if ifstring(i)then begin ncp := tostn(i); ncp := replacetext(ncp,".","\\o"); ncp := cp+".["+ncp+"]"; end else begin ncp := cp+".["+tostn(i)+"]"; end magicsetarray(d,array("result","CmdParam"),ncp); magicsetarray(d,array("result","CmdData"),v); dbgeventcall(d); end return; end else begin ddd := formatsysvlist(array(cp:ev),len); FVaraiblesList.SetNodeData(ddd,true); end end "DebugValue": begin cp := magicgetarray(d,array("result","CmdParam")); ev := magicgetarray(d,array("result","CmdData")); if(cp="#DebugEval")or(cp="#Error")then begin return showevaldata(nil,ev); end if ifarray(ev)then begin //showevaldata(cp,ev); ddd := formatvlist(array(cp:ev)); FVaraiblesList.SetNodeData(ddd,true); for i,v in ev do begin if ifstring(i)then begin ncp := tostn(i); ncp := replacetext(ncp,".","\\o"); ncp := cp+".["+ncp+"]"; end else begin ncp := cp+".["+tostn(i)+"]"; end magicsetarray(d,array("result","CmdParam"),ncp); magicsetarray(d,array("result","CmdData"),v); dbgeventcall(d); end return; end else begin ddd := formatvlist(array(cp:ev)); FVaraiblesList.SetNodeData(ddd,true); end end "noattachederror": begin return disconnectserver(); FRemoteWait := 0; ExecuteCommand("showeval","noattachederror"); d["recvtype"]:= 0; //退出 dbgeventcall(d); return; end else begin //echo tostn(d); end end return; end function showevaldata(cp_,ev); begin cp := cp_; if cp then begin if parseregexpr("\\(\\w+\\)\\.",cp,"r", function(a) begin return ""; end ,s)=1 then begin cp := s; end end if ev and ifarray(ev)then begin fwnd := getvalewnd(cp); fwnd.TSLdata := ev; fwnd.Show(); end else begin if cp then FShowText.Text += ">>"+cp+"\r\n"; ExecuteCommand("showeval",ev); end end function ExecuteCommand(cmd,p); begin case cmd of "dbgstate": begin if ifnil(p)then return FdebugState; end "execommand": begin case p of "#127": begin FShowText.Text := ""; end end; end "docmd": begin s := FCommandtext.Text; if not s then return; FCommandtext.Text := ""; if s="#cls" then return ExecuteCommand("execommand",s); FShowText.Text += ">>"+s+"\r\n"; ExecuteCommand("dbgeval",s); end "clearall": //清除所有 begin //FStackList.items := array(); //FStackList.text := ""; FStackList.DeleteAllItems(); FVaraiblesList.SetNodeData(array()); if p then begin FShowText.Text := ""; FCommandtext.Text := ""; end end "showeval": begin FShowText.Text += "ans="+tostn(p)+"\r\n"; FShowText.ExecuteCommand(FShowText.ecGotoXY,array(100000,1)); end "dbgcreatechannel": begin if not FConnectchannel then begin idx := 0; if not checkconnected()then begin while(FDebugtype="local")and(0 <> connectserver(FDebugaddr,FDebugport)) do begin sleep(100); idx++; if idx>20 then begin return ExecuteCommand("debugconnecterr"); end; end end FConnectchannel := dbgcreatechannel(); setgdbcallback(); end end "dbggetallvalue": begin if FConnectchannel then begin dbggetallvalue(FConnectchannel); end end "dbggetcurrentnode": begin FVaraiblesList.getcurrentnodedata(); end "dbgreset": //停止 begin if FConnectchannel then begin if FDebughandle then begin return SysTerminate(-1,FDebughandle); end if FAttchedid then begin //echo "\r\n终止"; return dbgdetach(FConnectchannel); end else begin if FDebugtype="remotewait" then //远程,断开连接 begin return disconnectserver(); end return dbgdetach(FConnectchannel); //return dbgreset(FConnectchannel); end end end "dbgrun": //运行 begin if FConnectchannel then dbgrun(FConnectchannel); end "dbgstep": begin if FConnectchannel then dbgstep(FConnectchannel); end "dbgpause": //暂停 begin if FConnectchannel then dbgpause(FConnectchannel); end "dbgstepover": //下一行 begin if FConnectchannel then dbgstepover(FConnectchannel); end "dbgstepout": //跳出函数 begin if FConnectchannel then dbgstepout(FConnectchannel); end "dbgeval": //执行 begin if FConnectchannel and p and ifstring(p)then begin getvalewnd("ans"); dbgeval(FConnectchannel,p); end end end end function Recycling();override; begin global g_tsldbgcallback_handle; stopdebug(); inherited; FStackList := nil; FVaraiblesList := nil; FToolbar := nil; FCommandtext := nil; FShowText := nil; fimgelist := nil; FBtns := nil; g_tsldbgcallback_handle := nil; fdbgselwnd := nil; end private function getdefaultdbger(); begin fdefaultdbger := gettslexe(); end function getdebuger(pms); //获得调试程序 begin p := static pluginpath(); FDebugExe := inireadstring("",p+"localediter.ini","debug","debuger",""); pms := " "; //if FDebugExe="1" then //默认获取参数 // begin ps := owner.getexecuteparams(FRuningfile); if ps then begin psi := ps[0]; if fileexists("",psi)then begin cmdexe := psi; end else begin if FDebugExe="1" then ExecuteCommand("showeval","当前指定的执行程序不存在!!"); end psi := ps[1]; if psi and fileexists("",psi)then begin end else begin pms += " "+tostn(psi); end idx := 2; while idx"); end else if fileexists("",FDebugExe)then begin ExecuteCommand("showeval","<用配置文件给定的调试器>"); end else begin FDebugExe := fdefaultdbger; ExecuteCommand("showeval","<用编辑器自带的调试器b:>"); end end function remotedbugok(); begin if FAttchedid then begin ExecuteCommand("showeval","远程启动脚本:"+FAttchedid["info"]); end end function remotewaitinit(d); begin if FDebugtype <> "remotewait" then return; if FAttchedid then return; FAttchedid := magicgetarray(d,array("result","CmdData","StartInfo")); file := fdbgselwnd.getstartfilename(FAttchedid); item := nil; if file=0 then //不存在脚本 begin if 1 <> MessageboxA("没找到本地对应的tsl\r\n是否继续调试","提示",1,self.Handle)then begin dbgdetach(FConnectchannel); return "dbgdetach"; //return serwnd_cclk(); end end else begin item := owner.OpenAndGotoFileByName(file,1); end FRuningItem := item; FCurrentgotoitem := item; parsercurrentitem(item); setbrks(); //设置断点 remotedbugok(); end function debuginitok(); begin if FDebugtype <> "remotewait" then setbrks(); //设置断点 //showbtns(); //显示按钮 ExecuteCommand("showeval","开始调试"); //toolbtnState("暂停"); remotedbugok(); return; end function opengoto(v); begin cn := v["NAME"]; cnn := ""; for ii := 1 to length(cn) do begin if cn[ii]in array(".",":")then begin cn := cnn; break; end cnn += cn[ii]; end f := FDebugtsfs[lowercase(cn)]; if not f then begin return ExecuteCommand("showeval","找不到代码:"+cn); end it := owner.OpenAndGotoFileByName(f,v["LINE"]); return it; end function cancelremotedbg(o,e,s); begin fdbgselwnd.Visible := false; if e then e.skip := true; if FConnectchannel then dbgdeletechannel(FConnectchannel); FConnectchannel := 0; ExecuteCommand("showeval",ifstring(s)?s:"取消远程调试..."); end function stkdbclk(o,e); begin //echo "\r\n",o.SelectedId; id := o.SelectedId; if id >= 0 then begin d := o.GetItem(id); if d then begin return opengoto(d); end end end function vdoshowarray(d); begin //echo tostn(d); try gp := d[3]; if(gp[length(gp)]="+")and parseregexpr("\\+$",gp,"r", function(a) begin return ""; end ,sgp)=1 then begin gp := "sysparams:"+sgp; end showevaldata(gp,d[1]["value"]); except end; end function vdoedit(d,s); begin if not FConnectchannel then return; gp := d[1][3]; try v := eval(&s); except v := nil; end if(gp[length(gp)]="+")and parseregexpr("\\+$",gp,"r", function(a) begin return ""; end ,sgp)=1 then begin dbgsetvalue(FConnectchannel,sgp,d[1][5],v); sleep(20); dbggetvalue(FConnectchannel,sgp,d[1][5]); end else begin //echo "\r\nset: ",gp," ",v; dbgsetvalue(FConnectchannel,gp,0,v); sleep(20); dbggetvalue(FConnectchannel,gp,0); end end function vdbclk(o,e); begin if not FConnectchannel then return; if(e[0]=1)and(e[1][2]="*")then begin gp := e[1][3]; if gp="sysparams+" then return; if(gp[length(gp)]="+")and parseregexpr("\\+$",gp,"r", function(a) begin return ""; end ,sgp)=1 then begin dbggetvalue(FConnectchannel,sgp,e[1][5]); end else begin dbggetvalue(FConnectchannel,gp,0); end end end function parsercurrentitem(item); //修正本地函数 begin FDebugtsfs := class(TTSLCompletion).getdirtsfs(); if item then begin FRuningfile := item.OrigScriptPath; // %% E:\TSUIGROUP\script\tgdb.tsl%%; FDebugtsfs["__main__"]:= FRuningfile; ls := item.FEditer.lines; d := tsl_tokenizeex_2_(item.FEditer.Text,0xffff); for i,v in d["blcks"] do begin s := ls.GetStringByIndex(v["mbeg"]-1); ctls := 0; case v["mtype"]of //函数 11: begin ctls := "function\\s+(\\w+)\\("; end 3: begin ctls := "type\\s+(\\w+)\\s*=\\s*class" //类 end end; if s and ctls and(parseregexpr(ctls,s,"si",m,mp,ml)=1)then begin n := lowercase(m[0,1]); FDebugtsfs[n]:= FRuningfile; end end end end function toolbtnState(flg); begin case flg of "启动","暂停": begin showbtns(); FBtns["暂停"].Visible := false; FBtns["刷新符号表"].Visible := true; FBtns["刷新当前符号"].Visible := true; end "继续": begin //运行 FBtns["继续"].Visible := false; FBtns["进入"].Visible := false; FBtns["跳出"].Visible := false; FBtns["下一行(F8)"].Visible := false; //FBtns["单步"].Visible := false; FBtns["终止"].Visible := false; FBtns["暂停"].Visible := true; FBtns["刷新符号表"].Visible := false; FBtns["刷新当前符号"].Visible := false; end "停止": begin hiddenbtns(); end end end function showbtns(); //显示 begin for i,v in FBtns do begin V.Visible := true; end //FToolbar.Visible := true; end function hiddenbtns(); //隐藏 begin for i,v in FBtns do begin if v.Caption="添加/删除断点F5" then continue; v.Visible := false; end //FToolbar.Visible := false; end function stopdebug(); //结束进程 begin if FDebughandle then begin SysTerminate(-1,FDebughandle); FDebughandle := 0; end end function parseriteminfo(item,idx,n,usr); begin if item=FRuningItem then begin usr := "local"; n := "__main__"; end else begin usr := "system"; end if not n then begin n := getscriptname(item.OrigScriptPath); end end function getscriptname(nn); begin fio := ioFileseparator(); n := ""; for i := Length(nn)-1 downto 1 do begin if fio=nn[i]then begin n := nn[i+1:]; idx := pos(".",n); if idx then begin n := lowercase(n[1:idx-1]); end break; end end return n; end function setbrks(); //初次添加断点 begin its := owner.GetAllPageItems().data; for i,v in FDebugtsfs do begin delii :=-1; for ii,vv in its do begin ifok := vv.ScriptPathIs(v); if ifok then begin delii := ii; lines := vv.FEditer.Lines; for idx := 0 to Lines.Length()-1 do begin if Lines[idx].FMarked then addbreak(vv,idx,i); end break; end end if delii <> 0 then begin reindex(its,array(delii:nil)); end end if FRuningItem then begin lines := FRuningItem.FEditer.Lines; for idx := 0 to Lines.Length()-1 do begin if Lines[idx].FMarked then addbreak(FRuningItem,idx,"__main__"); end end end function setgdbcallback(); //设置回调 begin global g_tsldbgcallback_handle; g_tsldbgcallback_handle := thisfunction(dbgeventcall); dbgsetcallback(FConnectchannel,"return unit(UtslCodeEditor).tdbgcallback();"); end function formatvlist(d); begin r := array(); ncs := array(); { ddd := array(); for i,v in dd do begin ddd[i]["id"] := v["n"]; ddd[i]["data"] := array(v["c"],v["v"],v["t"],v["n"]); ddd[i]["pid"] := v["p"]; end } idx := 0; for i,v in d do begin ri := parservname(i,v); for j,vj in ri do begin id := vj["n"]; if ncs[id]then continue; ncs[id]:= true; r[idx]["id"]:= id; vjt := vj["t"]; vjv := vj["v"]; if vjt="*" then begin vval := array("value":vjv,"font":("color":0xff0000)); end else if ifarray(vjv)then begin vval := array("value":vjv,"font":("color":0)); end else if ifstring(vjt)and(vjt <> "nil")then begin vval := array("value":tostn(vjv),"font":("color":0)); end else begin vval := array("value":"","font":("color":0)); end r[idx]["data"]:= array(vj["c"],vval,vj["t"],vj["n"],id); r[idx]["pid"]:= vj["p"]; r[idx]["nnp"]:= vj["nnp"]; idx++; end end return r; end function formatsysvlist(d,len); begin r := array(); ncs := array(); idx := 0; for i,v in d do begin ri := parsersysname(i,v,len); for j,vj in ri do begin id := vj["n"]; if ncs[id]then continue; ncs[id]:= true; r[idx]["id"]:= id; vjt := vj["t"]; vjv := vj["v"]; if vjt="*" then begin vval := array("value":vjv,"font":("color":0xff0000)); end else if ifarray(vjv)then begin vval := array("value":vjv,"font":("color":0)); end else if ifstring(vjt)and(vjt <> "nil")then begin vval := array("value":tostn(vjv),"font":("color":0)); end else begin vval := array("value":"","font":("color":0)); end r[idx]["data"]:= array(vj["c"],vval,vjt,vj["n"],id,vj["len"]); r[idx]["pid"]:= vj["p"]; r[idx]["nnp"]:= vj["nnp"]; idx++; end end return r; end function gettypename(ev); begin case datatype(ev)of 0:t := "int"; //处理长整型的问题 20:t := "int64"; 24:t := "lstr"; 1:t := "double"; 2:t := "str"; 5:t := "array"; else t := "nil"; end; return t; end function parsersysname(ostring,ev,nlen); begin len := length("*TSL_UNComplete*"); ucp := false; if pos("*TSL_UNComplete*",ostring)=1 then begin ucp := true; if Length(ostring)=len then //空串 begin nstr := ""; return array(); end else nstr := ostring[len+1:]; end else nstr := ostring; r := array(); if ucp then t := "*"; else t := gettypename(ev); nid := ""; r[0]:= array("n":"sysparams+", "c":array("font":("color":0x0000ff,"italic":1),"value":"sysparams") ); if nlen >= 0 then begin nnl := 0x80000000+_shl(nlen,4)+1; cn := ""; if nlen=0 then begin r[1]:= array("n":"+", "c":tostn(""), "len":nnl, "p":"sysparams+" ); end else begin cn := nstr[1:nlen]; r[1]:= array("n":cn+"+", "c":cn, "len":nnl, "p":"sysparams+" ); if nlen"; o := o_; obk := o; try stk := array(); idx :=0; while idx<(ct>0?ct:3) do begin mus[length(mus)] := o; d := o.classinfo(); stk[idx,0] := o; stk[idx,1] := d; inh := d["inherited"]; if not inh then break; o := findclass(inh[0],o); idx++; end for idx := length(stk)-1 downto 0 do begin o:=stk[idx,0]; for i,v in stk[idx,1,"properties"] do begin n := v["name"]; if v["read"] and (v["access"] in array(0,1)) then begin r[n] := 0; end else begin reindex(r,array(n:nil)); end end for i,v in stk[idx,1,"members"] do begin n := v["name"]; if v["access"] in array(0,1) then begin r[n] := 0; end else begin reindex(r,array(n:nil)); end end end rs := mrows(r,1) ; for i := length(rs)-1 downto 0 do begin v := rs[i]; nv := invoke(obk,v); if datatype(nv)=7 then r[v] := ""; else if ifarray(nv) then r[v] := _show_dbg_obj(nv,ct,mus); else if ifobj(nv) then r[v] := _show_dbg_obj(nv,ct,mus); else r[v] := _show_dbg_obj(nv,ct,mus); end except return r; end; return r; end %%; end FStackList; FVaraiblesList; FToolbar; FCommandtext; FShowText; fimgelist; end type TFindListWnd=class(TListBox) //查找的地方 function Create(AOwner); begin inherited; end function CheckListItem(s);override; begin return ifarray(s); end function GetItemText(i);override; begin it := GetItem(i); if it then r := it["caption"]; if not ifstring(r)then return ""; return r; end Published private end type TGoToLineWnd=class(TVCForm) //跳转 function Create(AOwner);override; begin inherited; wssizebox := false; minmaxbox := false; WsDlgModalFrame := true; width := 300; height := 80; caption := "转到.."; FLabel := new TLabel(self); FLabel.SetBoundsRect(array(3,10,70,35)); FEdit := new TEdit(self); FEdit.SetBoundsRect(array(75,10,200,35)); FBtn := new TBtn(self); FBtn.SetBoundsRect(array(210,10,280,35)); FLabel.Caption := "目标位置:"; FBtn.Caption := "定位"; FLabel.parent := self; FEdit.parent := self; FEdit.OnKeyPress := function(o,e) begin if e.CharCode=13 then begin e.skip := true; GotoTextInteger(); end end OnClose := function(o,e) begin o.visible := false; e.skip := true; end FBtn.parent := self; FBtn.OnClick := function(o,e) begin GotoTextInteger(); end end function DoControlAlign();override; begin end function ShowGoto(); begin show(); FEdit.SetFocus(); FEdit.Text := ""; end private function GotoTextInteger(); begin id := FEdit.Text; id := StrToIntDef(id,0); if id>0 then begin it := Owner.GetCurrentItem(); Visible := false; Owner.OpenAndGotoFileByName(it.ScriptPath,id); //it.SetFocus(); //return ; it := Owner.GetCurrentEditer(); if not it then return; //it.ExecuteCommand(it.ecGotoXY,array(id,1)); //Visible := false; it.SetFocus(); end end FEdit; FBtn; end type TTslCodeMap=class(TTreeView) //tsl代码地图 function Create(AOwner); begin inherited; caption := "代码树:支持[左/右/上/下/enter]键"; width := 400; height := 800; WsPopUp := true; WsSysMenu := true; WsSizeBox := true; OnClose := function(o,e) begin o.visible := false; e.skip := true; if not FTreeEditer then return; FTreeEditer.SetFocus(); end OnActivate := function(o,e) begin if not e.wparam then CodeMapLive(o,e); {o.Visible := false; if not FTreeEditer then return; FTreeEditer.SetFocus();} end onKeyPress := thisfunction(CodeMapLive); //OnDblClick := thisfunction(SynNodeSelected); OnSelChanged := thisfunction(SynNodeSelected); end function CodeMapLive(o,e); begin o.Visible := false; if not FTreeEditer then return; FTreeEditer.SetFocus(); end function SynNodeSelected(o,e); begin //双击 if not FTreeEditer then return; nd := CurrentNode; line := nd._tag; if line>0 then begin FTreeEditer.ExecuteCommand(FTreeEditer.ecGoToXY,array(line,1)); end end function hasFocus();override; begin return true; end function ShowMap(); begin FTreeEditer := nil; it := Owner.GetCurrentItem(); if not it then return; //caption := "codemap:"+it.ScriptPath; FTreeEditer := it.FEditer; s := FTreeEditer.Text; if FString <> s then begin FString := s; LoadString(s,FTreeEditer.CaretY); end else GoToTheNode(FTreeEditer.CaretY); end function Recycling();override; begin inherited; FTempNodes := nil; //节点 FEditer := nil; FString := nil; FTreeEditer := nil; end private function LoadString(s,line); begin { 代码块快类型 #define Block_TypeClass 1 #define Block_Function 2 #define Block_Statements 4 #define Block_If 8 #define Block_Else 16 #define Block_SubCase 32 #define Block_Goto_Label 64 #define Block_Empty_Begin_End 128 #define Block_Try 256 #define Block_NeedSql 512 #define Block_UnitStruct 1024 } if s then r := tsl_tokenizeex_2_(s,1+2+4+8+16+32+256+1024+2048+4096); else r := array(); RootNode.RecyclingChildren(); FTempNodes := array(); ScriptDelBlocks(r["blcks"],str2array(s,"\r\n"),self.RootNode,0); GoToTheNode(line); end function GoToTheNode(line); begin nd := FTempNodes[0]; for i,v in FTempNodes do begin if v._tag <= line then begin nd := v; end else if v._tag >= Line then begin SetSel(nd); break; end end Show(); if _wapi.GetFocus()<> Handle then begin SetFocus(); end end function ScriptDelBlocks(blcks,strs,Node,ct); begin if not blcks then return; for i,v in blcks do begin if v["mtype"]<> 1 then begin cnd := CreateTreeNode(); cnd.Caption := trim(strs[v["mbeg"]-1]); cnd._tag := v["mbeg"]; FTempNodes[length(FTempNodes)]:= cnd; cnd.parent := node; end if not cnd then cnd := node; ScriptDelBlocks(v["msub"],strs,cnd,ct+1); end end FTempNodes; //节点 FString; //字符串 FTreeEditer; //编辑框 end type TEditer=class(TCustomcontrol) //包括工具栏,状态栏,输出,查找 function Create(AOwner);override; begin inherited; FOpenHistory := new TMyarrayb(); FFistShows := array(); FSynHCS := New TMyArrayA(); //构造部件 FLastDispathTime := now(); FTslexe := gettslexe() ;//SysExecName(); FTabChar := " "; FTabWidth := 4; FCurrentItemCode := array(); FGoBackA := new TMyarrayB(); FGoBackB := new TMyarrayB(); FToolbar := new TToolBar(self); //工具栏 FStatus := new TStatusBar(self); //状态栏 FInfoShowWnd := new TEditerAuxiliary(self); FPageEditer := new TPageEditer(self); //FPageEditer.CloseBtn := true; FPageEditer.Onbmpbclick := function(o,e) begin it := e._Tag; if not it then return ; if JudgeItemState(it)then return; if it.FEditer.ChangedFlag then begin mr := MessageboxA(format("是否保存:%s",it.OrigScriptPath),"提示",3,self); if mr=IDYES then begin SavePageItem(it); end else if mr=IDCANCEL then begin return; end end DeletePageItem(it); o.CallSelChanged(); end FPageEditer.OnCloseClick := function(o,e) begin it := GetCurrentItem(); if not it then return ; if JudgeItemState(it)then return; if it.FEditer.ChangedFlag then begin mr := MessageboxA(format("是否保存:%s",it.OrigScriptPath),"提示",3,self); if mr=IDYES then begin SavePageItem(it); end else if mr=IDCANCEL then begin return; end end DeletePageItem(it); end; FFindWnd := new TFindWnd(self); //查找 FGotoLineWnd := new TGoToLineWnd(self); //共同 FListPages := new TListPages(self); //tab 跳转页面 FEchoWnd := new TEditerEchoWnd(self); FEchoWnd.font := array("height":16,"width":8,"escapement":0,"orientation":0,"weight":400,"italic":0,"underline":0,"strikeout":0, "charset":0,"outprecision":0,"clipprecision":0,"quality":1,"pitchandfamily":1,"facename":"Courier New","color":0); FTslDebug := new TTslDebug(self); FFindListWnd := new TFindListWnd(self); FCodeMap := new TTslCodeMap(self); FFileopen := new TOpenFileADlg(self); FFileSave := new TSavefileADlg(self); FFileopen.WndOwner := self; FFileSave.WndOwner := self; //初始部件 ////////////////////////////////////// FEchoWnd.Border := true; FEchoWnd.WsSysMenu := false; FEchoWnd.WsSizeBox := false; FEchoWnd.Caption := "echo..."; FFindListWnd.Caption := "find...."; FFindListWnd.OnDblClick := thisfunction(FindListChoosed); FGotoLineWnd.Visible := false; ///////////////////////// FCodeMap.visible := false; FFindWnd.Visible := false; FFileSave.Filter := array("any":"*.*","tsl文件":"*.tsl;*.tsf"); FFileSave.Caption := "另存为"; FFileopen.Filter := array("any":"*.*","tsl文件":"*.tsl;*.tsf"); FPageEditer.OnSelChanged := thisfunction(PageItemSelChanged); //////// FListPages.Visible := false; //////////////////////////// FPageMenu := new TPopUpMenu(self); for i,v in array("关闭","关闭其他标签","复制文件名","复制文件全名","重新加载","打开目录","另存为") do begin mi := new TMenu(self); mi.Caption := v; mi.Parent := FPageMenu; mi.OnClick := thisfunction(PageMenuClick); end FExecuteEditer := new TExecuteEditer(self); FExecuteEditer.visible := false; //////////// FPageEditer.PageItemOnRClick := thisfunction(PageItemOnRClick); FImages := new TControlImageList(self); FImages.Width := 22; FImages.Height := 22; bmp := new TBitmap(); imgs := GetEditIcons(); id := 0; FToolbtns := array(); dbgbtns := array(); for i,v in imgs do begin bmp.Readvcon(HexFormatStrToTsl(v)); FImages.addbmp(bmp); bt := new TToolButton(self); FToolbtns[i]:= bt; bt.OnClick := thisfunction(ToolClick); bt.Caption := i; bt.imageid := id; id++; BT.parent := FToolbar; if i in array("添加/删除断点F5","暂停","继续","进入","跳出","单步","下一行(F8)","终止","刷新符号表","刷新当前符号")then begin dbgbtns[i]:= bt; end end FImages.DrawBimpFirst := true; FTslDebug.addbtns(dbgbtns); FToolbar.ImageList := FImages; FInfoShowWnd.Visible := false; //FInfoShowWnd.WsSysMenu := true; FInfoShowWnd.WSsizebox := true; FInfoShowWnd.height := 200; //FInfoShowWnd.OnSize := thisfunction(DoControlAlign); FInfoShowWnd.OnCloseClick := function(o,e) begin o.visible := false; e.skip := true; DoControlAlign(); end ///////////////////// FStatus.Items := array(("text":"","width":0.85),("text":"","width":0.16)); ///////////////////////////////////////// //FInfoShowWnd.Caption := "信息:"; ////构造节点//////////////////////////////////////////////////// FToolBar.Parent := self; FStatus.Parent := self; FInfoShowWnd.Parent := self; FPageEditer.Parent := self; FCodeMap.parent := self; FGotoLineWnd.Parent := self; FFindWnd.parent := self; FFileopen.parent := self; FFileSave.parent := self; FListPages.parent := self; FExecuteEditer.parent := self; //FEchoWnd FInfoShowWnd.AddWnd(FEchoWnd); FInfoShowWnd.AddWnd(FFindListWnd); FInfoShowWnd.AddWnd(FTslDebug); FTempPageItem := new TPageEditerItem(FPageEditer); ///////////// FSynClasses["txt"]:= array(class(TSynHighLighter),class(TSynCompletion),";txt;"); FSynClasses["tsl"]:= array(class(TTslSynHighLighter),class(TTslCompletion),";tsl;tsf;pas;stm;"); FSynClasses["json"]:= array(class(TJsonSynHighLighter),class(TSynCompletion),";json;"); FSynClasses["ini"]:= array(class(TINISynHigLighter),class(TSynCompletion),";ini;"); FSynClasses["bat"]:= array(class(TBatSynHigLighter),class(TSynCompletion),";bat;cmd;"); FSynClasses["None"]:= array(nil,nil,""); //FSynClasses["tsf"] := FSynClasses["tsl"]; FTslChmHelp := new TTslChmHelp(); FCodeFormatInfo := array("wordct":80,"charct":200,"syn":true,"sel":false,"arraytype":0); FPageEditer.OnDblClick := function(o,e) begin CreateAFile(); end end function PopUpAuxiliary(); begin FInfoShowWnd.ShowPopUp(); end function ClearPageItemMark(it); begin if not it then it := GetCurrentItem(); if not it then return; ed := it.FEditer; ls := ed.Lines; canval := false; for i := 0 to ls.length()-1 do begin li := ls[i]; if li.FMarked then begin li.FMarked := false; canval := true; end end if canval then ed.InValidateRect(nil,false); end function GetAllPageItems(); begin return FPageEditer.PageItems; end function SaveFileByName(n); begin for i,v in FPageEditer.PageItems.Data do begin if v.ScriptPathIs(n)then begin return SavePageItem(v); end end end function GetAllPagesInfo(); begin r := array(); its := FPageEditer.PageItems; for i := 0 to its.Length()-1 do begin it := its[i]; r["pages"][i]["filename"]:= it.OrigScriptPath; edt := it.FEditer; r["pages"][i]["r"]:= edt.TopLine; //edt.CaretY; ls := edt.Lines; f2s := array(); for j := 0 to ls.Length()-1 do begin if ls[j].FMarked then f2s[j]:= true; end r["pages"][i]["f2"]:= f2s; r["pages"][i]["isnewfile"]:= it.fisnewfile; end it := GetCurrentItem(); if it then begin r["currentpage"]:= array(it.OrigScriptPath,it.FEditer.TopLine); end //FPageEditer.DoControlAlign(); return r; end function CloseScriptByFileName(n); begin for i,v in FPageEditer.PageItems.Data do begin if v.ScriptPathIs(n)then begin return DeletePageItem(v); end end end function CloseAllPageItems(it); begin its := FPageEditer.PageItems; tits := its.Data; FPageEditer.CloseAllItem(it); for i,v in tits do begin if v=it then begin cit := it; continue; end v.Recycling(); end if cit then cit.FEditer.ReCreateCaret(); end function SaveAllPageItems(); //保存所有 begin its := FPageEditer.PageItems; for i,v in its.Data do begin JudgeItemState(v); end its := FPageEditer.PageItems; for i := 0 to its.Length()-1 do begin SavePageItem(its[i]); end end function WMUSER(o,e):WM_USER;override; begin inherited; if e.wparam=101 and e.lparam=102 then begin self.Enabled := true; end end function EndFind(); begin FIsFinding := false; _send_(WM_USER,101,102,1); end function DoFind(d,o); begin if FIsFinding then return; o.SetStatusText("查找....."); o.SaveCurrentEditer(); self.Enabled := false; FIsFinding := true; if not(d["c_reg"])then begin if(d["section"]="查找")and(d["btn"]="全部查找")then begin FFindListWnd.Clean(); ShowFindWnd(); FindAllInCurrent(d,o,nil,ct); o.SetStatusText(format("查找到 %d处",ct)); return EndFind(); end else if(d["section"]in array("查找","替换"))and(d["btn"]="查找")then begin FindInCurrent(d,o); return EndFind(); end else if(d["section"]in array("替换"))and(d["btn"]="替换")then begin if d["replace"]<> d["target"]then FindInCurrent(d,o,nil,1); return EndFind(); end else if(d["section"]in array("替换"))and(d["btn"]="全部替换")then begin if d["replace"]<> d["target"]then begin FFindListWnd.Clean(); ShowFindWnd(); ReplaceAllInCurrent(d,o,nil,idx); o.SetStatusText(format("替换 %d处",idx)); end return EndFind(); end else if(d["section"]in array("文件查找"))and(d["btn"]="全部替换")then begin FFindListWnd.Clean(); ShowFindWnd(); FindInFiles(d,o,true,ct); o.SetStatusText(format("总共替换 %d处",ct)); return EndFind(); end else if(d["section"]in array("文件查找"))and(d["btn"]="查找")then begin FFindListWnd.Clean(); ShowFindWnd(); FindInFiles(d,o,false,ct); o.SetStatusText(format("总共查找 %d处",ct)); return EndFind(); end end o.SetStatusText("功能开发中...."); EndFind(); end function DebugPageItem(it,h); begin if not it then return; showdbugwnd(); FTslDebug.Debuglocal(it); end function Debugremote(it); begin showdbugwnd(); FTslDebug.Debugremote(it); end function DbgNextLine(); begin FTslDebug.DbgNextLine(); //FDebuger end function ExecutePageItem(it,h); begin if not it then return; ShowEchoWnd(); //exe :=(FTslExe and ifstring(FTslExe))?FTslExe:SysExecName(); if FEchoWnd.Exeing()then FEchoWnd.Endexe(); s := FExecuteEditer.GetCurrentExuteString(it.Scriptpath); // echo s,"\r\n"; FEchoWnd.Exec(s,"",h); //FEchoWnd.Exec(exe,format('"%s" -libpath "%s"',it.ScriptPath,getdirfromfile(it.ScriptPath)),h); end {function ExecutePageItemWithCmd(it); begin s := FExecuteEditer.GetCurrentExuteString(it.Scriptpath); hd := "d:\\test\\execmd.cmd"; //RewriteString(hd,s); _wapi.WinExec("cmd.exe",1); //_wapi.WinExec("",1); //SysExec("","cmd.exe /c " + s,nil,false,c,nil); //echo "===\r\n"; end } function SavePageItem(it,f); begin if not it then return -1; if f or it.PrePareSave()then begin it.FEditer.ChangedFlag := false; s := it.LastText; case it.EnCode of "UTF8": begin s := AnsiToutf8(it.LastText); end "UTF8 BOM": begin //0xEF, 0xBB, 0xBF s := " "; s[1]:= 0xEF; s[2]:= 0xBB; s[3]:= 0xBF; s += AnsiToutf8(it.LastText); //ECHO "SAVE UTFB-BOM\r\n"; end "UCS2-little": begin s := " "; s[1]:= 0xFF; s[2]:= 0xFE; s += multibytetounicode(it.LastText,936); end "UCS2-big": begin s2 := " "; s2[1]:= 0xFF; s2[2]:= 0xFE; s2 += multibytetounicode(it.LastText,936); s := ""; setlength(s,length(s2)); for i := 1 to length(s2)-1 step 2 do begin s[i]:= s2[i+1]; s[i+1]:= s2[i]; end end end; fp := it.OrigScriptPath; if it.FISstm then begin try v := eval(&s); //s := tostm(v); r := exportfile(ftstream(),"",fp,v); it.ReGetLastLoadTime(); return r; except end end r := ReWriteString(fp,s); it.ReGetLastLoadTime(); return r; end return 1; end function ShowFindWnd(); begin FInfoShowWnd.ShowByTag(FFindListWnd); ShowLogWnd(true); end function showdbugwnd(); begin FInfoShowWnd.ShowByTag(FTslDebug); ShowLogWnd(true); end function ShowEchoWnd(); begin FInfoShowWnd.ShowByTag(FEchoWnd); ShowLogWnd(true); end function SwitchLogWnd(); begin FInfoShowWnd.Visible := not(FInfoShowWnd.Visible); DoControlAlign(); end function SetFindHistroy(d); begin FFindWnd.SetHistory(d); end function GetFindHistory(); begin return FFindWnd.GetHistory(); end function ShowLogWnd(flg); begin n :=(ifnil(flg)or flg)?true:false; if n=FInfoShowWnd.Visible then return; FInfoShowWnd.Visible := n; DoControlAlign(); end function JudgeItemState(it); //状态处理 begin lt := it.GetLastLoadTime(); nlt := it.ReGetLastLoadTime(); if not lt then return; if nlt <> lt then begin FPageEditer.FCanDraged := false; FPageEditer.MouseDrageLeave(); //此处不知为什么会报错 if not nlt then //已经删除 begin if Messageboxa("文件已经被删除,依然保存请按确定","提示",1,self)=IDOK then begin CreateDirWithFileName(it.OrigScriptPath); //新建 SavePageItem(it,true); end else begin DeletepageItem(it); //删除 return true; end end else //被其他程序修改 begin if Messageboxa(format("%s\r\n被其他程序修改是否重新加载",it.ScriptPath),"提示",1,self)=IDOK then begin LoadFromFile(it,true); end else begin it.FEditer.ChangedFlag := true; end end end end function PageItemTextChanged(o,flg); begin its := FPageEditer.Pageitems; cit := GetCurrentItem(); for i := 0 to its.Length()-1 do begin it := Its[i]; if it.FEditer=o then begin if cit=it then begin if it.fisnewfile then Caption := (flg?"*":"")+" new "; else Caption :=(flg?"*":"")+it.OrigScriptPath; end callDatafunction(OnPageEditerChanged,it,flg); it.BitmapA := flg?GetNeedSaveBmp():GetNneedSaveBmp(); return; end end end function DeletePageItem(it); begin idx := FPageEditer.GetItemIndex(it); if idx >= 0 then begin //f := it.OrigScriptPath; FPageEditer.DeleteItemByIndex(idx); it.Recycling(); it := GetCurrentItem(); if it then it.FEditer.ReCreateCaret(); //if it.fisnewfile then filedelete("",f); end end function PageItemSelChanged(o,e);virtual; begin it := GetCurrentItem(); if not it then return; //if JudgeItemState(it) then return ; FCurrentItemCode[length(FCurrentItemCode)]:= it; if it.fisnewfile then begin Caption :=(it.FEditer.ChangedFlag?"*":"")+" new "; end else begin Caption :=(it.FEditer.ChangedFlag?"*":"")+it.OrigScriptPath; end CallDatafunction(FOnPageItemSelChanged,self(true),it); cp := it.FEditer.Completion; if cp and it.FInitCompletion then begin it.FInitCompletion := false; cp.PrePareCompletion(it.Caption); end EditerCaretChanged(it.FEditer,nil); end function PageMenuClick(o,e); begin it := GetCurrentItem(); if not it then return; case o.Caption of "关闭": begin if it.fisnewfile then //单独处理新建关闭 begin f := it.OrigScriptPath; DeletePageItem(it); if fileexists("",f) then filedelete("",f); return ; end if JudgeItemState(it)then return; if it.FEditer.ChangedFlag then begin mr := MessageboxA(format("是否保存:%s",it.OrigScriptPath),"提示",3,self); if mr=IDYES then begin if SavePageItem(it)=0 then begin it.FEditer.ChangedFlag := true; return 0; end end else if mr=IDCANCEL then begin return; end end DeletePageItem(it); end "关闭其他标签": begin Cit := it; its := GetAllPageItems(); for i := 0 to its.Length()-1 do begin it := its[i]; if it.FEditer.ChangedFlag then begin r := MessageBoxA("存在未保存的文件,是否保存!","提示",3,self); if r=IDYES then begin SaveAllPageItems(); break; end else if r=IDCANCEL then begin return; end else begin end break; end end CloseAllPageItems(Cit); end "另存为": begin if JudgeItemState(it)then return; //FFileopen.OverwritePrompt := true; if FFileSave.OpenDlg()then begin fn := FFileSave.FileName; dfn := it.ScriptPath; CreateDirWithFileName(fn); //echo format('FileCopy("","%s","","%s",false)',dfn,fn); ret := FileCopy("",dfn,"",fn,false); if ret then begin it.ScriptPath := fn; if SavePageItem(it)=0 then begin it.FEditer.ChangedFlag := true; end if it.fisnewfile then begin FileDelete("",dfn); it.fisnewfile := false; end end end //FFileopen.OverwritePrompt := false; end "重新加载": begin LoadFromFile(it,true); end "复制文件全名": begin if not FCliper then FCliper := new TClipBoard(self); FCliper.text := it.OrigScriptPath; end "复制文件名": begin if not FCliper then FCliper := new TClipBoard(self); FCliper.text := it.Caption; end "打开目录": begin p := it.ScriptPath; if FileExists("",p)then begin for i := length(p)downto 3 do begin if p[i]="\\" then begin p := p[1:i]; break; end end //_wapi.WinExec('cmd.exe /C start "" "'+p,1); _wapi.openresourcemanager(p); end end "采用cmd执行": begin //ExecutePageItemWithCmd(it); end end end function PageItemOnRClick(o,e); begin if FPageEditer.GetItemIndexByPos(e.pos)>= 0 then o.PopUpMenu := FPageMenu; else o.PoPupMenu := nil; end function PageEditerMenuClick(o,e); begin if pos("复制",o.caption)=1 then begin it := GetCurrentItem(); if it then begin ed := it.FEditer; if ed then begin ed.ExecuteCommand(ed.ecCopy); end //it.FEditer.ReadOnly := not(o.Checked); end return; end else if pos("粘贴",o.caption)=1 then begin it := GetCurrentItem(); if it then begin ed := it.FEditer; if ed then begin ed.ExecuteCommand(ed.ecPaste); end //it.FEditer.ReadOnly := not(o.Checked); end return; end else if pos("剪切",o.caption)=1 then begin it := GetCurrentItem(); if it then begin ed := it.FEditer; if ed then begin ed.ExecuteCommand(ed.ecCut); end //it.FEditer.ReadOnly := not(o.Checked); end return; end else if pos("定位",o.caption)=1 then begin InitShowWndPos(FGotoLineWnd,"g",200,200); FGotoLineWnd.ShowGoto(); return; end else if pos("查看",o.caption)=1 then begin cs := o.Caption; if length(cs)<6 then return; s :=(o.Caption)[6:]; GetCurrentEditer().Tryjump(s); return; end else if pos("只读",o.caption)=1 then begin it := GetCurrentItem(); if it then begin it.FEditer.ReadOnly := not(o.Checked); end return; end else if pos("执行",o.Caption)=1 then begin it := GetCurrentItem(); ExecutePageItem(it); return; end else if pos("停止",o.Caption)=1 then begin if FEchoWnd.Exeing()then FEchoWnd.EndExe(); return; end else if o.Caption = "转换为大写" then begin upperorlowercase(1); end else if o.Caption = "转换为小写" then begin upperorlowercase(0); end else if o.Caption = "删除尾空白" then begin seltrimright(); end end function PageEditerOnRClick(o,e); begin o.popupMenu := nil; if not FPageEditerMenu then begin FPageEditerMenu := new TPopUpMenu(self); FPageEditerMenus := array(); for i,v in array("查看","复制(C)","粘贴(V)","剪切(X)","定位(G)","只读","转换为大写","转换为小写","删除尾空白","执行(F9)","停止执行") do begin it := new TMenu(self); it.Caption := v; it.parent := FPageEditerMenu; FPageEditerMenus[v]:= it; it.OnClick := thisfunction(PageEditerMenuClick); end end rd := FPageEditerMenus["只读"]; if rd then begin zd := GetCurrentItem().FEditer.Readonly; rd.Checked := zd; it := FPageEditerMenus["粘贴(V)"]; if it then it.Enabled := not zd; it := FPageEditerMenus["剪切(X)"]; if it then it.Enabled := not zd; end rd := FPageEditerMenus["查看"]; if rd then begin mtic; it := GetCurrentEditer(); s := it.CanJump(); if s then begin rd.Caption := "查看:"+s; rd.Enabled := true; end else begin rd.Caption := "查看"; rd.Enabled := false; end end ex := FEchoWnd.Exeing()?true:false; rd := FPageEditerMenus["执行(F9)"]; if rd then rd.Enabled := not ex; rd := FPageEditerMenus["停止执行"]; if rd then rd.Enabled := ex; rd := FPageEditerMenus["执行"]; if rd then begin end o.popupMenu := FPageEditerMenu; //MessageBoxA("MESSAGErclick","tis",0); end function createparams(p);override; begin inherited; P.ExStyle := P.ExStyle .| WS_EX_ACCEPTFILES; end {$ifdef linux} function DragQueryFileA(); {$else} function DragQueryFileA(hDrop:pointer;iFile:integer;lpszFile:string;cch:integer):integer;stdcall;external "Shell32.dll" name "DragQueryFileA"; {$endif} function WMDROPFILES(o,e):WM_DROPFILES; begin dn := ""; opends := array(); for i := 1 to DragQueryFileA(e.wparam,0xFFFFFFFF,"",0) do begin len := DragQueryFileA(e.wparam,i-1,nil,0); if len>0 then begin setlength(dn,len+10); if DragQueryFileA(e.wparam,i-1,dn,len+1)>0 then begin opends[length(opends)]:= dn[1:len]; end end end for i,v in opends do begin arr := FileList("",v); if not(pos("D",arr[0,"Attr"]))then OpenAndGotoFileByName(v); end end function GetOpendPageItemByFileName(n); begin its := FPageEditer.PageItems; for i := 0 to its.Length()-1 do begin it := its[i]; if it.ScriptPathIs(n)then return it; end end function EditerCaretChanged(o,e); begin if GetCurrentEditer()=o then begin FStatus.setitemtext(format("col:%d | %s",o.CaretX,o.PageItem.EnCode),1); end end function OpenScriptByFileName(n); begin if not ifstring(n)then return false; it := GetOpendPageItemByFileName(n); if it then return it; fl := FileList("",n); if not(length(fl)=1)then return false; nn := fl[0,"FileName"]; if(POS("d",fl[0,"Attr"]))then return false; it := new TPageEditerItem(FPageEditer); it.FDebuger := FTslDebug; it.FEditer.OnCaretChanged := thisfunction(EditerCaretChanged); it.FEditer.Parent := FPageEditer; it.FEditer.TabChar := FTabChar; it.FEditer.PageItem := it; it.FEditer.QuckKeys := Thisfunction(EditerQuckKeys); it.FEditer.OnTextSetFocus := function(o,e) begin //echo "\r\n",o.PageItem.Scriptpath; JudgeItemState(o.PageItem); end FPageEditer.PageItems.push(it); nn1 := n; nn1[(length(n)-length(nn)+1):]:= nn; //echo nn1,"==",n,"\r\n"; it.ScriptPath := nn1; it.BitmapA := GetNneedSaveBmp(); it.BitmapB := Closebmp(); LoadFromFile(it,true); for i,v in FReadDirs do begin if not ifstring(v)then continue; if pos(v,n)=1 then begin it.FEditer.ReadOnly := true; break; end end //DoControlAlign(); if it then begin SetHistoryFiles(n); it.FEditer.OnRclick := thisfunction(PageEditerOnRClick); it.FEditer.OnTextChanged := thisfunction(PageITEMtextChanged); end return it; end function GetHistoryFiles(); begin return FOpenHistory.Data; end function SetHistoryFiles(v); begin if ifarray(v)then begin for i,vi in v do begin SetHistoryFiles(vi); end return; end if ifstring(v)and v then begin fcadd := true; for i,vi in FOpenHistory.Data do begin if filenameIsTheSame(v,vi)then begin fcadd := false; break; end end if fcadd then begin FOpenHistory.Push(v); if FOpenHistory.Length()>30 then FOpenHistory.shift(); end end end function ShowHistoryWnd(); begin if not FHistoryWnd then begin FHistoryWnd := new TMouseMoveList(self); FHistoryWnd.Visible := false; FHistoryWnd.WSpOPUp := true; FHistoryWnd.Parent := self; FHistoryWnd.Caption := "打开历史...."; FHistoryWnd.WSsysMenu := true; FHistoryWnd.WsSizeBox := true; FHistoryWnd.Width := 400; FHistoryWnd.Height := 600; {FHistoryClearMenuPop := new TPopUpMenu(self); FHistoryClearMenu := new TMenu(self); FHistoryClearMenu.Caption := "清空历史记录"; FHistoryClearMenu.Parent := FHistoryClearMenuPop; FHistoryWnd.PopUpMenu := FHistoryClearMenu; FHistoryClearMenu.OnClick := function(o,e)begin FHistoryWnd.SetData(array()); FOpenHistory.Splices(0,FOpenHistory.Length()); end } FHistoryWnd.OnClose := function(o,e) begin o.EndModal(); o.Visible := false; e.skip := true; end FHistoryWnd.OnClick := function(o,e) begin idx := o.getCurrentSelection(); if idx >= 0 then begin n := o.GetItem(idx); o.EndModal(); O.Visible := false; OpenAndGotoFileByName(n); end end end if FOpenHistory.Length()>0 then begin FHistoryWnd.SetData(FOpenHistory.Data); InitShowWndPos(FHistoryWnd,"history",100,100); FHistoryWnd.ShowModal(); end end function OpenAndGoLineByName(n,L); begin it := OpenScriptByFileName(n); if it then begin if l>0 then begin ed := it.FEditer; ed.ExecuteCommand(ed.ecGoToXY,array(L,1)); end end return it; end function OpenAndGotoFileByName(n,L); begin bit := GetCurrentItem(); if bit then begin if not((ifnil(L)or(L=bit.FEditer.CaretY))and(filenameIsTheSame(n,bit.ScriptPath)))then begin bit := array("file":bit.OrigScriptPath,"line":bit.FEditer.CaretY); if FRebackFlag then FGoBackB.Push(bit); else FGoBackA.Push(bit); end end it := OpenAndGoLineByName(n,L); if it then FPageEditer.SetSel(it); return it; end function CommetCurrentSel(); //注释选择 begin it := GetCurrentEditer(); if it then begin if it.ReadOnly then return; bg := it.BlockBegin; ed := it.BlockEnd; if bg and ed and ed[0]<> bg[0]then begin it.ExecuteCommand(it.ecTab,"//"); end else begin it.ExecuteCommand(it.ecLineStart); it.ExecuteCommand(it.ecString,"//"); end end end function UnCommentCurrentSel(); //取消注释 begin it := GetCurrentEditer(); if it then begin if it.ReadOnly then return; bg := it.BlockBegin; ed := it.BlockEnd; if bg and ed and bg[0]<> ed[0]then begin it.ExecuteCommand(it.ecShifttab,array("//")); end else begin s := it.LineText; if pos("//",s)=1 then begin it.ExecuteCommand(it.ecLineStart); it.ExecuteCommand(it.ecSelLineEnd); if length(s)>= 3 then it.ExecuteCommand(it.ecString,s[3:]); else it.ExecuteCommand(it.ecString,""); end end end end function UnDoCurrentEditer(); begin it := GetCurrentEditer(); if it then begin if it.ReadOnly then return; self.Enabled := false; it.ExecuteCommand(it.ecUndo); self.Enabled := true; if it.ChangedFlag then begin cit := GetCurrentItem(); if it.Text=cit.LastText then // begin it.ChangedFlag := false; end end end end function ToolClick(o,e); // begin case o.caption of "打开文件": begin OpenAFile(); //FPages.OpenAFile(); end "新建": begin CreateAFile(); //FPages.CreateAFile(); end "保存全部": begin return SaveAllPageItems(); end "保存": begin it := GetCurrentItem(); if SavePageItem(it)=0 then begin it.FEditer.ChangedFlag := true; end end "取消注释": begin UnCommentCurrentSel(); end "注释": begin CommetCurrentSel(); end "快捷键说明": begin s := ""; s += "ctrl+o 打开\r\n"; s += "ctrl+N 新建\r\n"; s += "ctrl+s 保存\r\n"; s += "ctrl+F 查找窗口\r\n"; s += "ctrl+R 替换窗口\r\n"; s += "ctrl+a 全选\r\n"; s += "ctrl+c 拷贝选择\r\n"; s += "ctrl+D 复制被插入当前行\r\n"; s += "ctrl+v 粘贴\r\n"; s += "ctrl+x 剪切选择\r\n"; s += "ctrl+G 定位到行\r\n"; s += "ctrl+L|Y 删除当前行\r\n"; s += "tab | shift+tab 多行选中时缩进\r\n"; s += "ctrl+/ 注释当前选择\r\n"; s += "ctrl+\\ 取消当前注释\r\n"; s += "ctrl+U 反撤销\r\n"; s += "ctrl+z 撤销\r\n"; s += "ctrl+tab 切换标签\r\n"; s += "F2 跳转到下一个断点行\r\n"; s += "F5 添加删除断点\r\n"; s += "Alt+F5 将选中字符串转换为大写\r\n"; s += "ctl+F5 将选中字符串转换为小写\r\n"; s += "F3 正向搜索先前搜索的字符\r\n"; s += "ctrl+F3 反向搜索先前搜索的字符\r\n"; s += "ctrl+tab 切换标签页\r\n"; s += "F9 执行当前页的代码\r\n"; s += "ctrl+F9 打开执行代码编辑器\r\n"; s += "F7 显示隐藏日志窗口\r\n"; s += "F1 对于tsl语言查找当前光标所在位置的帮助\r\n"; s += "alt+m 弹出tsl代码地图\r\n"; messageboxa(s,"快捷键说明",0,self); end "撤销": begin UnDoCurrentEditer(); end "反撤销": begin it := GetCurrentEditer(); if it then begin if it.ReadOnly then return; self.Enabled := false; it.ExecuteCommand(it.ecRedo); self.Enabled := true; end end "tsl语法检查": begin it := GetCurrentEditer(); if it then begin if not CheckTslCode(it.Text,err)then begin Messageboxa(err,"提示",0,self); end else messageboxa("符合tsl语法","提示",0,self); end end "tsl代码格式化": begin it := GetCurrentEditer(); if it then begin if 1 <> MessageboxA("将格式化代码!!","提示",1,self.Handle)then return; if it.ReadOnly then return; //sel := FCodeFormatInfo["sel"]; syn := FCodeFormatInfo["syn"]; arraytype := FCodeFormatInfo["arraytype"]; cftype :=(FCodeFormatInfo["cmt"]=1); arraytype :=(arraytype in array(0,1,3))?arraytype:1; sel := true; sel2 := false; if sel then begin s := it.SelText; if s then sel2 := true; end if not s then begin s := it.Text; end if not s then return; if syn then begin if not CheckTslCode(s,err)then begin return Messageboxa(err,"提示-tsl语法错误",0,self); end end try Enabled := false; fs := UNIT(UTslCodeFormat).FormatTsl(s,FTabWidth,wordct,charct,arraytype,cftype); if fs <> s then begin if sel and sel2 then begin it.SelText := fs; end else begin it.Text := fs; it.ExecuteCommand(it.ecGotoXY,array(1,1)); end end finally Enabled := true; end; end end "查找": begin FFindWnd.Show(); end "前进": begin GoToReBack(); end "后退": begin GoToBack(); end "代码地图(alt+m)": begin InitShowWndPos(FCodeMap,"cm",250,100); FCodeMap.ShowMap(); end end end function GetCurrentItem(); begin return FPageEditer.CurrentItem; end function GetCurrentEditer(); begin it := GetCurrentItem(); if it then return it.FEditer; end function DoControlAlign();override; // 对齐 begin if not(FPageEditer and FPageEditer.parent=self)then return; rr := ClientRect; r := rr; th := FToolbar.CalcHeightFixWidth(rr[2]-rr[0]); //FToolbar.Height := th; r[3]:= r[0]+th; FToolBar.SetBoundsRect(r); r := rr; r[1]:= r[3]-FStatus.Height; FStatus.SetBoundsRect(r); rr := rr; rr[1]:= FToolbar.Height+1; rr[3]:= rr[3]-FStatus.Height-1; {if ffolderdlg and ffolderdlg.Visible then begin r := rr; fwd := min(ffolderdlg.Width,integer(r[2] * 0.6)); r[2] := r[0]+fwd; rr[0] := r[2]+1; ffolderdlg.SetBoundsRect(r); end } if FInfoShowWnd.Visible and not(FInfoShowWnd.WSpOPUp)then begin r := rr; r[1]:= r[3]-min(FInfoShowWnd.Height,integer(r[3] * 0.6)); rr[3]:= r[1]-1; {fwd := min(FInfoShowWnd.Width,integer(r[2] * 0.6)); //右侧 r[0] := r[2]-fwd; rr[2] := r[0]-1;} FInfoShowWnd.SetBoundsRect(r); end FPageEditer.SetBoundsRect(rr); end function CreateAFile(); //构造文件 begin if FTslCacheDir then begin idx := 0; while true do begin idx++; fn := FTslCacheDir+"newfile"+ioFileseparator()+"new"+inttostr(idx); if fileexists("",fn) then continue; r := ReWriteString(fn,""); if r=1 then begin it := OpenAndGotoFileByName(fn); it.fisnewfile := true; end return ; end end FFileopen.Caption := "新建文件--输入文件名点击打开"; FFileopen.Multiselected := false; it := GetCurrentItem(); if it then begin s := it.ScriptPath; sp := ioFileseparator(); for i := length(s)downto 2 do begin if s[i]=sp then begin FFileopen.initialDir := s[1:i-1]; break; end end end if FFileopen.Opendlg()then begin exen := FFileopen.FileName; if FileExists("",exen)then begin r := true; end else r := ReWriteString(exen,""); //exportfile(ftstream(),"",exen,"//createBytsl"); if r=1 then OpenAndGotoFileByName(exen); end end function OpenAFile(); //打开文件 begin FFileopen.Caption := "打开文件"; FFileopen.Multiselected := true; it := GetCurrentItem(); if it then begin if not it.fisnewfile then begin s := it.ScriptPath; sp := ioFileseparator(); for i := length(s)downto 3 do begin if s[i]=sp then begin FFileopen.initialDir := s[1:i-1]; break; end end end end if FFileopen.Opendlg()then begin rs := FFileopen.getResults(); //echo tostn(rs); lenrs := length(rs); for i,v in rs do begin if lenrs=1 and not(FileList("",v))then begin if MessageboxA("文件不存在,点击确定新建.点击取消退出","提示",1)=IDOK then begin ReWriteString(v,""); end end OpenAndGotoFileByName(v,1); end end end function GoToBack(); begin FRebackFlag := true; it := FGoBackA.Pop(); if it then OpenAndGotoFileByName(it["file"],it["line"]); FRebackFlag := false; end function GoToReBack(); begin it := FGoBackB.Pop(); if it then OpenAndGotoFileByName(it["file"],it["line"]); end function seltrimright(); begin ed := GetCurrentEditer(); IF not ed then return; //ed.Lines.SetValueByIndex b := ed.BlockBegin; e1 := ed.BlockEnd; try if b and e1 then begin ed.IncPaintLock(); for i := b[0] to e1[0] do begin s1 := ed.Lines.GetValueByIndex(i-1).FStr; s := trimright(s1); if s1=s then continue; ed.Lines.SetValueByIndex(i-1,s); end ed.ExecuteCommand(ed.ecGoToXY,b); ed.ExecuteCommand(ed.ecSelGotoXY,e1); ed.DecPaintLock(); end else begin s1 := ed.LineText; s := trimright(s1); if s1<>s then ed.LineText :=s; end except end; end function upperorlowercase(f); begin ed := GetCurrentEditer(); IF not ed then return; s := ed.SelText; if s then begin b := ed.BlockBegin; e1 := ed.BlockEnd; ed.SelText := f?uppercase(s):lowercase(s); ed.ExecuteCommand(ed.ecGoToXY,b); ed.ExecuteCommand(ed.ecSelGotoXY,e1); end end function EditerQuckKeys(o,e);virtual; //快捷键 begin if e.Result=0 and(ssAlt in e.shiftstate)then begin case e.charcode of VK_F5: //大写 begin upperorlowercase(1); e.skip := true; return true; end ord("M"): begin InitShowWndPos(FCodeMap,"cm",250,100); FCodeMap.ShowMap(); e.skip := true; return true; end end end if ssCtrl in e.ShiftState then begin if e.Result=0 then //down begin case e.CharCode of 220,191: begin if e.CharCode=220 then UnCommentCurrentSel(); else CommetCurrentSel(); e.skip := true; return true; end VK_F5: //小写 begin upperorlowercase(0); return true; end ord("D"): begin ed := GetCurrentEditer(); if not ed then return; if ed.ReadOnly then return; //xy := ed.CaretY; ed.ExecuteCommand(ed.ecLineEnd,nil); S := ed.LineText; ed.ExecuteCommand(ed.ecString,"\r\n"+s); return; end ord("R"): begin InitShowWndPos(FFindWnd,"fr",200,150); FFindWnd.oPENreplace(); FFindWnd.Show(); return true; end ord("E"): begin ed := GetCurrentEditer(); IF not ed then return; s := ed.CaretWords(); if s then ed.Tryjump(s); return true; end ord("F"): begin InitShowWndPos(FFindWnd,"fr",200,150); FFindWnd.OpenFind(); FFindWnd.Show(); return true; end ord("G"): begin InitShowWndPos(FGotoLineWnd,"g",200,200); FGotoLineWnd.ShowGoto(); return true; end ord("O"): begin OpenAfile(); return true; end ord("N"): begin CreateAfile(); return true; end ord("Z"): begin UnDoCurrentEditer(); return true; end ord("S"): begin it := GetCurrentItem(); if 0=SavePageItem(it)then begin it.FEditer.ChangedFlag := true; end return true; end end end else //up begin case e.CharCode of VK_TAB: begin TabChecking(ssShift in e.ShiftState); return true; end VK_F3: begin d := FFindWnd.GetINfo(); d["section"]:= "查找"; d["btn"]:= "查找"; d["c_revers"]:= 1; DoFind(d,FFindWnd); return true; end end end end if e.Result=1 then begin case e.CharCode of 17: begin if e.Result then begin TabCheckChanged(); end end VK_F7: begin SwitchLogWnd(); return true; end VK_F8: begin DbgNextLine(); return true; end VK_F9: begin if ssctrl in e.ShiftState()then begin ShowExeEditer(); return true; end ExecutePageItem(GetCurrentItem()); return true; end VK_F3: begin d := FFindWnd.GetINfo(); d["section"]:= "查找"; d["btn"]:= "查找"; d["c_revers"]:= 0; DoFind(d,FFindWnd); return true; end VK_F1: begin it := GetCurrentItem(); if it.FSynType="tsl" then begin ed := it.FEditer; IF not ed then return; s := ed.CaretWords(); if s then FTslChmHelp.SearchWord(s); end return true; end end; end end function ShowTslLangChm(); begin FTslChmHelp.ShowTslLangChm(); end function InitShowWndPos(wnd,n,ix,iy); //计算初始位置 begin if not FFistShows[n]then begin FFistShows[n]:= true; xy := Clienttoscreen(ix,iy); wnd.left := xy[0]; wnd.top := xy[1]; end end function SetPageItemSyn(it,n); begin if not it then return; if not ifstring(n)then return; if it.FSynType=n then return; hc := GetFreeSynObjectByName(n); if hc then begin cp := hc[1]; it.FEditer.IncPaintLock(); it.FEditer.HighLighter := hc[0]; it.FEditer.Completion := hc[1]; it.FEditer.DecPaintLock(); cp.OnJumpChoosed := function(cmp,d); begin f := d["file"]; nf :=(f?(cmp.GetFileFullPath(f)):GetCurrentItem().OrigScriptPath); //echo "\r\n",nf,"===",d["line"]; OpenAndGotoFileByName(nf,d["line"]); end cit := GetCurrentItem(); if cit=it then begin it.FInitCompletion := false; cp.PrePareCompletion(it.Caption); end else begin it.FInitCompletion := true; end it.FSynType := n; end else begin it.FEditer.IncPaintLock(); it.FEditer.HighLighter := nil; it.FEditer.Completion := nil; it.FEditer.DecPaintLock(); it.FSynType := n; end end function Recycling();override; begin inherited; FSynHCS := nil; FCurrentItemCode := array(); FPageEditer := nil; FToolbar := nil; FStatus := nil; FInfoShowWnd := nil; FPageMenu := nil; FPageEditerMenu := nil; FPageEditerMenus := array(); FOnPageEditerChanged := nil; fOnPageItemSelChanged := nil; FListPages := nil; FCodeMap := nil; FEchoWnd := nil; FFindListWnd := nil; FTempPageItem := nil; FExecuteEditer := nil; FTslDebug := nil; end function GetSynTypeNames(); begin return FSynClasses.IndexNames(); end function SetCodeFormatInfo(d); begin if ifarray(d)then FCodeFormatInfo := d; else return FCodeFormatInfo; end function getexecuteparams(f); //获得当前的执行参数 begin return FExecuteEditer.GetCurrentExuteparams(f); end function ShowExeEditer(flg); begin if ifnil(flg)or flg then begin InitShowWndPos(FExecuteEditer,"exe",200,200); FExecuteEditer.showexeediter(); end else begin FExecuteEditer.Visible := false; end end function getlibpathstr(); begin dirs := ""; fio := ioFileseparator(); for i,v in FTslSearchDir do begin if ifstring(v)then begin if v[length(v)]=fio then begin dirs += v; end else begin dirs += v; dirs += fio; end end dirs += ";"; end return dirs; end function echoAppendString(s); begin FEchoWnd.AppendString(s); end published //property 位置 FHistoryDir; property OnPageEditerChanged read FOnPageEditerChanged write FOnPageEditerChanged; property OnPageItemSelChanged read FOnPageItemSelChanged write FOnPageItemSelChanged; property TslSearchDir read FTslSearchDir write SetTslSearchDir; property TslCacheDir read FTslCacheDir write SetTslCacheDir; property TabWidth read FTabWidth write SetTabWidth; property TabChar read FTabChar; property Tslexe read FTslExe write FTslExe; property ReadOnlyDirs read FReadDirs write FReadDirs; protected class function Sinit();override; begin inherited; if not FSynClasses then FSynClasses := new TMyArrayA(); end class function GetSynTypeByFileType(ft); begin if not string(ft)then return "txt"; nft := lowercase(ft); for i,v in FSynClasses.IndexNames() do begin dv := FSynClasses[v]; dvf := dv[2]; if ifstring(dvf)then begin if pos(";"+nft+";",dvf)then begin return v; end end end return "None"; end class function RegSynType(n,h,c,files); begin if ifstring(n)and(h is class(TSynhighLighter))and(c is TSynCompletion)then begin FSynClasses[n]:= array(h,c,files); end end class function UnRegSynType(n,h,c); begin if ifstring(n)then begin FSynClasses.DeleteIndex(n); end end { r["section"] := CurrentITem.Caption; r["target"]:= FEdit_target.Editer.Text; r["replace"]:= FEdit_repace.Editer.Text; r["filetype"] := FEdit_type.Editer.Text; r["dir"] := FEdit_dir.Editer.Text; r["c_revers"]:=FCheck_revers.Checked; r["c_cycle"]:= FCheck_cycle.Checked; r["c_wrap"] := FCheck_wrap.Checked; r["c_case"] := FCheck_case.Checked; r["c_reg"] := FCheck_reg.Checked; r["c_dir"] := FCheck_subdir.Checked; } function ReplaceAllInCurrent(data,fo,it,idx); begin data["c_revers"]:= 0; data["c_cycle"]:= 0; if not it then it := GetCurrentItem(); if not it then return; ed := it.FEditer; if not ed then return; idx := 0; try ed.IncPaintLock(); ed.ExecuteCommand(ed.ecGotoXY,array(1,1)); cidx := 0; while FindInCurrent(data,fo,it,1)=0 do begin if idx=0 then begin FFindListWnd.AppendItem(array("caption":format("replace:%s in file:%s",data["target"],it.OrigScriptPath))); end if idx>0 then begin ed.MergeLastUndo(); end idx++; L := ed.CaretY; if cidx=L then continue; cidx := L; scap := format(" %d:(第%d行) ",idx,L)+trim(ed.LineText); FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":L)); end finally ed.DecPaintLock(); end //fo.SetStatusText(format("共替换:%d 处",idx)); end function FindInFiles(d,o,rep,ct); begin fs := GetFilesFormSearchInfo(d); ct := 0; for i,v in fs do begin if not FIsFinding then break; o.SetStatusText("查找文件:"+i); it := GetOpendPageItemByFileName(i); if not it then begin FTempPageItem.ScriptPath := i; LoadFromFile(FTempPageItem,false); it := FTempPageItem; end if rep then begin ReplaceAllInCurrent(d,o,it,idx); SavePageItem(it); end else begin FindAllInCurrent(d,o,it,idx); end ct += idx; end end function FindInCurrent(data,fo,it,rep); begin if not it then it := GetCurrentItem(); if not it then return-2; ed := it.FEditer; if not ed then return-2; cy := ed.CaretY; cx := ed.CaretX; wordwrap := data["c_wrap"]; fs := data["target"]; if not(fs and ifstring(fs))then begin fo.SetStatusText("查找内容为空!"); return-2; end stringiswrapword := isCaseWords(fs); if data["c_case"]then fs := lowercase(fs); rstring := data["replace"]; lfs := length(fs); L := ed.Lines; ct := L.length(); if data["c_revers"]then begin for i := cy-1 downto cy-ct do begin ridx := i; if data["c_cycle"]then begin ridx :=(ridx<0)?(ridx+ct):ridx; end if ridx<0 then begin fo.SetStatusText("到达顶部"); return-2; end s := L.GetStringByIndex(ridx); ls := length(s); while cx-lfs+1>1 do begin if not FIsFinding then return-2; TryDispatch(); subs := s[cx-lfs:cx-1]; if data["c_case"]then subs := lowercase(subs); if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了 begin ed.ExecuteCommand(ed.ecGotoXY,array(ridx+1,cx)); ed.ExecuteCommand(ed.ecSelGotoXY,array(ridx+1,cx-lfs)); if rep then begin ed.SelText := rstring; end fo.SetStatusText(format("位置: %d %d",ridx+1,cx-lfs)); return 0; end cx--; end tidx := ridx-1; if data["c_cycle"]then begin tidx += ct; tidx := tidx mod ct; end else begin if tidx<0 then begin fo.SetStatusText("到达顶部"); return-2; end end s := L.GetStringByIndex(tidx); cx := length(s)+1; end fo.SetStatusText("到达顶部"); return-2; end for i := 0 to ct do begin ridx := i+cy-1; if data["c_cycle"]then begin ridx := ridx mod ct; end if ridx >= ct then begin fo.SetStatusText("到达底部"); return-2; end s := L.GetStringByIndex(ridx); ls := length(s); while cx+lfs-1 <= ls do begin if not FIsFinding then return-2; //GetAndDispatchMessageA(); TryDispatch(); subs := s[cx:cx+lfs-1]; if data["c_case"]then subs := lowercase(subs); if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了 begin ed.ExecuteCommand(ed.ecGotoXY,array(ridx+1,cx)); ed.ExecuteCommand(ed.ecSelGotoXY,array(ridx+1,cx+lfs)); if rep then begin ed.SelText := rstring; end fo.SetStatusText(format("位置: %d %d",ridx+1,cx)); return 0; end //没找到 cx++; end cx := 1; end fo.SetStatusText("到达底部"); return-2; end function FindListChoosed(o,e); begin it := o.GetItem(o.GetCurrentSelection()); if ifarray(it)then begin f := it["file"]; l := it["line"]; if ifstring(f)and l >= 0 then begin OpenAndGotoFileByName(f,l); end end end function TryDispatch(); begin {$ifdef linux} return; {$endif} t := now(); if(t-FLastDispathTime)>0.25e-5 then begin FLastDispathTime := t; GetAndDispatchMessageA(); end end function FindAllInCurrent(data,fo,it,rt); begin rt := 0; if not it then it := GetCurrentItem(); if not it then return; ed := it.FEditer; if not ed then return; wordwrap := data["c_wrap"]; fs := data["target"]; if not(fs and ifstring(fs))then return fo.SetStatusText("找到 0 处"); if data["c_case"]then fs := lowercase(fs); stringiswrapword := isCaseWords(fs); lfs := length(fs); L := ed.Lines; ct := L.length(); cidx := 0; for i := 0 to ct-1 do begin s := L.GetStringByIndex(i); ls := length(s); cx := 1; while cx+lfs-1 <= ls do begin if not FIsFinding then return rt; //GetAndDispatchMessageA(); TryDispatch(); subs := s[cx:cx+lfs-1]; if data["c_case"]then subs := lowercase(subs); //((stringiswrapword .& 2) and (IsWordsChar(s,cx-1,ls)) ( (stringiswrapword .& 1) and IsWordsChar(s,cx+lfs,ls)) ) if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了 begin if rt=0 then FFindListWnd.AppendItem(array("caption":format("find:%s in file:%s",fs,it.OrigScriptPath),"file":it.OrigScriptPath,"line":1)); cx += lfs; rt++; if cidx=i+1 then continue; cidx := i+1; scap := format(" %d:(第%d行) ",rt,i+1)+trim(s); FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":i+1)); continue; end //没找到 cx++; end end return rt; end function isCaseWords(s); //判断全词匹配 begin if ifstring(s)and s then begin len := length(s); if len=1 then return IsWordsChar(s,1,1); return IsWordsChar(s,1,1).|(2 * IsWordsChar(s,len,len)); end end function IsWordsChar(s,idx,len); begin if not(len>0)then len := length(s); if idx>len then return true; if idx<1 then return true; ivi := ord(s[idx]); if(ivi<48)or(ivi>57 and ivi<65)or(ivi>90 and ivi<95)or(ivi>95 and ivi<97)or(ivi>122 and ivi <= 127)then return true; end function TabCheckChanged(); begin if not FListPages.Visible then return; FListPages.Visible := false; n := FListPages.GetSelFileName; OpenAndGotoFileByName(n); end function TabChecking(f); begin its := FPageEditer.PageItems; if not(its.Length()>1)then return FCurrentItemCode := array(); if FListPages.Visible then begin FListPages.IncIndex((f>0)?1:(-1)); end else begin //初始化 bit := GetCurrentItem(); for i := 0 to its.Length()-1 do begin it := its[i]; it.FPageOrderId := 0; end idx := 1; for i := length(FCurrentItemCode)-1 downto 0 do begin it := FCurrentItemCode[i]; if it.FPageOrderId<1 then it.FPageOrderId := idx++; end sr := array(); for i := 0 to its.Length()-1 do begin it := its[i]; sv := it.OrigScriptPath; if it.FEditer.ChangedFlag then sv := "*"+sv; sr[i,0]:= sv; sr[i,1]:= it.FPageOrderId; sr[i,2]:= it; if it.FPageOrderId=0 then begin it.FPageOrderId := idx++; end end sit := sselect[0]from sr order by[1]asc end; FCurrentItemCode := sselect[2]from sr order by[1]desc end; FListPages.SetData(sit); FListPages.IncIndex(-1); xy := ClientToScreen(100,100); FListPages.Top := xy[1]; FListPages.Left := xy[0]; //FListPages.SetBoundsRect(array(xy[0],xy[1],xy[0]+600,xy[1]+600)); //FListPages.Visible := true; FListPages.Show(SW_SHOWNOACTIVATE); //bit.FEditer.SetFocus(); end end function GetFreeSynObjectByName(n); begin if not ifstring(n)then return; lns := FSynHCS[n]; if not lns then begin lns := new TMyARRayB(); FSynHCS[n]:= lns; end for i := 0 to lns.length()-1 do begin vi := lns[i]; if not(vi[0].Memo)then return vi; end hc := CreateASynObject(n,self); if hc then begin lns.Push(hc); return hc; end end public FExecuteEditer; private class function CreateASynObject(n,ow); begin c := FSynClasses[n]; //if not c then c := FSynClasses["txt"]; if c then begin if ifobj(c[0])and ifobj(c[1])then return array(CreateObject(c[0],ow),CreateObject(c[1],ow)); end end static FSynClasses; FCodeFormatInfo; FTslChmHelp; FFistShows; FSynHCS; FLastDispathTime; FIsFinding; FOnPageEditerChanged; FPageEditerMenu; FPageEditerMenus; fOnPageItemSelChanged; FReadDirs; FCurrentItemCode; FGoBackA; // := new TMyarrayB(); FGoBackB; // := new TMyarrayB(); FRebackFlag; FPageEditer; FToolbar; FStatus; FInfoShowWnd; FCodeMap; FListPages; FFindWnd; FFindListWnd; FEchoWnd; FGotoLineWnd; FFileopen; FFileSave; FPageMenu; //图标 FNeedSaveBmp; FNotNeedSaveBmp; FBmpClose; FTabWidth; FTabChar; FTslexe; FTslSearchDir; FTslCacheDir; FTempPageItem; FOpenHistory; FHistoryWnd; FTslDebug; private function GetFilesFormSearchInfo(d); begin r := array(); dir := d["dir"]; if not dir then return r; ft := d["filetype"]; if ft then begin ft := str2array(ft,";"); end if not ft then ft := array("*"); FindFiles(dir,ft,d["c_dir"],r); return r; end function FindFiles(dir,ft,sub,ret); begin dir_ := dir; sp := ioFileseparator(); if not(dir_[length(dir_)]=sp)then dir_ += sp; if sub then begin dirs := FileList("",dir_+"*"); for i,v in dirs do begin TryDispatch(); if not FIsFinding then return; fn := v["FileName"]; if(pos("D",v["Attr"]))and not(fn in array(".",".."))then begin FindFiles(dir_+fn,ft,sub,ret); end end end for i,v in ft do begin vi := trim(v); if not vi then continue; fs := FileList("",dir_+vi); for j,vj in fs do begin if(POS("D",vj["Attr"]))then continue; ret[dir_+vj["FileName"]]:= true; end end end function SetTslCacheDir(d); begin if FTslCacheDir=d then return; if ifstring(d)then begin FTslCacheDir := d; class(TTSLCompletion).SetCacheDir(d); end end function SetTslSearchDir(d); begin if FTslSearchDir=d then return; if ifarray(d)then begin FTslSearchDir := d; class(TTSLCompletion).SetFindDirs(d); its := GetAllPageItems(); for i := 0 to its.Length()-1 do begin it := its[i]; it.RepreComple := true; end end end function SetTabWidth(n); begin if not(n >= 0)then return; nn := integer(n); if nn >= 0 and nn <> FTabWidth then begin FTabWidth := nn; if nn=0 then FTabChar := "\t"; else begin FTabChar := ""; for i := 1 to nn do begin FTabChar += " "; end end its := FPageEditer.PageITems; for i := 0 to its.Length()-1 do its[i].FEditer.TabChar := FTabChar; end end function getdirfromfile(p); begin r := ""; if not ifstring(p)then return r; sp := ioFileseparator(); for i := length(p)downto 1 do begin if p[i]=sp then return p[1:i]; end return r; end function LoadFromFile(it,ifinit); begin p := it.ScriptPath; sz := filesize("",p); if readFile(rwRaw(),"",p,0,sz,s)then begin it.ReGetLastLoadTime(); if lowercase(p[length(p)-3:length(p)])=".stm" then begin try if s then begin v := stm(s); s := tostn(v); end it.FEditer.ReadOnly := true; it.FISstm := true; except end end edt := it.FEditer; tl := edt.TopLine; cxy := edt.CaretXY; it.SetLoadScript(s); if ifinit then begin InitScriptHighLighter(it); edt.TopLine := tl; edt.ExecuteCommand(edt.ecGotoXY,cxy); end end else begin //MessageBoxA(s,"提示",0,self); it.ReGetLastLoadTime(); it.SetLoadScript(s); it.FEditer.ReadOnly := true; //设置为自读 end end function InitScriptHighLighter(it); begin p := it.ScriptPath; for i := length(p)downto 3 do begin if p[i]="." then begin synt := GetSynTypeByFileType(p[i+1:]); return SetPageItemSyn(it,synt); end end end function GetNNeedSaveBmp(); begin if not FNOTneedSaveBmp then begin s := "0502000000060400000074797065000203000000696D670006040000006461746 100027701000089504E470D0A1A0A0000000D4948445200000030000000300806 0000005702F987000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000010C49444154 6843ED9AC1AA83500C05FBFFBFE84E45117521A21B955B023790B6E73D5B29490 A199876D148CFACDB5B5DD7A9288A9FB1AAAA741C47626EE8C8BBEBBAE6F92701 C3309889F6B06F07C8436DD01E360234407BD808D000ED61234003B4878D000DD 01E360234407BD808D000ED61234003B4878D000DD01E360234407BD88F02AC44 7B58FA9CF937C0AB11606D04581B01D64680B59702BE0D8D40DFF38E11F00D222 0732960DFF7D434CD8BD334E58B73CC03D08D4940DBB6F0E85989AB007AE9BA0E 1E4A25EE0288B30889CB00A2EF7BF80029711B40FC1521711D40A01F9A25EE038 8711C1F1E9258069465F9F85F89FCFE11DBB6A5799E5F5C96255FE87129C0133F 1E90D21D478EF0B86077F81A0000000049454E44AE42608200"; FNOTneedSaveBmp := new TBitmap(); FNOTneedSaveBmp.ReadVcon(HexFormatStrToTsl(s)); end return FNOTneedSaveBmp; end function Closebmp(); begin if not FBmpClose then begin FBmpClose := new TBitmap(); s := "0502000000060400000074797065000203000000696D670006040000006461746 100025601000089504E470D0A1A0A0000000D494844520000001C000000100806 00000005CF1FEF000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000EB49444154 484B63F88F03FC7DFCF0FFEF3327C9C6B8005E0BDF19A89285BFB637424DC1040 42DFC36B1FBFFD7E61A0C43D1F17B0BDDFF7FAE5DFEFFC1C789320B3F0679FEFF 73E7365E4BDF3B9881D57C9F3E09CCA7C84210865BDA5A0F1783E10F1E7628968 130C5168230CCD26F3D6D08B100370CCB40982A168230DCD2C9BD7036BA65204C 350B411866112ECB40983616DEBE497B0B9183F163A007381BD02C48B1C5D9072 F47AC96526C21CCB26FD326A2180CC21F5CAC302CA5C842B865FD9D7003D1F17B 5B63144B29B2105CB4B537A058800DBF37D7A14ED1460E26DB426CD50EB1183BF 8FF1F00B989BEC710621E4C0000000049454E44AE42608200"; FBmpClose.ReadVcon(HexformatStrToTsl(s)); end return FBmpClose; end function GetNeedSaveBmp(); begin if not FNeedSaveBmp then begin s := "0502000000060400000074797065000203000000696D670006040000006461746 10002A701000089504E470D0A1A0A0000000D4948445200000030000000300806 0000005702F987000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000013C49444154 6843ED8FBB4A43511045F32F7E908D95BDAD551A6DAC6C6CB4110276368282852 00ADAD908B6E94212141F49A110BC820FC2918133307A3737C925CC4C6016AC34 9993ECD5E8AF1EA4F6D2E6C2D85B69A5F1C757621AE8C8BBC56D37CF9F1030DCB B3613ED61A70E9087DAA03D6C046880F6B011A001DAC3468006680F1B011AA03D 6C046880F6B011A001DAC3468006680F1B011AA03D6C046880F6B033055889F6B 0F43D5319E0D508B03602AC8D006B23C0DA5A01F38646A0FF99C60898071190A9 15F0F35AA4FBB5C3926FC777F96232E601E8C624E061FD081EFD57E22A803E1E9 B27F0502A7117403C6D9CC26356E2328078DE3A830F4889DB00E265FB1C3E92B8 0E20063B97A54712F701C470F7EACF2389654077793F8D8BCFFC2B1501557C0F4 66974D12EF97ED3C9177AD40AF0C48207A4F40B898CCDD8EC600A800000000049 454E44AE42608200"; FNeedSaveBmp := new TBitmap(); FNeedSaveBmp.ReadVcon(HexFormatStrToTsl(s)); end return FNeedSaveBmp; end end implementation type tdbgselwnd=class(tdcreateform) uses tslvcl; label1:tlabel; furl:tedit; label2:tlabel; fport:tedit; label3:tlabel; fusr:tedit; label4:tlabel; label5:tlabel; fpwd:tpassword; fdir:tedit; fdiag:tfolderchooseadlg; flist:tlistview; fcbtn:tbtn; flogout:tbtn; flogin:tbtn; fdbg:tbtn; cancel_clk; save_clk; dbg_clk; fhistorydir; function Create(AOwner);override; //构造 begin inherited; Visible := false; Loader.LoadFromTfmScript(self,getinfo()); flist.Columns := array( ("text":"ID号","width":150), ("text":"信息","width":300), ("text":"创建时间","width":100) ); flogout.top := 140; flogout.OnClick := function(o,e) begin calldatafunction(cancel_clk,self,e); end flogin.OnClick := function(o,e) begin if fhistorydir and ifstring(fhistorydir)then begin Fremotepath := fhistorydir+"remoteinfo.tsm"; d := getdata(); Exportfile(ftstream(),"",Fremotepath,d); end calldatafunction(save_clk,self,e); end fdbg.onclick := function(o,e) begin calldatafunction(dbg_clk,self,e); end setlist(); end function setattachwait(flg); //设置登陆样式 begin if flg then begin Height := 210; end else begin Height := 550; end end function loaddata(); //导入数据 begin if fhistorydir and ifstring(fhistorydir)then begin Fremotepath := fhistorydir+"remoteinfo.tsm"; if fileexists("",Fremotepath)and(1=importfile(ftstream(),"",Fremotepath,d))then begin setdata(d); end end end function getdata(); begin r := array(); r["addr"]:= furl.text; r["port"]:= fport.text; r["usr"]:= fusr.text; r["pwd"]:= fpwd.text; r["dir"]:= fdir.text; return r; end function tserlogersimplewnd1_close(o;e);virtual; begin e.skip := true; end function Recycling();override; //回收变量 begin inherited; ci := self.classinfo(); //将成员变量赋值为nil避免循环引用 for i,v in ci["members"] do begin if v["static"]then continue; invoke(self,v["name"],nil); end end function getdir(); begin if fdiag.ChooseDlg()then begin fdir.text := fdiag.Folder; end end function setlist(d); begin FList.DeleteAllItems(); fdbg.Enabled := false; if d and ifarray(d)then begin FList.appendItems(d); FList.SelectedId := 0; fdbg.Enabled := true; end end function getstartfilename(sv); begin dirt := fdir.Text; if not sv then sv := FList.SelectedValue; if dirt and sv then begin if sv then begin fs := sv["info"]; if fs then begin for i := length(fs)-1 downto 1 do begin if fs[i]in array("\\","/")then begin fs := fs[i+1:]; break; end end return gettruefile(dirt,fs,ioFileseparator()); end end end end private function getinfo(); begin return %% object tserlogersimplewnd1:tserlogersimplewnd caption="远程调试" color=0xFFFFFF top=100 height=550 minmaxbox=false onclose=tserlogersimplewnd1_close width=580 wsdlgmodalframe=true wssizebox=false object label1:tlabel left=4 top=3 width=80 height=25 caption="服务器地址" end object furl:tedit height=25 left=88 tabstop=true top=3 width=204 end object label2:tlabel left=296 top=3 width=34 height=25 caption="端口" end object fport:tedit height=25 left=333 tabstop=true top=3 width=62 end object label3:tlabel left=2 top=38 width=80 height=25 caption=" 用户名" end object fusr:tedit height=25 left=88 tabstop=true top=38 width=300 end object label4:tlabel left=2 top=72 width=80 height=25 caption=" 密 码" end object label5:tlabel left=2 top=100 width=80 height=25 caption=" 脚本目录" end object fpwd:tpassword height=25 left=88 tabstop=true top=72 width=300 end object fdir:tedit height=25 left=88 tabstop=true top=100 width=300 end object fcbtn:tbtn caption="..." height=25 left=390 tabstop=true top=100 width=22 onclick=getdir end object flogout:tbtn an1chors=[akright akbottom] caption="取消" height=23ff left=375 tabstop=true top=480 width=74 end object fdbg:tbtn an1chors=[akright akbottom] caption="调试" height=23 left=470 tabstop=true top=480 width=74 end object flogin:tbtn caption="连接" height=23 left=470 tabstop=true top=140 width=74 end object flist:tlistview anch1ors=[akTop akright akLeft akBottom] height=290 left=2 top=180 width=560 end object fdiag:tfolderchooseadlg caption="执行目录" end end %%; end private function setdata(d); begin if not ifarray(d)then return; furl.text := d["addr"]; fport.text := d["port"]; fusr.text := d["usr"]; fpwd.text := d["pwd"]; fdir.text := d["dir"]; end function gettruefile(dir,n,fio); begin if dir and ifstring(dir)then begin rfile := dir+fio+n; if fileexists("",rfile)then return rfile; for i,v in FileList("",dir+fio+"*") do begin fn := v["FileName"]; if pos("D",v["Attr"])and not(fn in array(".",".."))then begin rfile := gettruefile(dir+fio+fn,n,fio); if rfile then return rfile; end end end end end function tdbgcallback(); begin global g_tsldbgcallback_handle; if g_tsldbgcallback_handle then call(g_tsldbgcallback_handle,sysparams); end function filenameIsTheSame(p1,p2); begin if not(ifstring(p1)and ifstring(p2))then return 0; if p1=p2 then return 1; {$ifdef linux} {$else} return lowercase(p1)=lowercase(p2); {$endif} end type TMouseMoveList=class(TListBox) function Create(AOwner);override; begin inherited; FCurrentIndex :=-1; end function MouseMove(o,e);override; begin inherited; idx := GetIdxByYpos(e.ypos); if FCurrentIndex <> idx then begin FCurrentIndex := idx; InValidateRect(nil,false); end end function getItemText(i);override; begin r := inherited; return " "+r; end function PaintIdx(idx,rc_,cvs);virtual; begin {** @explan(说明)绘制项 %% @param(item)(TCustomListItem) 项 %% @param(rc)(array) 绘制区域%% @param(cvs)(tcanvas) 画布 %% **} inherited; if idx=FCurrentIndex then begin rc := rc_; rc[2:3]-= 1; cvs.pen.Color := rgb(30,144,255); cvs.draw("Polyline",array(rc[0:1],(rc[2],rc[1]),(rc[2],rc[3]),(rc[0],rc[3]),rc[0:1])); end end private FCurrentIndex; end type TTSLDataGrid=class(TDrawGrid) {** @explan(说明)TSL数组和对象展示 %% **} private static FHGS; ftext; FCols; Fdata; FMRWD; FGridControl; FRows; FShowTwo; FCControls; FColumnWidth; FRowHeader; FControlIndex; FStringAlign; FNumberAlign; FDefAlign; FCanedit; function showstring(f); begin if ifarray(Fdata)then begin gettxtobj(); ftext.text := ""; if f then begin ftext.HighLighter := FHGS[1]; //FHGS[1]; ftext.Caption := "json"; ftext.text := ejsonformat(Fdata); end else begin ftext.HighLighter := FHGS[0]; ftext.Caption := "原串...."; ftext.text := tostn(Fdata); end ftext.show(); end end function getdata(i,j,cp,indexs); begin {** @explan(说明) 获取数据 **} 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 begin cs := r; if ifstring(cs)then cs := replacetext(cs,".","\\o"); cp := "["+tostn(cs)+"]"; end if indexs then indexs := array(r); end return d; end 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 return FData; end function StrToNumber(s); begin if pos(".",s)then begin return StrToFloatDef(s,0); end else begin return StrToIntDef(s,0); end end 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 if FCanedit and nv then return; //编辑情况 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; if FShowTwo then begin for i,v in FData do begin if not ifarray(v)then begin allFCL := false; break; end end end fcs := array(); wd := 150; for i,v in FRows do begin if ifstring(v)then begin wd := max(wd,length(v) * 9); 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:150); end Columns := fcs; ItemCount := length(FRows); end function gettxtobj(); begin if not ftext then begin FText := new TFTSLScriptMemo(self); //tmemo(self); //ftext.HighLighter := FHGS[0]; ftext.readonly := true; ftext.left := left+20; ftext.top := top+20; ftext.width := 500; ftext.height := 400; ftext.wspopup := true; FText.WsSysMenu := true; ftext.WsSizeBox := true; FText.onclose := function(o,e) begin e.skip := true; o.visible := false; end FText.parent := self; end return ftext; end function SetData(data,f); begin if Fdata=data then return; DeleteAllColumns(); if ftext then ftext.Visible := false; for i,v in mrows(FCControls,1) do begin obj := FCControls[v]; obj.TSLdata := nil; obj.Visible := false; obj.Parent := nil; end FCControls := array(); FData := data; setdatap(); end function itemishow(r,r2); begin return r[2]r2[2]; end function getdtobject(); begin global Fdtobjects; if not ifarray(Fdtobjects)then Fdtobjects := array(); for i,v in Fdtobjects do begin p := v.Parent; if not p then begin return v; end end o := new TTSlDataGrid(initializeapplication()); o.ControlIndexs(idexs); o.height := 500; o.width := 500; o.Twodimensional := Twodimensional; o.Visible := false; o.wspopup := true; o.WsSysMenu := true; o.WsSizeBox := true; o.onclose := thisfunction(ShowDataClose); Fdtobjects[length(Fdtobjects)]:= o; return o; 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 := getdtobject(); o.parent := self; FCControls[idx]:= o; end //o.Twodimensional := Twodimensional; if o.wspopup then p := ClientToScreen(p[0],p[1]); o.left := p[0]-20; o.top := p[1]-20; o.caption := caption+"."+cp; o.TSLdata := d; o.show(); end end public function create(AOwner);override; begin inherited; if not fhgs then begin FHGS := array(); FHGS[0]:= new TTslSynHighLighter(initializeapplication()); FHGS[1]:= new TJsonSynHighLighter(initializeapplication()); end GridLine := true; FCControls := array(); FRowHeader := true; FixedColumns := 1; itemheight := 25; caption := ""; FMRWD := 150; FShowTwo := false; OndblClick := thisfunction(GridCellDblClick); FNumberAlign := AL9_CENTERRIGHT; FStringAlign := AL9_CENTERLEFT; FDefAlign := AL9_CENTER; mu := new TPopupmenu(self); for i,v in array("一维","二维","原串","json") do begin mi := new TMenu(self); mi.parent := mu; mi.caption := v; mi.OnClick := function(o,e) begin case o.caption of "一维": begin Twodimensional := false; end "二维": begin if FCanedit then return; Twodimensional := true; end "原串": begin showstring(); end "json": begin showstring(1); end end end end PopupMenu := mu; 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 ds := format("",length(d)); //dc.drawtext(ds,src); class(TLabel).CanvasDrawAlignText(dc,src,ds,FDefAlign); end else if ifstring(d)then begin ds := d; //dc.drawtext(ds,src); class(TLabel).CanvasDrawAlignText(dc,src,ds,FStringAlign); 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 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 then getitemcontrol(d,p,e.iitem,cl,"grid",cp,indexs); end else begin gettxtobj(); ftext.caption := Caption+"."+cp; FText.text := tostn(d); FText.show(); end end function ShowDataClose(o,e); begin o.show(false); o.TSLdata := array(); e.skip := true; end function Recycling();override; begin inherited; ftext := nil; FCols := nil; Fdata := nil; FControls := array(); end function ControlIndexs(dx); begin {** @ignore(忽略) %% **} if dx then FControlIndex := dx; return FControlIndex; 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 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 TGroupGridA=class(TDrawGrid) {** @explan(说明)带层级功能的表格 %% **} {** @expample(范例) FGrid := new TGroupGridA(self); FGrid.border := true; FGrid.OddLineBKColor := 0xFF0000; //奇数行背景色 FGrid.EvenLineBKColor := 0x00FF00;//偶数行背景色 cls := array(("text":"a","width":300),("text":"b","width":30)); //设置标题 FGrid.Columns := cls; d := array( ("id":1,"data":("福哥",true)), ("id":2,"data":("a",false)), ("id":3,"pid":1,"data":(("value":"a","type":"string","font":("color":rgb(200,0,0))),true)), ("id":4,"pid":1,"data":("a",false)), ("id":5,"pid":3,"data":("a",false)) ); FGrid.SetNodeData(d); //设置数据 //获得数据使用 FGrid.GetNodeData(); **} uses tslvcl; function Create(AOwner);override; begin inherited; GridLine := true; FOddLineBKColor := 0xFAF3F1; FEvenLineBKColor := 0xFFFFFF; FNodeManger := new TGroupManger(); GridLine := true; FNodes := array(); FCellediter := new tedit(self); FCellediter.Visible := false; FCellediter.Parent := self; FCellediter.onkeyup := thisfunction(doeditcell); FCellediter.onKillFocus := function(o,e) begin o.Visible := false; end //inherited SetColumns(array(("text":"","width":25))); end function doeditcell(o,e); begin //echo "\r\nkey up:",e.charcode; case e.charcode of 13: begin e.skip := true; o.Visible := false; callDatafunction(FCelledit,o._Tag,o.text); end end; end function SetNodeData(d,ncls); //设置数据 begin FCellediter.Visible := false; if not ncls then begin FCurrentNode_a := nil; FNodeManger.RootNode.RecyclingChildren(); FNodeData := array(); FNodeIds := array(); end for i,v in d do begin id := v["id"]; nd := FNodeData[id]; if nd then begin for j,vj in v["data"] do begin nd[j]:= vj; end continue; end pid := v["pid"]; nd := CreateNode(); nd.FNodeid := id; nd.FNNNODE := V["nnp"]; nd.Expanded := false; pnd := FNodeData[pid]; for j,vj in v["data"] do begin nd[j]:= vj; end if not(pnd)then AppendNode(nd); else AppendNode(nd,pnd); FNodeData[id]:= nd; FNodeIds[id]:= pid; end UpdateWindow(); InValidateRect(nil,false); end function GetNodeData(); //获得数据 begin r := array(); ri := 0; for i,v in FNodeData do begin r[ri,"id"]:= i; r[ri,"pid"]:= FNodeIds[i]; r[ri,"data"]:= v.FData; ri++; end return r; end function getcurrentnodedata(); begin if FCurrentNode_a then begin d := FCurrentNode_a.Fdata; if d[3]="sysparams+" then return; d[2]:= "*"; FNodeManger.getcdnodes(FCurrentNode_a,r); reindex(FNodeData,r); reindex(FNodeIds,r); FCurrentNode_a.RecyclingChildren(); FCurrentNode_a.Expanded := false; calldatafunction(FCelldbclk,self,array(1,d,FCurrentNode_a)); end end function MouseDown(o,e);override; begin // inherited; if e.shiftdouble()then begin r := HitTestItem(e.xpos,e.ypos); if r[0]>= 0 and r[1]=1 then begin nd := FNodes[r[0]]; d := nd.Fdata; if d[2]in array("str","int","lstr","double","nil","int64")then begin try rc := o.GetSubItemRect(r[0],r[1]); FCellediter.SetBoundsRect(rc); try FCellediter.Text := d[1]["value"]; except FCellediter.Text := ""; end; FCellediter._Tag := array(r[1],d,nd); FCellediter.show(); FCellediter.SetFocus(); except end; return; end else if d[2]="array" then begin calldatafunction(FShowarray,d); return; end calldatafunction(FCelldbclk,o,array(r[1],d,nd)); end end FCellediter.Visible := false; end function MouseUp(o,e);override; //展开折叠点击 begin inherited; r := HitTestItem(e.xpos+5,e.ypos); if r[0]>= 0 then begin nd := FNodes[r[0]]; if FCurrentNode_a <> nd then begin FCurrentNode_a := nd; InValidateRect(nil,false); end if r[1]=0 then begin if nd and nd.NodeCount>0 then begin if nd.Expanded then nd.UnExpand(); else nd.Expand(); UpDateWindow(); end return; end v := nd[r[1]]; if ifarray(v)then begin if v["type"]="link" then begin return CallMessgeFunction(OnLinkCellClik,o,v); end end end end function AppendNode(nd,pnd); //在父节点中追加节点 begin if not(pnd is class(TNode))then _pnd := FNodeManger.RootNode; else _pnd := pnd; _pnd.AppendNode(nd); end function InsertNode(nd,idx,pnd); //插入节点 begin if not(pnd is class(TNode))then _pnd := FNodeManger.RootNode; else _pnd := pnd; _pnd.InsertNode(nd,idx); end function CreateNode(); //构造节点 begin return FNodeManger.CreateNode(); end function InsertNodes(nds,idx,pnd); //批量添加节点 begin if not(pnd is class(TNode))then _pnd := FNodeManger.RootNode; else _pnd := pnd; _pnd.InsertNodes(nds,idx); end function GetNodeByIndex(idx); //通过序号获得节点,必须update后 begin return FNodes[idx]; end function UpDateWindow(); //update节点 begin //更新窗口 FNodes := FNodeManger.ListNodes(); ItemCount := length(FNodes); end function DoDrawItem(o,e);override; //绘制单元格 begin inherited; j := e.Subitemid; i := e.itemid; DObject := FNodes[i]; if not DObject then return; dc := e.canvas; e.rcitem := rec; rec := e.SubItemRect; wd := 4; if FCurrentNode_a=DObject then begin dc.Brush.Color := 0xffce87; end else begin if i mod 2 then begin dc.Brush.Color := FOddLineBKColor; // FOddLineBKColor := 0xFAF3F1; end else dc.Brush.Color := FEvenLineBKColor; // FEvenLineBKColor := 0xFFFFFF; end dc.FillRect(rec); dc.pen.color := 0xa8a8a8; //dc.pen.style := PS_DASHDOT; dc.pen.width := 2; dc.moveto(array(rec[2],rec[1])); dc.LineTo(array(rec[2],rec[3])); if j=0 then begin cj :=-1; pd := DObject.Parent; while pd do begin if not(pd.FNNNODE)then cj++; pd := pd.Parent; end wd := cj * 20+4; if DObject.NodeCount>0 then begin if DObject.Expanded then bmp := FBmpExpand; else bmp := FBmpUnexpand; bmp.Draw(dc,rec[0]+wd+1,rec[1]+10,SRCAND); //dc.stretchdraw(array(rec[0]+2+wd,rec[1]+2,rec[0]+15+wd,rec[1]+15),bmp); end //rec[0]+=wd+4+18; rec[0]+= wd+16; end if j >= 0 and DObject then begin rec[0]+= 4; v := DObject[j]; if ifstring(v)then begin //if j=0 and v="sysparams" then dc.font.color := 0x0000ff; //else dc.font.color := 0; dc.DrawText(v,rec,DT_SINGLELINE .| DT_VCENTER); end else begin if ifarray(v)then begin val := v["value"]; typ := v["type"]; ft := v["font"]; rebk := false; if ifarray(ft)and ft then begin bf := dc.font.fontinfo(); dc.font.setvalues(ft); rebk := true; end if typ="link" then begin udl := dc.font.underline; fcl := dc.Font.Color; dc.font.underline := true; dc.Font.Color := rgb(0,0,254); end if ifstring(val)then begin dc.drawtext(val,rec,DT_SINGLELINE .| DT_VCENTER .| DT_NOPREFIX); end else if ifarray(val)then begin dc.drawtext(format("ARRAY<[%d]>",Length(val)),rec,DT_SINGLELINE .| DT_VCENTER .| DT_NOPREFIX); end //还原 if rebk then begin dc.font.SetValues(bf); end else if typ="link" then begin dc.font.underline := udl; dc.Font.Color := fcl; end end else begin if not ifnil(v)then dc.drawtext(tostn(v),rec,DT_SINGLELINE .| DT_VCENTER .| DT_NOPREFIX); end end end end function Recycling();override; begin inherited; FCurrentNode_a := nil; FCelldbclk := nil; FShowarray := nil; FCelledit := nil; FOnLinkCellClik := nil; FBoolColumns := nil; FOddLineBKColor := nil; FEvenLineBKColor := nil; FNodeData := nil; FNodeIds := nil; FCellediter := nil; end published //属性 property OddLineBKColor read FOddLineBKColor write FOddLineBKColor; property EvenLineBKColor read FEvenLineBKColor write FEvenLineBKColor; property BoolColumns read FBoolColumns write FBoolColumns; property OnLinkCellClik read FOnLinkCellClik write FOnLinkCellClik; property celldbclk read FCelldbclk write FCelldbclk; property celledit read FCellEdit write FCelledit; property Showarray read FShowarray write FShowarray; private function GetChildAllChecked(nd,j,ck); begin nck := not(ck); for i := 0 to nd.NodeCount-1 do begin cnd := nd.GetNodeByIndex(i); if ifobj(cnd)then begin if cnd.NodeCount=0 then begin if cnd[j]=nck then return 0; end if 0=GetChildAllChecked(cnd,j,ck)then return 0; end end return 1; end function CheckAllChild(nd,j,ck); begin for i := 0 to nd.NodeCount-1 do begin cnd := nd.GetNodeByIndex(i); if ifobj(cnd)then begin vi := nd[j]; if vi=0 or vi=1 then cnd[j]:= ck; CheckAllChild(cnd,j,ck); end end end FBoolColumns; FOddLineBKColor; FEvenLineBKColor; FNodeData; FNodeIds; FOnLinkCellClik; FCelldbclk; FCelledit; FShowarray; FCellediter; protected type TGroupNode=class(TNode) //groupgrid节点 uses tslvcl; function Create(); begin inherited; FData := array(); end function Operator[](idx); begin return FData[idx]; end function Operator[1](idx,val); begin return FData[idx]:= val; end FNodeid; FNNNODE; //private FData; end type TGroupManger=class(TNodeManger) //group节点管理 function Create(); begin inherited; end function CreateNode();override; begin return new TGroupNode(); end end class function Sinit();override; begin inherited; GetSJPng(); end private FCurrentNode_a; FNodes; FNodeManger; static FBmpExpand; static FBmpUnexpand; class function GetSJPng(); begin if not FBmpExpand then begin FBmpExpand := new TBitmap(); FBmpExpand.readvcon(HexFormatStrToTsl("0502000000060400000074797065000203000000696D670006040000006461746 10002C700000089504E470D0A1A0A0000000D494844520000000A0000000A0806 0000008D32CFBD000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000005C49444154 285363F84F24204DE1EA7DF8F1ABF740851FBFFEFF9FD9F3FF7F443D6E7CF53ED 4C41B0FFFFF8F6FC1AEE8D005900A24379EBA86A968D729A82410A07866F76984 A2CD47A1825080E16B9807D00186425C804885FFFF030081696EBEB08C861D000 0000049454E44AE42608200")); end if not FBmpUnexpand then begin FBmpUnexpand := new TBitmap(); FBmpUnexpand.readvcon(HexFormatStrToTsl("0502000000060400000074797065000203000000696D670006040000006461746 10002BF00000089504E470D0A1A0A0000000D494844520000000A0000000A0806 0000008D32CFBD000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000005449444154 285363F88F0672FAFEFF3F7A09CA4102180A23EA2178DF39A80014E05408C23B4 E40058100AF4210DE7404224E502108AFDE474D852045208057214C1108E05488 AC08043014164DC654F4FFFFFFFF0022DF66E2EA30F3BB0000000049454E44AE4 2608200")); end end end type TNodeManger=class //节点树管理 uses tslvcl; function Create(); begin FRootNode := CreateNode(); end function CreateNode();virtual; begin return new TNode(); end function ListNodes();virtual; begin r := array(); GetExpandedNodes(FRootNode,r,0); return r; end function GetNodeByListIndex(id);virtual; begin return GetExpandedNodeById(FRootNode,0,id); end function getcdnodes(nd,r); begin if not ifarray(r)then r := array(); for i := 0 to nd.NodeCount-1 do begin cnd := nd.GetNodeByIndex(i); r[cnd.FNodeid]:= nil; getcdnodes(cnd,r); end end Property RootNode read FRootNode; Private function GetExpandedNodes(nd,r,ct); begin for i := 0 to nd.NodeCount-1 do begin cnd := nd.GetNodeByIndex(i); r[ct++]:= cnd; if cnd.NodeCount>0 and cnd.Expanded then GetExpandedNodes(cnd,r,ct); end end function GetExpandedNodeById(nd,ct,id); begin for i := 0 to nd.NodeCount-1 do begin cnd := nd.GetNodeByIndex(i); if ct=id then return cnd; ct++; if cnd.NodeCount>0 and cnd.Expanded then begin r := GetExpandedNodeById(cnd,ct,id); if r then return r; end end end private FRootNode; end function getdebugicons(); begin r := array(); r["调试运行"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100021003000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000002A549444154 484BAD958952DA501486592ACAA652A4E2C6BE18A22202A540DDA6639FABCB540 58D200AA22C21019EAF8FF0F704AE89B59A9982DFCC9924E4DEF3DD73C84D0C60 7CED7238E96CB2ABB743157C11E314511C53BC25AAE044A2E4BD108EC4200EBB0 1F6EBF46815C8611CCB945CF2E340F461BFBBC1EE4C872A381E0470D8A7C4FD75 14A555E4452FF22D2FBB3B39AAE068E8C7FE601D85FE0AF2D2077CEC2D21DB762 37BBFC4464C862A38186EE0F380920F3CC8C8EF91E92D22DD5944AAB580BD3B17 1BF5FFA882FDE11A0AC36564FB6EA4E505A47A4EECB41D483ED8B1DDA0E3ED3C1 BF92FBF396E14CFCF15544171B88ADCD083ECC08594E4C0B668C5567B167C93A2 318BC48D157CD5C146BFCCD3C48FA802A53DB901ADBE3F8F64CF06BE330BAEFD0 EF1A609F1BA199BB5197095396C09AF4B7405C5A177D49E3D995A23CE21D19941 ECDE8448C38048CD8068D584A8402281AA29BF2CD115140624905DD895ECE0BBB 4FA0733227794FCDA80B06040F0928E17242A5355E7566C979C6CA686BE405E46 5A2281E800DFB62046AD89DE8C93874A2438A5E319C5B911B1730B36CF6C6CA68 6AEE093444F50CF8564DB8EC403B5A76142A8AA250FFE64F18BAA3A35B3597FA3 2B50766EA64B15B49C48DC5910AD1B11BE52563C4E1CF83E0EE5FC35F42BE890A 0E5C64E93047512DC90807A1EA0D58F927F1B871EFA15D07B27D37423D97082AB CD21563523541EB74411F874922B891F933F3D57D02AB85F41A64102DAB1FCB50 D316106E1B2712CF8A1BF723DD499B90609EA1EECD616C05FD910BFB4205232D3 1F6C642326436BD1ED1AB2B565EC565CA3DDCA95ADA3C7715A5441A1B6814CD58 BD4951B5B17F3E04A7676673AB40AAA3EE42AAB480B1E242F267F3D3F47ABA0EA 474E5843E672FAAFD8535441B112445EF0B1ABB702F803D2475555757FB6FA000 0000049454E44AE42608200"; return r; end function GetEditIcons(); begin r := array(); r["打开文件"]:= "0502000000060400000074797065000203000000696D670006040000006461746 10002DB02000089504E470D0A1A0A0000000D4948445200000026000000200806 0000007E640AB3000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000027049444154 5847ED97DF4B537114C0EFDF104410414808D54B62504F113D590FBDF86A083E0 4820FD10F028320EAA51E7ACD880C451DA8A5A258334B1333FAF51211856E7777 D3DAE62CE6E6D674DB3D9D73EEF56EB77D37B6D5BE97A00F1C3676B7EFF9F03DE 7FB63CAB43F011D3361383DB652760C2DC6A0D6280D7D9A3079A9D8716709FCB1 2D7388DAA050124A562EB7DE7D67B1F995A4F9496DF82F5629158B3D0F2458ACD A689B0AC2C3C5B8395A712A168B6D66E1DAAB08FFA69AA07CADEEA0395A712A16 FB53CACDF76F8A851219B8F976ADAAA045220ACA77A8CF277CB61D6A74ABB4D88 9E1000FE44414157BAA6DF0177A3EADF3D6202B86F1B82B2976793EC25F904DE7 4B23AF502CA3EBD0D8AF712965D334B20CC787026231B7666CA25446997C8CA46 067D7125CC159138A5D9A5B75A48CBD38119477528D178A6D6674D8DFA3C2499C 52D99C9B0DB35834952D147BECCBAD4699A4B33A1C1BF45B7D5D2076FE85612D9 B37C19F9C97FA8BB089A5B08C7BEF7BA179DCDE7332E8FA10B5FA8BB0894D789D 292371763AC4B9A9BF089B58FBB3102E570FBF97C93A5EA50E0F68D0F428B7E02 CB1445AE73DE4CC936FE62379CC2E2779B6AE2E18FD455862639E383F1CF82CBF 8CB7DFFFB0F5176189D1AD921ADF095AB04ABBEEE6FA8B60B153B899D22BF5986 C8278E73BD8EBC3C9B16FE82C76D4E567B1512CA76C26556327B8FE7ACDFCC480 C5F675AB70008F2127B88142E4E0C613271F16A3B88007B713344F7C853DF73CB 6FE222CB129BCB1CAC68B77FBBA6EF149A3D43F5061371AD7E18AAC5960F2EDA0 1D203F6852E8CFCBEF28AE2F3138E2D2C403FE8DC89312895D9C0B43326D2F230 0C02FA1DC4D3F567030CC0000000049454E44AE42608200"; r["保存全部"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100025302000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000001E849444154 5847ED974D4B42411486EF7FE9EFB40A8268518B68578B9605EDA25D50B4A88C2 40C8A5A5408B5882430C122888220B2FC46F2A696A9842935F91EEF19A68B9479 3F16D50B0766CE9999F771D0EB3D9A3054BDD545767A5F447B16C455D7842381B 3E1012F16013CCC055A6E7032F4D9C326402DFB2C93A991755139898A78FFB25C 84B995E00F873331CF8C6F4B3F786BF7537BD28CA50258950AC04A0EFB28076FE DAE7B9E26A0635901C09EC4D0AA281FDDD0BC1540C117A61CBC350CEC0430EF6D 05002FF6FDBD003086FE1E40D17F29729EA03CCF7500B32C03206F253A028031E 7ED0AF536BF05803293BB446D47E02C556D0138A97F808E005037AFF92A67CEAB 42EDC700BC4E15FFC45471CE5680F271446E78DA3937B22E02A44637E8252231E 815B13E8F917509E0AD5AA77A29702DF499031ABFBFD4A8C60F2C55B60314FD17 B25E398DD138BF12A29A2B00E9C6F5F31A8EF880976AAD0038670B405D2F512DB 7D4FC7B45608CDC6BB220CDF8918B39DF00E7F0A66D56DB0085B5301D520E468C 4CE317D11823875ADE1B92460806507396009CD227006EC5DC0478DC3A234F786 BE8D53041C7E29662BD8BE4096F0D8D2226083C6CD034E0369C089C9D1EDB947E F0A6E694BFCD6E063C21D99EA35144AFC6AD9A1381B3E101AFA684F80055B3808 F56B6A2590000000049454E44AE42608200"; r["保存"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100022702000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000001BC49444154 5847ED97CD2E035114C7EF4AB045B011ED0295D06D173E1296880891B0A88588F 00E3C000F6021165D88442CBD869022AA3A65CC0C8BAA36165A334D8FFEAF7B5B 7442FA35ABF927279973EE9C737E776E663287514196A191B1BE48515F1B457A9 A1A6AE8A1AFCDD387728BD6C4D03C36DC657B73232D36D4C937CEB07304B49559 B29E0DCA84CFB81F1F1B20538DD7C5500B3551DB7AD2490BCE70DFD85822261F3 B16A022C0A49FFB952A6F59A4AFCE91693C8A08F15A1200C2CEE1477DEDC47001 93AA15207B73C9F3D3C7211129078064DFBA03C8FCD4E1BE88380C90BD3AE7F9E 9A303117118209F79A758C0C38F42AA2280ECF505F7EFC77D2252BBE45B80DA52 B26F19402E99A0486F3345BDAD646A0F225ABDF01A463C2DBC662E9514D13F002 02D38CD63CA683FA5427BF4767A5295215719E9E3B5F09DF92ED9D716C0D4557E 8E72AD565302DE1FDF0548AED90240388AC4CE16A90B13A44E05AAB3426E62779 B72AF2FA26A49FF02345A2E800BE002B8002E800BE00214017E0F264EA838980C 7610C3A00807E3921310682E7FF98CCD65629852312822E0A4DDF9BBF9864BE37 96150C4AC6677733D0D3DB0F3AFA74DF409837977A59FB64D730000000049454E 44AE42608200"; r["取消注释"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100022001000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000B549444154 5847ED95C109C5200C40FF4E4EE15D07D0832B787142F1EC0C2EE03925FC2A9F9 2160A7EE3C10739546DF220113FC0CC16D8026B0AD45A21A5343430270529E09C 0321C4D0C09C146B0AB0B76026EB0B78EF2184707E8DE751008BB721C23EFE035 2A094024AA95EDC180331C63E5039E7F3E497B6FE14AF86504AD98BDF45039353 FBD778750DD905B0055AEBFEB3B5766E0B1A6C43F80BEB359CC19A02EC8F11FB7 3CC2EC0DE82996C812DC02C0070005765629339C9EFE60000000049454E44AE42 608200"; r["注释"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100021201000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000A749444154 5847ED94410A80201045BB9377F20A6EBD9757F03A82BB8909021333B56F1AF8E 0D3A2181F8CFD8D06B30496C09C02CE39B2D642C333532405A4942484808667A6 985360F80ABEE41F02C6986387FC445324105E26B444D125D45A6725C26FEF02E F81538287A7DEC781F740578170058C52EA32ACFB0A42BCF7D9C3DFF228C0F0A1 437FC39ECC2910F70022F01EA80DBC076AD3DC03A834F7406F96C012182C40B40 319335F36295E4B140000000049454E44AE42608200"; r["撤销"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100022A03000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000002BF49444154 5847BD974B681341188073F289F80005116C6BA10F15D48B56A8AF832858A8288 8F460412A420F05A9079182E2C1E20391422B88A055F060050F2282482D689552 2A5AA14DB24D9A3449D39A36469B64934DB2BFFB4FA6D34C36AF26BBFBC17FC8F E9BFFFF6676323B314101486E2744C67ED24FDA925720F47500849A8D602E5B09 A12FFDF4AA76E414C0E6D6EA0D60DEBE824468F013CD68475681F0D067106A37B 1E6735D9D34A32D1905B8E6CAD4FB9F74D18CF6A80454CD9F76D38C3E7002E9CD FFF43EA219FD60025CF38AD51078D54B33FA4204D29BFF7DFD82245359F8F80E7 E775E2F2870C1E200A2360BFD76764CAAE66F5ED2D412F1791F98CB5725EF5966 D88FEE26EB4896A2B41A8FC9D5DCC86E7634D667BC518EC5C0717C1F5778B9613 B540DE1916FB4E212A644380453E74FB01B5D171A408E88349D422241B664C969 CF1BE2F72108F43D0777CB19B0EE58C36A5B2AD7A96698AC8182258A202A8C73B 5F13107073ED02C1540F49480781C663ADA586DEBAE2D109B769314B70F1089A6 93FA48C832785A9B586DEFD54BE4322780C862583789B87F0EAC3B37276B2B8F4 29A9A540B207A4AF8EEDF6475FD8F1F661640D2D784FBE269F24B2895C8F82F56 13079955004997107F0CD34C6990038E52CF565F955B0041096F7B0B9901AD1E8 3FD700D11B054ADCF2FA00713FBCB8880B067ABF102388B8BBB236EEF860B04FB DF93E618D36DCDC60B782E9F6302FFDEF6192B101E1E24272D6C2EECDD0689E08 2710231DF2C4C1C2867A3F73FEB21D70D11C093D1E4915AD6DC79F69872C69048 4E578178C00FBE07B7D8C68361AFAB24B3B1082780070EDC9FE77BEE151FDD776 1F6C615B2CD5A2BD6B2C6188E868310F37A68B7249C007770D030F0EF9DEF4E07 79C9A5C309CC5C6BCD58A0A85056BBF3549D7242BEAD1A752AFC1A50DE7691B15 11047474A0AC9E500391AA1457301F01FDA4F2FDFE8B101E70000000049454E44 AE42608200"; r["反撤销"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100028202000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000021749444154 584763F83FC060D401A30E1875004D1DF06ED684FF6F2677FCFFFFE70F540413D 0D401B73485FFDF9063FBFF28DCEDFFEFD72FA1A2A880A60EB8A9C403760008DF 3690FEFFF5C83EA80C02D0CD01207C4B89EBFFEBBEA6FFFFFFFE85AAA0B30360F 8496AF0FFBF9F3E80D5E075C0D7A3FBFFBFA8C8FAFFD0DBE2FF1D53B9FF7774C5 49C2D82C87E16779F1603BB03AE0F7B327C084E38A5523B5F0D3AC28B05D180EF 879EFF6FFBB26726045F71C75FF7F58B9E0FFEF17CFFEFFFFF70FAA8278802B0A 1E4579FCFFF3F635580D8A03FE7DFFF6FF9E830E58D1F3A2E4FFFF7EFD84CA900 7301C20CFFEFF557B154AB980E280B733FB202E8C70C75B78100B50B2A1BEE4FF 2FFB7740651000C501F7ED35C18A7F5CBF0C15A10CDCD610049BF7C0D7EAFFAF2 70FA1A2A800EE805F4F1F8115DF7731808A500E4079FE556BC5FF7F3F7F404530 01DC01DFCE1C033BE0496A0854843E00EE80EF174E431C90140015A10F803BE0C F9B57E0547AD74289AC2C472E404984A0C4020A852F87F64045680F501CF069E3 4AB0034065C1DFCF1FA1A2B405280E00D5524F62BDC18E78E86F0B2E92690D501 D00047F3FBEFFFFC0CF1AEC08503E7E599BFFFFF3EE2DFFBF5F3A4B3206A52B42 00C30120F0EFC7F7FF2F9B4BFFDF54E6053B845C0C2AFDFEFDFE0535153BC0EA0 018F8FDEAC5FFF74B66FD7F5E96F1FF496200B8122105BF6AAB849A841BE07500 3DC0A80306D801FFFF03006C2FCBC409CD25D50000000049454E44AE42608200"; r["tsl语法检查"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100020204000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000039749444154 5847AD97F94B545114C7FB5FFA2DA41FDAC8A00CCA225A7EA9205A208A8222081 222FA413335CD25358D448BCC32CA16111754D250C9164D2575F66677369D71C6 D91A47E734E7BEFB5E6FF4CD7B6FC6F9C0859973BFE7DCEFBB73EF7D7736419AA C8622E0EB99266D35B44CA3A993B281D09405EC0F7A40BDAF1C6636DF254DB3BF 021CE5BD109AB652957C641958F185C0F36E0C8C175F708362335D69212D2176F 515783BA620B6BC42B3C51135101C3382BDA80BD47BCAB801D4D965E0ACF90C51 E712550144ED3E7054F681725B11A7D31CA80267553F849576AA12669D81154F1 03CAD3FC078E139570C1B3EE9D2A08AAA92836BC270EE5962EEF556F076FD0688 51118F040373F91DA0DC55C225E2D3BAEA07613518A10AF9E0ACD88BBB61764B3 E574F7BB886CC1E1FCE80F5F6074E68BEF61A823F0DB467E3E0ACE84F3570F56D 859DB4876780ED4C075FEF0C18CE3641E0FB1F1A1106FB710CD4B26CD8406054C 74D333EA918193780FB5E955D4AF2F06C9022A30622C605D01EAA2639D63B1F69 549C8C19882EF8417F9A5954E6F8168B45A2B4479C8C18C0C18C979A9942F1FDC E3F90A4C8880157ED00D1E98E3E86C54F1364BFCB45D4806A37B398A49E088B68 0F3EE20C133327EAC9A123B50BFC032AA2B7DC7C4B233C03FA934F496770DC482 3E204BEEAC0F1B01774C7EA12CCAC3DE9F878DB27194D451F8DF00CA02BEC4451 AAB8EA0649AE3AA71CC2AAE42F1F77F328D1B9E3EF1A16CE00BA927A0221E61B8 7491E1E46FE112D8D0A83B551EB1F52D308CF4070D24C3A75C7EB68441A77CB37 92836DB17D824693A3D9CB5C62F036C5C21940B4476A89203C3B4723C9F1B48D7 383CF370DD368727081A2D674F9258D30241860A748EA67C0773B3BB8A354FA08 46D89BD342D3088D302418082B6CA0D85A088AAC02D159C07D8CC5AC79EF69441 C76B6943B4BC8187C120C20F30D4344CCDFAB6B8998DCB2176BD413004D2E736E A091B5AC338018CE3357AA5477841096BC3652CB16BF6D09216800A79F5DB178F 4A68BBDA49BD4D09F69A491F5081A40961D3EB216B0C05CFC758BDFE5825ACCC1 5CE58E621A1526A90116754E0529A4CDAD066F77FC662B016A508B39982B85A40 1C47CE30D2988CD7EBF1322160FEDF90FC6B08FD5618E1C641940F0CAC516C763 D77AAB0D82BF4CA4E167F65EA8C8BA07CECA7E9A258D6C0308BE01F9B3C16FCAE DC5602BE880BF6A0755CB2325032C38DDAE275FC881840DFF37C6C2E9FD434ECB 40E600F8077525AC9F3D612B2D0000000049454E44AE42608200"; r["tsl代码格式化"]:= "0502000000060400000074797065000203000000696D670006040000006461746 10002E601000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000017B49444154 484BCD96CD2B04611CC7FD390E8E5C1D957273578E0E2E4AED897FC045EBA58D1 4DBA675D8C8A64424D12E566B6D1B4931C94611C9719E9FF93EBF999E31EF333B C9A77E87797E2F9F79E6ADE92293A90341DD593D561C3F0AB3DB1F29687F916CA 83E89483152E2404FF936582205684271542CC1E239F7151AFE928E0460A9C6BD 0B67DE928E0560B5CEFDD98A7B462A02B07EED2D492C185873D76FDDF09CB9AA9 22712945A5C3F54E09D380339CC0489040067E9351C918A2088FF2FC0E539D5D4 8D74D29160A349345C0CAE8D2CC85FF14DB33398D7A9D8E435E4F0FC3B0915E42 E04F5E6749AD81574FF6E2E1AD49E897AE6551D72A8E9336A972F952850603D7E 56819D4963D8CC897B1DB5E899AD702E74078D17A2F11D215FA46DF373FCFACD8 DDAA73C9420879AB1B2A07A5B89430516B804993D2EC4376674530D01997D4177 6FE6818DC8023BFD2B828E1E7E0BFC882D40DE6A8842A21DC4E1EF05DA875A4C2 3300B3F12400AC0F42127D208FC0231443F28BE427F9C549A270000000049454E 44AE42608200"; r["查找"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100021B03000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000002B049444154 5847E597CB6B13511487FD5F5CB8115C09EE74A12E4437D58D2B455011DC88822 86215AD8A2DA1A550954A7D9582A4565B4DB56A158D4A11ADD6BE93B44D62D264 92A6499C344D3331C79CE39921D3492693718C0B3FB884FBE33E3EEECCBD77B20 6FE31550B48C20F488F06203D16845C2CC5A9792A0A64A6C310BAE880D93DD761 6CED694D99D8701EBCFB6F41F8CA5358F12E702FE3E80A084DCF6162FD399AC87 BE036241E7D858C5B809F6206A4A808A2D305D1F6B710386E2FB4AB87A94D9720 76E703F736465901FFD12E9A187F97867D9C9667E9E31C7876B52AB2462929202 F6FB27F9413E3044ED895FE46D008A0BDD1CEE548BDF7D01842F34B4ECAA312C0 E7871DC397FB3931CF42C73B1A0BDF1B3D14017C83F1259AA96BE3E4CFF11DBC0 B737BDBB9561A452074E10919E3F25985383845638A4E37275A1481E9CD8DB4D7 AD06572170F201D7B490406A68864CF1C0B19AE88D37E0DA66E39A161248F48D9 080996D5789B8FD138D9D5FCE72A28604A2379DD4480A2529B412F1D5EFF76079 32C4891A1290B74C3618A7D04A6401BC534A4102B8F4D828D1ABBF67CD808F607 CDD19C84B394ED49040C6132181F9B3BD145A49A4ED357876B6724D0B0920B3BB AF8167470BD7AC037798DE91AC08445A06691516BB3F73521B14815C220DEEC27 EC503A9962802C862E710AD42F0540F277F1F950062C5758CDB1A8B113402080A 60A9F664942222CCD7F729FDABFE1E28A6DA4FB2F8C32FE0DA6AA33EA106077C3 F76DF9044590104F7B07B7B330D84178AFFF03D101A0720F17804928E6F20D85E 80AF90B9B634511BEFBE0EFA3694C15BB09284AE0092CFE620DE330CFE239D345 87199DCD800BE4305A9C204C98171EEA1060F373D898A02AB91FF98ACF8629C54 061F094AE059B39AAA05CC12BEFAACE44AD44C00C1C951A2989A0A94E27F1700F 805D0F3420D05EDA5310000000049454E44AE42608200"; r["后退"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100027501000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000010A49444154 5847EDD3218B84501405E0FD8B16AB60325A15C162325A0C2641D0603319AC822 641EC62B2984C8270969179CBCC70C75D771FCAC23B708A70BD1F3CEE072E8E00 088000FC5F405DD7304D13711CDFBFFC2E8701E338C2F77D4892B4F5544096655 055F56BF96980A66960DBF6D3E25300D3342108027231AB65591BE2481FF31690 E739344D2397FEB56DDBDEB71080AEEBE0380E39C8AB6F0161189203BC4B02E67 9866118E400EFEE3E4151145014851CE4D55DC02DCBB2208A22729847BF05B0F4 7D0FD775C99FB052679824C96E1FB30B6029CB12BAAE9380D7BB3E9A1F016E59D 715699A4296E56B002CC330C0F3BCEB002C55556D677B19805704400004E06200 F00985F34928814F15230000000049454E44AE42608200"; r["前进"]:= "0502000000060400000074797065000203000000696D670006040000006461746 10002E501000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000017A49444154 5847C5963D4BC3501486F33B440DE220520D3AA888ABAB8A28A26DA9F5A355549 42EAE4E8E8E6ECE4EFE011737870E8E82AB38EB0FB8E7B6C79EF6857EA569D2DC 9B3CE585F4DE03EF43C897C331D9A0031C8D466C8129B5C05B94C3BFE81811185 3B3BC4D79AC44C3988064870A580D8F5101C92E15B1130EE302923D3AC2EE70AC 0848F6E90413C158139064A984A9C1581590E4A98C497F9CF75A95E3649880A44 0E7A8EBC7918165B51E2BBD857E39D417A8ECA62990548A7489DA36890A488EE9 0AD52D1217909CEA6BD4A7242029D14DBA02923255D213985073E99D0157CD37C B85C4055CF250DD2251015779AC1ABF4E121390D3FE5BFF436D9BA680DFE3B533 2B149CDEB2DE4C362EB86FFE416537D65F4672B57FD6BF50D78FD5D7F1B8CA70B 5FE81497FAC0ABCD6DE3035182B021EADF1B37EC14430C605326A951FF5137687 635460462DF1BD7EC04E388C094CAB45BED577580D8F1101B9D5CE74052BD1302 290D3C15FBE41C416D8A42C8E4681F91F06F7DA0A168403F80000000049454E44 AE42608200"; r["快捷键说明"]:= "0502000000060400000074797065000203000000696D670006040000006461746 10002C601000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000015B49444154 5847ED96314B03411085ADFC019616F676292D2DD2091616B63682A545B0B4505 BD1D2DA562C03762155AAD4225148F49010541051C1588CBCF1DEB91956B9856C C2E13D781C6F7676E7BBBDE66664CA2A014A800CE0A37329FD9D2DB95BAF46F56 0775BDEDBAD746A0AF0D66ACAD5C2ECC4DC599C9397FAF90FC0EDDA72B6D8AF6D CAC3D17E6E3F1E1FE436FA3907B79101B038D8AB6931A69ECF4E7F070021844FE 2DA57B3B63D36BBB55C00ACB1114FD6B0EE5E27F731C390DD031507000D34E466 0230739FDB637310404C0503B86F61330E83DD9AEDB10A06E01A0C61233301987 928336C553C000E816DF6D9F658A1160400B90786D827D4830150674F5EFFF532 582F1E00368478AC00E39417E0BA32AF45FC0B0C939E2EC4D2D3C9A1CE4A36563 52B0006F3162665DEB602BC362EA4B7B2E46D8CE16EB5A2C32105A086DD1BFD46 31FD799FA4D3BE3502300D9500FF1D40E40B036C6466EFBB13F70000000049454 E44AE42608200"; r["代码地图(alt+m)"]:= "0502000000060400000074797065000203000000696D670006040000006461746 10002A405000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000053949444154 5847C5577D4C95551847304021958FED22134190217B5F750C192226384030705 302455D3304FF409BB32205755CBED2A2D41495BBA29CAC81F63186D4D614E707 96C628FE486B4BD104CBC972E2951C9AECD7F31CCF7BE1CAB978B1B97EDB6FEFD D79CE739EDF39CF739EF7BD2EF89FE1B4804B972EA1B6B616797979A8A8A8C099 3367A4E5BFE1A902FAFBFB317DFA74F8F8F8206BC912588A8B51919D8DE52929F 01A3F1EADADAD72E6B3614401E7CF9F87C964C2E7F5F5B85F5E0EEBA245766C9B 370F73838361369BA5C7E831A2006F6F6F0C5CBF6E0B7868D62C644F9E8CB2F07 0B4C6C5D9C6E7F8FAE2D4A953D26B747028203A3A1ACDCDCDF87BDD3AFCB26001 5C5C5C7078F66CDC2A2D45C7CE9D707375457158984D04DB9F050EBD7C6957FD7 575B6C57F4B4810A73114251B36E0939933C59C147F7F946565498BF3500AB871 E30602030371BFA4041DF3E7232B20008F2E5E94D6417474746075529210F04D4 C0CA2283DA38552404B4B0B121313D1B772254EC7C66213ED5285BB77EFE2E5E4 6421E02ACDF7F5F09016E7E13005E154687D6BD6A093164E0E0A92A3F6686A6AC 2A6820221605764245684864A8BF3702860ECD8B1E8AAAC148BE7D155ABADAA92 9641B8B9B9E19CC522E6E44E998286DC5C69711E0E05A4A5A5A1913A1E2FCE7C8 36E00DFF7C6C64654575763C28409E204EE519AD89EE4E78787274E486FE7E150 405B5B1BBCC68DB309607653D57F4727F12B5DCF07478FE2DEAA5562BC6AC60CA CA6A21DE8EA92DECEC3A100467A7A3A8ED0D51A2A42C5A924B43127477A8D0E23 0AE0174E0C15972AA8C11A5D47F4C489F8E7EC59E9353A8C2880111515852F972 D530667A652033A9C9121678F1EC3049452ABD5340D4B972E457E7E3E32333391 4005A80ACEBB8F9D34090F8F1F17DD9253B670E14258AD56B11617726A6A2A62A 99744444420801A9AA7A7A76872C6BBC34E406F6FAF6840AF1DBE89B995D76DF4 D333B0272E759880006A3CFBE317DBCD359873A41B71F464AAECC6BBC34EC0B16 3C7F0E6B672686FFF6EC7D0579BE0EAEA66179C77BF96EE7E51DE67C3E66BDBAE 41AFBE327C7C0859C0C53FFBED05141616A2E8D3166825D786D13FBE00DB631EF 77DA6BFBB3B1AD25643DB71157A5527F4DD574450BDE632B47768EC7D1AA3DFFA 41228FEF21F2D8CE4E841534C3332012753FF4DA0B888F8FC7E27DDD4A01330A7 F8487879708CEAFE1726AD5AFAFFF0ADA76B23F417D3FED5EB1864153CA56F8C5 E6C2FA60C05E40DFC301E845EA23630666EC40CAB44878D2B7C0B7991B957398F A3E12B0596D637A4F4B44489645C4B413F0F1F777940E06F9085DC68C111F2639 EB4F2AE77060FD834EB54D728CDB0B48A8FC59C414027A7A7A44F5675AFE503A1 8E49C9A92B6A02187AEAAC22EC8C75C71556D9374F7094141C3CD4101EDEDEDE2 45137F90F2C7C5B48B8A8576218A860BEC3D492E26CB65A4ECBE209E23D228C00 344AA09E14BA989283B07AFD018D45EB83328A0A6A6065FFC6455AAB5B18C76F5 949D695BE89468034A9B64F02B87E017BD16576E3F782C80BB1677BE151F8D7CF C7CB5B4AD74BC2A9B4133D9E95A2A6D92A68422042DD92D82335CEAE99BDF6C2E C5AC62B583C1A7151693EFB8A80185CDA0ABC78B8879EBA40C4F02B2E95FCEC67 20BF40F29477B65AE38679C3BCE21E792734AF5C01D4E33D30E2BA9D1BC4B35C1 75C27EEC738048CD4608E079FCE4B4D15C8D84895AA2DA72F70FC6E6AF6FC9F02 480BFFD7D4C53956A0D8A8515E34F9205ABC60D86E41C112D78EFE9DB32BC2C42 6DCE4BC2F0BCE9E11F8ED0E507F057DF23119C616B443DD647A2373F6FDA03F81 751AD08E04A61DA310000000049454E44AE42608200"; return r union dbugicos(); end function dbugicos(); begin r := array(); r["添加/删除断点F5"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100022B01000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000C049444154 484B63F84F6330022CB0769FF85F58A98A280C528B0EF05A1095BAE8FFCEBD37A 03CC200A416A40719E0B500E42A5201BA1EFA5AB076D3C5FFF6DE93C16179E4F8 5DEA5B6064DFFDFFF6DDD7501E0D7C802E396A01088C5A800148B2A073E2DEFF3 9A56BFE6FD87A99280C52DB31610F543704E0B500040E1CB9FD3F2967195118A4 161D10B4801000F9121FA0AF0520C5DA961D58BD8F0DFB45CEFE7FEFC11BA86EE C00C50210F8F0F13BD608C48689011816501B0C750BFEFF070066B64F1FB7C689 CB0000000049454E44AE42608200"; r["暂停"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100022401000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000B949444154 484BED8FBB0AC2401045AD2CC4CA0FB0D0CA5E1B7F401B3F3C820A29825A98F8C A0F988744E2C459278F6598ADB450F6C06DE6C23D4C0BBECC1F0B1EE105B2E3E1 9D934FD79AAA7B258F6E74E58882FDA807DB7EBBCA3389A90148374BAD0B16536 A38A2A03980C9E3881A8064EDB05E4214EC061D6DC024F067636A3856A062052A 56C0B0821251D01CC098041809F98361571B300982F9841A8E28B87BAE1AC2A4E E8AAE356587C9AE67BA7244C1A7F875014001DF29EF2FFBC3E1B1000000004945 4E44AE42608200"; r["继续"]:= "0502000000060400000074797065000203000000696D670006040000006461746 10002E201000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000017749444154 484BAD95CB2E035118C73D835BB4112511D61E80A7B0747900AFC003D892A84E1 B246CEC24166A8145C3A60B21128BCE8CA6F4128AD665A42EF93B47BF3363B43A 9D73E697FC33E93933DFAFFDE6CB690788C5F43DB4F30A7D0A0E5B90BAB1108AE 9984916706B7DD2AA3A2E4124AEA3279A41E74A06CBA70FB4A3864B3098307E8A F3441226C636B338BAB6E80E39DC82B82310E16D9BDD2F4AB7CD53C0A3D2B6B60 422036CDF6FDB7C0944FC4C9B9480C769DB2355688EB440A4DEB62B1CE65EA992 1B6581482866603AD9386D81097844DBCCCA3B550D5AB0AA63FEF88E2AD609443 0C44E8089ED1CD2A537AAE6A024E863DFB88B5DA367FF4F92B420ACE998DA2B22 5B75FADD0CDF827ECDC0C8BA891DFD999E6C8D6FC1C249194FB52F7ACA9BB6046 176348CB39798CAFB3FBADD825FFF0722DD6CB6973C8E8356FC119876613E1D93 BB795C946B74871C0D82DEA88EE135135B9755DA51C316F0711BDD3031775042E 1E58356D5B1051CFE2B8205F806770EAF93F6C525FA0000000049454E44AE4260 8200"; r["进入"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100028401000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000011949444154 484BB5954B0AC2301086BD9E3771E3C643780B578AA2A0541405A122EE558A4F7 C811B372E4410DF1219496B8393F4B7EA0759740AF36566DA2422FE8C2248778E 62B5BDCB2795F6F2F25C9FE209287934B513B1D29E95D03B5AD9DE494630940A9 2CD835692E99E3C49C139CB68306F334025C53E56093B6454620D832B6105042A A98ECD83D70A0854529FE8254601814A1A53BE5D8102C224713F6F5AF6FCBD124 840A095B416AA041610AE245EDECBC80BBFC4595F6534A42051310B669B9B8CFE A845FE39846A11DA7F7B1662C8E8CE1B53FE5F300AD0E4B589FEC8D00AD0B6544 6FCCE5D58019ADC1A8438ECD0E4C53E762728023479DEC16F354F805E99B96FAE 4C9270C909FA527427A60976C8BF43880799B976B3940BD8ED0000000049454E4 4AE42608200"; r["跳出"]:= "0502000000060400000074797065000203000000696D670006040000006461746 10002ED01000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000018249444154 484BCD933B4BC3601486FD0F3A3938D841872E0A0AD2C1C141271727577111A48 30E855625A09680507410844E2E2A88508428B45EF082850A2254F1822288E0CF 3872EC39C9C9E5FB92140B3EF041F39E93F7214DDB062DE67F09CCF513D8DEADD 15534220BA66677A0BD3BFB7BF2850AA5E14412C8723E86794C533DA102598E9F E5F5C28A455B6AB4026F3923F38C714869304A81AA9C91F3B95C89523F8182B07 246EEA5330794BAF109A29633727F667E9F520797206E3923EF9B4EEF51DAC016 E09F48575EB2EA901ADD80B1892D7878FAA6D4414A16F347940A01FEAE75E57C3 39EC19102DCD7BF68EAC092CDE215258A972CF196F3E91F5E83DBBB4FDA52A315 78CBF15A66C92113AAB50FDA0E4629082A67E4AC6760152E6FDE68E22750A02B6 7E44EA26F194E2F5E69E2C6278852CEC8DDAEA401E5B3679A38B80471CA19794F 67EF1258E5479A34B00595F397D8E58C947424B2705D7DA789108C4F169B2A67A 404BB185B80561CE093340B7E3DB21CF1BDE4BFA6C502801FF275D8DB8771B6A3 0000000049454E44AE42608200"; {r["单步"] := "0502000000060400000074797065000203000000696D670006040000006461746 100025701000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000EC49444154 484BC5D5CD09C240108661EBB003CBB0801460035E723087282A117F886024A0A 0276F962558893B616565844427BB331B832F783003DF83E46047B7DCFF819BBE EB0B5CF19B3C2B60C6FB2AD0DD474F0F21C2A7B26A81F2F8FBE383587F41561C2 B800FE27C079B62DF087102A604B6DE080B304D60E985B0015304733122024C21 8C45881830E5707A8D72102FE073FC05A81F01D478A862BC7E2702A8F111CCF04 AC706A8F1181678AD8F0550E35358E3D59E13A0C61348F1EACE0A50E32BC8F0CA CB0A046A50194F21C70B3F2B50FE4FD8C1019FCA72BE0383E4C519BFC973024D6 B19D0FA0973865C3E24DD42ED0000000049454E44AE42608200";} r["下一行(F8)"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100025E01000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000F349444154 484BED93CD0A015118865D835BB0B37509EEC2CE6DB8105694B29C859548766E4 0ACFC6450148A1AA349C3A7777E0E66CE9C9F290BE5A96F31DF999EA74E9D0C7D 997F400A0B5C6E77AA8D4E3458DBC1261D8EFBA0C6E44CFBABEB7DB340D1D850B 63AF3A6DCDB055B3DDA738BF2CD25F3F457B61F30A6165B86A31B813CEA28B44C 3F303E3AB1438C6A8427C7943ADBD71541C6FB4916499263BA66704521BA11911 C67E0230054232A72100B005944550EB801208AF0F698A81C24068048161D9E1C 08034025922407D200D0BD96779402801791C9817200548607CAD517DE0B55910 3AD401AFE0129BF1E207A02B9FA383F9BCBB70F0000000049454E44AE42608200 "; r["终止"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100026602000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000001FB49444154 484BED94596B145114847DC8BEAF6423FBBE424296FFFF3F444386CC609C314EA 2AD498629EBEBE92B361C8982C197141C98BEC3AD3A5DA74EBFD10BE355E059FC 1F81F6D999F46B9D9E4AC7C7D2D191B4BFAF2757B6B7A7A6ABE1AAF9B9727050D C2E237E03482F2E3A757EDE793E39E908ECEE4A9B9B7A747DDDD8D0EDD6966EB6 B755D9D9292E97F16702E90D0E0F2593696D4DAD951565CBCB6AAEAEEAA39FABE BEBC5E5327E2F007122A77BC8E91EA2A525696E4EDFE7E775B7B0A0FAE2A2AA16 8B100B409ABC4FD6D86BAC913B9789DB53537A74DDCDCCA8313BABAACF22C402D 80171B205727B9D93BB6399B83D36A607D7FDF8B81A9393AA4D4F1797CB8805E8 984AB6D0B9BDCEC9211A1D556B6848DF5CF7C3C3AA8F8CA83631515C2E231670E C7262068AE7A9F3825CFDFD7AEAEB53D6DBABE6C080EA16AA5A24422840CEF3AE 9D8E7CA0F86B5B1279CBE40F3D3DFAD2DDAD4F16B9B1C8F5DF08B044E49C28921 6068AE7D842E790675D5DFA6C8186AB66D18AFF8B100AB0A12C1139278AA48581 E27966323A4FE41FFC06D73EBB1A1C2C6E97110AB0FE6C284B44CE89226961A07 88E2D3FC95D573E7BEFFF2284027C5B587F36942522E74491B430503CC796BC73 FFBEF4D93BE6132014E0C3C5B785F567435922724E14490B03C5F34B774DE790B F75031142817F89578167F1C202D20F98CF9591BE2EF7850000000049454E44AE 42608200"; r["刷新符号表"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100027702000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000020C49444154 484BC596DD4B145118C6FBEBBA13C12B6FBAE8224C414A08BA116BD584C050171 752D02093B6442D2F84CA34B520D35CBFC036493445CAAC50776D5D9DF771DEF3 313B677766F6EBA21F3C3767E73CCF9CF39EF3CE5E42996CEF03D7C2845B7DA44 64C0203D2E7C0EE0110FB068C2F1086DE1396364DA3CE1784CB8D96D0444C0DBA F00D189F275C699713BD74B5C342FB70C69C551B21A4D2E60BE404ECFC025A9E9 A138BD1E05440006F49436FE9E6ACAA7B16BEDB75D118010F46CB33D7EAB0EBA2 71020626A5F9F56E0B8FDF5A58DF31977A74024C2E93D8F7EAFBDEC66E2D6CC87 94E4043AF4C3E4CAA81003E7E81A7A95BFC928C08F89B80335008AD51FFADAC6A B5C4EF7C3F181130B3666E473EF8526943DEAEBB8384E88CBC23E933F590C2287 2A1FCF80361B6F75B0D0450524031FCFF80AD9F843731C2A7787175D2E40424FE 01EF5608E131428D7D277431FDBAA51FF35FE5F34E001FD31B3D19C36CF5BF2E2 CE0E4541E63DD2E44009B7B99BAB5B6259E0F64D16EEBF50F65173E55C755046C EC0115216F63AD8A10A1E909E1F92C612E2E8FA9D6C807C2ED4799BBF1EA7366B 5CE16E95E54AEBA5E9A1DC10948A581BA88F7A44275C75E61364E0033B592BF89 F9697A5599646104306DCFCC89BCE49B76A7AD6C36C759B5F631E60E1CDF55933 DC80970173CBBC31EDBDF84ED7D59D8644A0DE62127806163FE2BA25B6EE90017 13C9EE8D2E4822C60000000049454E44AE42608200"; r["刷新当前符号"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100027802000089504E470D0A1A0A0000000D4948445200000018000000180806 000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA8640000020D49444154 484BB594DD2BA74114C7F7EF70A914529262BD5C798B645F5A2552EE5C4872837 2B1524A6D5C59C566A98D52ECC55228B4ED850B3724424A5A89B8D9B597CFBC1C 7D4F679EE691C76EC37E6AFACD3933BFF93E73E63BF382FE3309815DBB4F8BF61 B4DE8695AB7DF25FB34628151F39132A29C442B5655321A0E0B1CDAE378D1CF66 96CEE827B5EA768E87F4084F0C8505E6CC022F76BF2CF9513995A81A89C260812 F669E05F0E53E9DBA87B2A32289C260814B7BC502288B0F726DBA43A230E243C6 D7624194A5570F701FED5FDC8439701E1C0827FAC402E0AB59A6DCE8252FDCAEB B69D9ACC9483A709AFB18D7E04847420038BBD6AA46C9A40387612E4A8BF38303 9D089C095205D046F498641F060E43497D502EFC17CE04A9020366987FDFA936D AB17B329A24332AE0B3F3C14EF03F9C09481500AB6683AAD55B8E1B54330DEA0F B465B669D12CD1A499A14AF5269EEB7017D499E35101704B7F68CC7CA20AF59AF 37E2B53B5BC0BF4E13C940B7DFF89F9AB800FC40EEC119DD853C910EFE8956AA1 2C55C86772FF694908F836456D7FD16F1909271670170D027E7FD3FC901961B0C 0B9BDE005BB741F271DC8F5E8F71285C102D37241AEE986930E1C5C5E542A5118 2C80370402B8893E285179542751182C80070A0268F02F76827221EED6FD3C319 4F890FD27C2B57AD524A3E1C402000F14DE907133452B765DB24F2321F0FC10DD 0144332BF870524ED00000000049454E44AE42608200"; return r; end function ejsonformat(d,tbw,ct); begin //d:天软数据 //tbw : 字符串,tab 宽度 //ct 递归深度,忽略 case datatype(d)of 0,20:return inttostr(d); 1:return floattostr(d); 2:return tostn(d); 8,10,11,12:return "null"; end; if not(ct>0)then ct := 0; if not ifstring(tbw)then tbw := " "; tbstr := ""; tbstra := ""; for i := 0 to ct do begin tbstr += tbw; if i>0 then tbstra += tbw end if ifarray(d)then begin if not d then return "[]"; idx := 0; for i,v in d do begin if idx <> i then begin fobj := true; break; end idx++; end if fobj then begin r := "{"; for i,v in d do begin if ifstring(i)then ii := tostn(i); else ii := tostn(tostn(i)); r += "\r\n"+tbstr+ii+":"; if ifarray(v)and v then begin r += "\r\n"+tbstr; end r += ejsonformat(v,tbw,ct+1)+","; end lr := length(r); r[lr:]:= "\r\n"+tbstra+"}"; end else begin r := "["; for i,v in d do begin r += "\r\n"+(tbstr)+ejsonformat(v,tbw,ct+1)+","; end lr := length(r); r[lr:]:= "\r\n"+tbstra+"]"; end return r; end else if ifobj(d)then begin try //return "{}"; //此处可以遍历对象信息 objtoarray(d,dinfo); for i,v in mrows(dinfo,1) do begin nv := invoke(d,v); if ifobj(nv)then nv := nil; //避免死循环 dinfo[v]:= nv; end return ejsonformat(dinfo,tbw,ct); except return "{}"; end end else return "null"; end function objtoarray(o,r); begin d := o.classinfo(); if not ifarray(r)then r := array(); for i,v in d["inherited"] do begin objtoarray(findclass(v,o),r); end for i,v in d["members"] do begin n := v["name"]; if v["access"]in array(0,1)then begin r[n]:= 0; end else begin reindex(r,array(n:nil)); end end for i,v in d["properties"] do begin n := v["name"]; if v["read"]and(v["access"]in array(0,1))then begin r[n]:= 0; end else begin reindex(r,array(n:nil)); end end end function ReWriteString(fn,d); begin if not ifstring(d)then return 0; als := ""; len := length(d); if FileExists(als,fn)and(filesize(als,fn)>len)then begin lfn := FileList(als,fn); //修正文件名变小写的问题 if lfn then begin nfn := lfn[0,"FileName"]; if nfn then begin for i := length(fn)downto 1 do begin if fn[i]="\\" then begin fn := fn[1:i]+nfn; break; end end end end FileDelete(als,fn); end else begin CreateDirWithFileName(fn); end spos := 0; return writefile(rwraw(),als,fn,spos,len,d); end function gettslexe(); begin return static gettslexefullpath(); end function gettslexefullpath(); begin plg := pluginpath(); sp := ioFileseparator(); for i:= length(plg)-1 downto 1 do begin if plg[i]=sp then begin if sp="/" then begin return plg[1:i]+"TSL"; end else begin return plg[1:i]+"tsl.exe"; end end end return ""; end {$ifdef linux} function HtmlHelpA() begin return 0; end function GetDesktopWindow() begin return 0; end {$else} function HtmlHelpA(hwndCaller:pointer;pszFile:string;uCommand:integer;dwData:pointer):pointer;stdcall;external "HHCTRL.OCX" name "HtmlHelpA"; function GetDesktopWindow():pointer;stdcall;external "User32.dll" name "GetDesktopWindow"; {$endif} end.