• delphi在TMemo中实现高亮文字


    delphi在TMemo中实现高亮文字
    在memo中实现类似IDE的效果,对数字及自定义的关键字高亮显示,并自定义关键字

    unit Unit1;
    
     
    
    interface
    
     
    
    uses
    
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    
      Dialogs, StdCtrls;
    
    type
    
      TMemo = class(stdctrls.TMemo)
    
      private
    
        procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    
        procedure WMSize(var Message: TWMSize); message WM_SIZE;
    
        procedure WMMove(var Message: TWMMove); message WM_MOVE;
    
        procedure WMVScroll(var Message: TWMMove); message WM_VSCROLL;
    
        procedure WMMousewheel(var Message: TWMMove); message WM_MOUSEWHEEL;
    
      protected
    
        procedure Change; override;
    
        procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    
        procedure KeyUp(var Key: Word; Shift: TShiftState); override;
    
        procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    
          override;
    
        procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    
          override;
    
      public
    
        PosLabel: TLabel;
    
        procedure Update_label;
    
        procedure GotoXY(mCol, mLine: Integer);
    
        function Line: Integer;
    
        function Col: Integer;
    
        function TopLine: Integer;
    
        function VisibleLines: Integer;
    
      end;
    
    type
    
      TForm1 = class(TForm)
    
        Label1: TLabel;
    
        GroupBox1: TGroupBox;
    
        KeywordList: TListBox;
    
        GroupBox2: TGroupBox;
    
        GroupBox3: TGroupBox;
    
        Memo1: TMemo;
    
        Label2: TLabel;
    
        procedure FormCreate(Sender: TObject);
    
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
    
      private
    
        { Private declarations }
    
      public
    
        { Public declarations }
    
      end;
    
     
    
    var
    
      Form1: TForm1;
    
     
    
    implementation
    
     
    
    {$R *.dfm}
    
    //分隔符,如有特殊需要自己添加
    
    function IsSeparator(Car: Char): Boolean;
    
    begin
    
      case Car of
    
        '.', ';', ',', ':', '?', '!', '"', '''',' ', '^', '+', '-', '*', '/', '', '`', '[', ']', '(', ')', 'o', 'a', '{', '}', '%', '=': Result := True;
    
      else
    
        Result := False;
    
      end;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    function NextWord(var s: string; var PrevWord: string): string;
    
    begin
    
      Result := '';
    
      PrevWord := '';
    
      if s = '' then Exit;
    
      while (s <> '') and IsSeparator(s[1]) do
    
      begin
    
        PrevWord := PrevWord + s[1];
    
        Delete(s, 1, 1);
    
      end;
    
      while (s <> '') and not IsSeparator(s[1]) do
    
      begin
    
        Result := Result + s[1];
    
        Delete(s, 1, 1);
    
      end;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    function IsKeyWord(s: string): Boolean;
    
    begin
    
      Result := False;
    
      if s = '' then Exit;
    
      Result := Form1.KeywordList.Items.IndexOf(lowercase(s)) <> -1;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    function IsNumber(s: string): Boolean;
    
    var
    
      i: Integer;
    
    begin
    
      Result := False;
    
      for i := 1 to Length(s) do
    
        case s[i] of
    
          '0'..'9': ;
    
        else
    
          Exit;
    
        end;
    
      Result := True;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
    ////////////////////////////////////////////////////////////////////////////////
    
    ////////////////////////////////////////////////////////////////////////////////
    
    // New or overrided methods and properties for TMemo using Interjected Class ///
    
    // Technique ///////////////////////////////////////////////////////////////////
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    function TMemo.VisibleLines: Integer;
    
    begin
    
      Result := Height div (Abs(Self.Font.Height) + 2);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.GotoXY(mCol, mLine: Integer);
    
    begin
    
      Dec(mLine);
    
      SelStart := 0;
    
      SelLength := 0;
    
      SelStart := mCol + Self.Perform(EM_LINEINDEX, mLine, 0);
    
      SelLength := 0;
    
      SetFocus;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.Update_label;
    
    begin
    
      if PosLabel = nil then Exit;
    
      PosLabel.Caption := '(' + IntToStr(Line + 1) + ',' + IntToStr(Col) + ')';
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    function TMemo.TopLine: Integer;
    
    begin
    
      Result := SendMessage(Self.Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    function TMemo.Line: Integer;
    
    begin
    
      Result := SendMessage(Self.Handle, EM_LINEFROMCHAR, Self.SelStart, 0);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    function TMemo.Col: Integer;
    
    begin
    
      Result := Self.SelStart - SendMessage(Self.Handle, EM_LINEINDEX,
    
        SendMessage(Self.Handle,
    
        EM_LINEFROMCHAR, Self.SelStart, 0), 0);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.WMVScroll(var Message: TWMMove);
    
    begin
    
      Update_label;
    
      Invalidate;
    
      inherited;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.WMSize(var Message: TWMSize);
    
    begin
    
      Invalidate;
    
      inherited;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.WMMove(var Message: TWMMove);
    
    begin
    
      Invalidate;
    
      inherited;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.WMMousewheel(var Message: TWMMove);
    
    begin
    
      Invalidate;
    
      inherited;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.Change;
    
    begin
    
      Update_label;
    
      Invalidate;
    
      inherited Change;
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.KeyDown(var Key: Word; Shift: TShiftState);
    
    begin
    
      Update_label;
    
      inherited KeyDown(Key, Shift);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.KeyUp(var Key: Word; Shift: TShiftState);
    
    begin
    
      Update_label;
    
      inherited KeyUp(Key, Shift);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    
    begin
    
      Update_label;
    
      inherited MouseDown(Button, Shift, X, Y);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    
    begin
    
      Update_label;
    
      inherited MouseUp(Button, Shift, X, Y);
    
    end;
    
    ////////////////////////////////////////////////////////////////////////////////
    
     
    
    procedure TMemo.WMPaint(var Message: TWMPaint);
    
    var
    
      PS: TPaintStruct;
    
      DC: HDC;
    
      Canvas: TCanvas;
    
      i: Integer;
    
      X, Y: Integer;
    
      OldColor: TColor;
    
      Size: TSize;
    
      Max: Integer;
    
      s, Palabra, PrevWord: string;
    
    begin
    
      DC := Message.DC;
    
      if DC = 0 then DC := BeginPaint(Handle, PS);
    
      Canvas := TCanvas.Create;
    
      try
    
        OldColor := Font.Color;
    
        Canvas.Handle := DC;
    
        Canvas.Font.Name := Font.Name;
    
        Canvas.Font.Size := Font.Size;
    
        with Canvas do
    
        begin
    
          Max := TopLine + VisibleLines;
    
          if Max > Pred(Lines.Count) then Max := Pred(Lines.Count);
    
     
    
          //Limpio la sección visible
    
          Brush.Color := Self.Color;
    
          FillRect(Self.ClientRect);
    
          Y := 1;
    
          for i := TopLine to Max do
    
          begin
    
            X := 2;
    
            s := Lines[i];
    
     
    
            //Detecto todas las palabras de esta línea
    
            Palabra := NextWord(s, PrevWord);
    
            while Palabra <> '' do
    
            begin
    
              Font.Color := OldColor;
    
              TextOut(X, Y, PrevWord);
    
              GetTextExtentPoint32(DC, PChar(PrevWord), Length(PrevWord), Size);
    
              Inc(X, Size.cx);
    
     
    
              Font.Color := clBlack;
    
              if IsKeyWord(Palabra) then
    
              begin
    
                Font.Color := clHighlight;
    
     
    
                TextOut(X, Y, Palabra);
    
                 {
    
                 //Draw dot underline
    
                 Pen.Color := clHighlight;
    
                 Pen.Style := psDot;
    
                 PolyLine([ Point(X,Y+13), Point(X+TextWidth(Palabra),Y+13)]);
    
                 }
    
              end
    
              else if IsNumber(Palabra) then
    
              begin
    
                Font.Color := $000000DD;
    
                TextOut(X, Y, Palabra);
    
              end
    
              else
    
              begin
    
     
    
                TextOut(X, Y, Palabra);
    
               end;
    
              GetTextExtentPoint32(DC, PChar(Palabra), Length(Palabra), Size);
    
              Inc(X, Size.cx);
    
     
    
              Palabra := NextWord(s, PrevWord);
    
              if (s = '') and (PrevWord <> '') then
    
              begin
    
                Font.Color := OldColor;
    
                TextOut(X, Y, PrevWord);
    
              end;
    
            end;
    
            if (s = '') and (PrevWord <> '') then
    
            begin
    
              Font.Color := OldColor;
    
              TextOut(X, Y, PrevWord);
    
            end;
    
     
    
            s := 'W';
    
            GetTextExtentPoint32(DC, PChar(s), Length(s), Size);
    
            Inc(Y, Size.cy);
    
          end;
    
        end;
    
      finally
    
        if Message.DC = 0 then EndPaint(Handle, PS);
    
      end;
    
      Canvas.Free;
    
      inherited;
    
    end;
    
     
    
    procedure TForm1.FormCreate(Sender: TObject);
    
    begin
    
      Memo1.PosLabel := Label1;
    
      Memo1.Update_label;
    
    end;
    
     
    
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    
    begin
    
      Action := caFree;
    
    end;
    
     
    
    end.
  • 相关阅读:
    PAT甲题题解-1106. Lowest Price in Supply Chain (25)-(dfs计算树的最小层数)
    PAT甲题题解-1105. Spiral Matrix (25)-(模拟顺时针矩阵)
    PAT甲题题解-1102. Invert a Binary Tree (25)-(建树,水题)
    PAT甲题题解-1101. Quick Sort (25)-大水题
    PAT甲级题解-1100. Mars Numbers (20)-字符串处理
    XJOI网上同步训练DAY1 T2
    XJOI网上同步训练DAY1 T1
    BZOJ 1061 志愿者招募
    BZOJ 2432 兔农
    KMP算法总♂结
  • 原文地址:https://www.cnblogs.com/jijm123/p/14098303.html
Copyright © 2020-2023  润新知