⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editunit.pas.svn-base

📁 支持自定义语法高亮显示的编辑器控件
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
end;

procedure TEditForm.ShowMethodHint(const s: string; APoint: TPoint;
  CheckBold: boolean; AKeepHint : boolean = false);
begin
  if s = '' then
    exit;
  with EasyEdit, TextToPixelPoint(APoint, false) do
  begin
    ShowPopupHintEx(s, ClientToScreen(Point(X, Y + EasyEdit.Painter.GetLineHeight(APoint.X, APoint.Y, false) + 1)), false, AKeepHint);
    if CheckBold then
      CheckMethodParams;
  end;
end;

procedure TEditForm.CheckMethodParams;
var
  i     : integer;
  Index : integer;
  info  : TFunctionInfo;
  str   : string;

  procedure AddBoldSting(const AStr : string; ABold : boolean);
  begin
    if ABold then
      str := str + '\b ' + AStr + '\b0 '
    else
      str := str + AStr;
  end;

begin
  str := '';
  Index := GetParamIndex;
  if Index < 0 then
    EasyEdit.HidePopupHint;
  info := GetFunctionInfo(EasyEdit);
  if (info <> nil) and (info.Params <> nil) then 
    begin
      for i := 0 to info.Params.Count - 1 do
        begin
          AddBoldSting(info.Params[i], i = Index);
          if i < info.Params.Count - 1 then
            str := str + ', ';
        end;
        if str <> '' then
          str := '(' + str + ')'
        else
          str := sNoParams;  
    end;
    EasyEdit.PopupHint.Caption := str;
end;

function TEditForm.GetParamIndex: integer;
var
  s     : string;
  Pt    : TPoint;
  p     : integer;
  Index : integer;
begin
  result := -1;
  Index := -1;
  if IsMethod(s, Pt) then
    begin
      if Pt.X >= 0 then
        Index := EasyEdit.CurrentPosition.X - Pt.X;
      if Index >= 0 then
        result := 0;
      s := Copy(EasyEdit.EditSource.Strings.GetStr(EasyEdit.CurrentPosition.Y), Pt.X + 1, Index);
      P := Pos(',' , s);
      while (p <> 0) and (p <= Index) do
      begin
        inc(result);
        s := Copy(s, p + 1, Length(s));
        Index := Index - p;
        p := Pos(',', s);
      end;
    end;
end;

function TEditForm.IsMethod(var s : string; var Pt : TPoint) : boolean;
var
  pLeft    : integer;
  ss       : string;
  Info     : TFunctionInfo;

  function _IsMethod: boolean;
  begin
    Info := nil;
    Info := GetFunctionInfo(EasyEdit);
    result := Info <> nil;
  end;

begin
  Pt := Point(-1, -1);
  s := '';
  result := _IsMethod;
  if not result then
    exit;
  ss := EasyEdit.EditSource.Strings.GetStr(EasyEdit.CurrentPosition.Y);
  pLeft := Pos('(', ss);
  Pt.X := pLeft;
  Pt.Y := EasyEdit.CurrentPosition.Y;
  if Info <> nil then
  begin
    if Info.Params.Count > 0 then
      s := Info.ParamText
    else
      s := sNoParams;
  end;
end;

procedure TEditForm.EasyEditSelectionChanged(Sender: TObject);
begin
  CheckMethodParams;
end;

procedure TEditForm.EasyEditKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = ' ') then
    if (GetAsyncKeyState(VK_CONTROL) and $80000000) <> 0 then
    begin
      CheckCtrlSpace;
      Key := #0;
    end;
end;

procedure TEditForm.CheckCtrlSpace;
var
  i        : integer;
  AStrings : TStrings;
  ALeft : integer;
  ARight : integer;

  function GetFunctionInfo(APos : integer): TFunctionInfo;
  var
    i : integer;
  begin
    result := nil;
    for i := 0 to UnitInfo.Functions.Count - 1 do
      if (APos >= TFunctionInfo(UnitInfo.Functions.Objects[i]).StartPos) and
       (APos <= TFunctionInfo(UnitInfo.Functions.Objects[i]).EndPos) then
        begin
          result := TFunctionInfo(UnitInfo.Functions.Objects[i]);
          break;
        end;
  end;

begin
  EasyEdit.Options := EasyEdit.Options + [eoTripleClickLine];
  AStrings := TStringList.Create;
  try
    FillInfo(AStrings, GetFunctionInfo(EasyEdit.CurrentPosition.Y));
    if AStrings.Count > 0 then
    begin
      for i := 0 to AStrings.Count - 1 do
        EasyEdit.PopupWindow.ImageIndex[i] := Integer(AStrings.Objects[i]);
      with TMEdit(EasyEdit), EditSource do
      begin
        GetWord(CurrentPosition, ALeft, ARight, wsWord);
        if (ALeft < ARight) or ((ALeft = ARight) and (ARight > 0)) then
          AutoCompletePos := Point(ALeft - 1, CurrentPosition.Y)
        else
          AutoCompletePos := CurrentPosition;
      end;
      EasyEdit.ShowPopupListBox(AStrings, false);
    end;
  finally
    AStrings.Free;
  end;
end;

procedure TEditForm.EasyEditDisplayHint(Sender: TObject; var s: String;
  AKey: Char; var AllowPopup: Boolean);
var
  Pt : TPoint;
begin
  AllowPopup := AKey = '(';
  if AllowPopup then
    if IsMethod(s, Pt) then
      begin
        ShowMethodHint(s, Pt, true, true);
        AllowPopup := false;
      end;
end;

procedure TEditForm.EasyEditAutoComplete(Sender: TObject;
  Strings: TStrings; AKey: Char; var AllowPopup: Boolean);
begin
  AllowPopup := (AKey = '.');
  if AllowPopup then
    FillCodeCompletion(Strings);
end;

procedure TEditForm.FillCodeCompletion(Strings: TStrings);
var
  s      : string;
  Cmp    : TComponent;
  AClass : TClass;
begin
  Strings.Clear;
  EasyEdit.PopupWindow.Images.Free;

  with EasyEdit, EditSource, CurrentPosition do
    s := GetTextAt(Point(X - 1, Y), false);

  if (s <> '') and (s[Length(s)] = '.') then
    Delete(s, Length(s), 1);

  AClass := GetClass(s);

  if AClass <> nil then
    FillStrings(Strings, AClass)
  else
  begin
    Cmp := EasyEdit.Owner.FindComponent(s);
    if Cmp <> nil then
      FillStrings(Strings, Cmp.ClassType)
    else
      FillStrings(Strings, TWinControl);
  end;
end;

procedure TEditForm.FillStrings(Strings: TStrings; AClass: TClass);
var
  i         : integer;
  Count     : integer;
  RealCount : integer;
  PropInfo  : PPropInfo;
  PropList  : PPropList;
begin
  Count := GetTypeData(AClass.ClassInfo)^.PropCount;
  if Count > 0 then
  begin
    GetMem(PropList, Count * SizeOf(Pointer));
    try
      RealCount := GetPropList(AClass.ClassInfo, tkAny, PropList);
      for i := 0 to RealCount - 1 do
      begin
        PropInfo := PropList^[i];
        Strings.Add(Format(sColorTable + sPropStr, [PropInfo.Name, PropInfo.PropType^.Name]));
      end;
    finally
      FreeMem(PropList, Count * SizeOf(Pointer));
    end;
  end;
end;

procedure TEditForm.EasyEditBeforeInsertPopup(Sender: TObject;
  var s: String);
var
  i          : integer;
  IsFunction : boolean;
begin
  GetPlainString(s, IsFunction);
  if IsFunction then
  begin
    i := UnitInfo.Functions.IndexOf(s);
    if i >= 0 then
    begin
      s := s + '()';
      FFunctionIndex := i;
    end;
  end;
end;

procedure TEditForm.DoPopupClosed(Sender: TObject);
begin
  if FFunctionIndex >= 0 then
    begin
      EasyEdit.EditSource.JumpToChar(EasyEdit.CurrentPosition.X - 1);
      ShowMethodHint(TFunctionInfo(UnitInfo.Functions.Objects[FFunctionIndex]).ParamText, EasyEdit.CurrentPosition, true);
      FFunctionIndex := -1;
    end;
end;

procedure TEditForm.EasyEditFindStringInPopup(Sender: TObject;
  Strings: TStrings; const s: String; var Index: Integer;
  var Handled: Boolean);
var
  i            : integer;
  ss           : string;
  AStrings     : TStringList;
  Visible      : boolean;
begin
  Index := -1;
  ss := UpperCase(s);
  AStrings := TStringList.Create;
  try
    AStrings.Assign(Strings);
    GetPlainText(AStrings);

    TMEasyPopupWindow(EasyEdit.PopupWindow).StringsChanged(Strings);
    
    for i := 0 to AStrings.Count - 1 do
    begin
      Visible := (Pos(ss, UpperCase(AStrings[i])) = 1) or (ss = '');
      TMEdit(EasyEdit).PopupWindow.ItemVisible[i] := Visible;
    end;

    if (ss <> '') and (AStrings.Count > 0) then
      Index := 0;

    Handled := true;
    for i := 0 to EasyEdit.PopupListBox.Items.Count - 1 do
      EasyEdit.PopupListBox.ImageIndex[i] := Integer(EasyEdit.PopupListBox.Items.Objects[i]);
  finally
    AStrings.Free;
  end;
end;

procedure TEditForm.GetPlainText(AStrings: TStrings);
var
  i          : integer;
  s          : string;
  IsFunction : boolean;
begin
  for i := 0 to AStrings.Count - 1 do
    begin
      s := AStrings[i];
      GetPlainString(s, IsFunction);
      AStrings[i] := s;
    end;
end;

procedure TEditForm.GetPlainString(var s: string; var IsFunction : boolean);
var
  P : integer;
begin
  IsFunction := Pos('Function', s) > 0;
  P := Pos('|', s);
  if P <> 0 then
    Delete(s, 1, P);
  s := Trim(s);
  P := Pos(' ', s);
  if P <> 0 then
    Delete(s, P, MaxInt);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -