unit UtslCodeEditor; { 编辑器相关的代码20220518整理, 20220520 分离调试器代码 } interface uses utslvcldesignerresource,cstructurelib,utslvclauxiliary,utslvclmemstruct,utslvclgdi,tslvcl,UTslmemo,UTslSynMemo,utslvclsyntaxparser,utslvcldebuger; { 1. page标签 TPagees; TPageItem 2. TMemoPages ,TMemoPageItem 3. TEchoWnd 4. TFindResultWnd 5. FindStringWnd 查找框 5. TGotoLineWnd 跳转 } 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 TFTSLScriptMemo = class(TFTSLScriptcustomMemo) function create(AOwner); begin inherited; end 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 adduses(libs);//添加uses begin if not FTslParser then return 0; if not(libs and ifarray(libs))then return; d := GetClassInfo(); if not(d and ifarray(d))then return 0; usd := d["uses"]; if usd then //存在uses begin adu := lowercase(libs) minus (usd["info"]) ; if adu then begin adus := array2str(adu,","); if adus then begin usd["beg"]+=5; adus +=","; rec := GetInfoRowCol2(usd); p := rec[0]; if ifarray(p) then begin FEditer.ExecuteCommand(FEditer.ecGotoXY,rec[0]); FEditer.ExecuteCommand(FEditer.ecString,adus); end end end end { else begin adus := array2str(lowercase(libs),","); ups := d["inheritedendpos"]; if adus and ups>0 then begin ups +=1; adus+=";"; //添加uses 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 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 ttslscripparser(); #! 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 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 it.fisnewfile then //单独处理新建关闭 begin f := it.OrigScriptPath; DeletePageItem(it); if fileexists("",f) then filedelete("",f); end else begin 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 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); ECHO "==222=>>>"; 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 then begin case e.charcode of VK_F9: begin if ssctrl in e.ShiftState()then begin ShowExeEditer(); e.skip := true; return true; end ExecutePageItem(GetCurrentItem()); e.skip := true; return true; end end; end 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_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 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 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 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 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 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 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 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 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 function GetEditIcons(); begin r := array(); r["打开文件"]:= getopenfilebmpinfo(); r["保存全部"]:= getsaveallbitmapinfo(); r["保存"]:= GetSaveFileBitmapInfo(); r["取消注释"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100022001000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000B549444154 5847ED95C109C5200C40FF4E4EE15D07D0832B787142F1EC0C2EE03925FC2A9F9 2160A7EE3C10739546DF220113FC0CC16D8026B0AD45A21A5343430270529E09C 0321C4D0C09C146B0AB0B76026EB0B78EF2184707E8DE751008BB721C23EFE035 2A094024AA95EDC180331C63E5039E7F3E497B6FE14AF86504AD98BDF45039353 FBD778750DD905B0055AEBFEB3B5766E0B1A6C43F80BEB359CC19A02EC8F11FB7 3CC2EC0DE82996C812DC02C0070005765629339C9EFE60000000049454E44AE42 608200"; r["注释"]:= "0502000000060400000074797065000203000000696D670006040000006461746 100021201000089504E470D0A1A0A0000000D4948445200000020000000200806 000000737A7AF4000000017352474200AECE1CE90000000467414D410000B18F0 BFC6105000000097048597300000EC300000EC301C76FA864000000A749444154 5847ED94410A80201045BB9377F20A6EBD9757F03A82BB8909021333B56F1AF8E 0D3A2181F8CFD8D06B30496C09C02CE39B2D642C333532405A4942484808667A6 985360F80ABEE41F02C6986387FC445324105E26B444D125D45A6725C26FEF02E F81538287A7DEC781F740578170058C52EA32ACFB0A42BCF7D9C3DFF228C0F0A1 437FC39ECC2910F70022F01EA80DBC076AD3DC03A834F7406F96C012182C40B40 319335F36295E4B140000000049454E44AE42608200"; r["撤销"]:= getredobitmapinfo(); r["反撤销"]:= getunredobitmapinfo(); r["tsl语法检查"]:=gettslsyntaxcheckbitmapinfo(); r["tsl代码格式化"]:= gettslcodeformatbitmapinfo(); r["查找"]:=getfindbitmapinfo(); 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["快捷键说明"]:= getquickkeybitmapinfo(); r["代码地图(alt+m)"]:= gettslcodemapbitmapinfo(); 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 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 {$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.