打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
delphi在TMemo中实现高亮文字
delphi在TMemo中实现高亮文字(1)

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.

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Delphi中关于NMUDP控件的用法(原创)
给 TStringGrid 添加鼠标拖动功能
DELPHI中鼠标的各种操作
SCROLLBOX的MouseWheel
JSON 之 SuperObject(17): 实例
delphi实现屏幕截图
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服