reinier stam
reinier stam

Reputation: 148

Highlighting delphi code in RAD Studio

I am trying to highlight Delphi code in RAD Studio with a Delphi plugin. I use OpentoolsAPI to get code out of the editor.

EditorServices := BorlandIDEServices as IOTAEditorServices;

Buffer := EditorServices.TopBuffer;
Editblock := EditorServices.TopView.GetBlock;
Buffer.EditPosition.Move(1,1);
Editblock.BeginBlock;
Editblock.Extend(10,5);

After that, the open tools FAQ tells me to use a custom highlighter. I copied a custom highlighter from here : http://www.delphi-central.com/syntax_highlighting.aspx

But still, The documentation is very limited, and I cannot figure a way to use this custom highlighter. What I am currently trying is the following:

HighlightServices := BorlandIDEServices as IOTAHighlightServices;
SimpleHighLight := TSimpleHighlight.Create;
HighlightServices.AddHighlighter(SimpleHighLight);

Text := Editblock.Text; //string
StartClass := 1; //integer
SyntaxByte := SyntaxOff; //byte
SyntaxCode := @SyntaxByte; //POTASyntaxCode

SimpleHighLight.Tokenize(StartClass,Addr(Text),Text.Length, SyntaxCode);

But that results in an access violation error at this line of the demo code:

FillChar(HighlightCodes^, LineBufLen, $E);

Can somebody give me an example of the right implementation? Or help me out with what I am doing wrong?

Upvotes: 1

Views: 1492

Answers (1)

reinier stam
reinier stam

Reputation: 148

I stopped looking for a way to use the highlighter. I could not get it working.

Luckely i found an other solution to my problem, for anyone interested :)

The OpenToolsAPI makes it possible to add notifiers. an example notifier can be found here: http://www.gexperts.org/examples/IdeNotifier.pas.

I had to modify the notifier from the example to my own notifier. This is the result:

unit ViewPaintNotifier;

interface

uses
  ToolsAPI, System.Types, Vcl.Graphics;

type
  TViewPaintNotifier = class(TInterfacedObject, IOTANotifier, INTAEditViewNotifier)
  private
  public
    constructor Create;
    destructor Destroy; override;
  public
    // INTAEditViewNotifier
    procedure BeginPaint(const View: IOTAEditView; var FullRepaint: Boolean);
    procedure EditorIdle(const View: IOTAEditView);
    procedure EndPaint(const View: IOTAEditView);
    procedure PaintLine(const View: IOTAEditView; LineNumber: Integer;
      const LineText: PAnsiChar; const TextWidth: Word;
      const LineAttributes: TOTAAttributeArray; const Canvas: TCanvas;
      const TextRect: TRect; const LineRect: TRect; const CellSize: TSize);
    // IOTANotifier
    procedure AfterSave;
    procedure BeforeSave;
    procedure Destroyed;
    procedure Modified;
  end;

  procedure register(View: IOTAEditView);
  procedure RemoveNotifier(View: IOTAEditView);

implementation

uses
  System.SysUtils, Vcl.Dialogs, System.Generics.Collections;

var
  NotifierIndexDictionary : TDictionary<string,Integer>;

procedure Register(View: IOTAEditView);
var
  Services: IOTAEditorServices;
  NotifierIndexPair : Tpair<string,Integer>;
begin
  if not Assigned(NotifierIndexDictionary) then
     NotifierIndexDictionary := TDictionary<string,Integer>.create;
  NotifierIndexPair := NotifierIndexDictionary.ExtractPair(View.Buffer.FileName);

  if (NotifierIndexDictionary.ExtractPair(View.Buffer.FileName).Value = 0) then
  begin
    NotifierIndexDictionary.Add(View.Buffer.FileName,View.addNotifier(TViewPaintNotifier.Create));
  end;
end;

procedure RemoveNotifier(View: IOTAEditView);
var
  Services: IOTAEditorServices;
begin
  if (NotifierIndexDictionary.ExtractPair(View.Buffer.FileName).Value > 0) then
  begin
    View.RemoveNotifier(NotifierIndexDictionary.ExtractPair(View.Buffer.FileName).Value);
    NotifierIndexDictionary.Add(View.Buffer.FileName,0);
  end;
end;


{ TViewPaintNotifier }

constructor TViewPaintNotifier.Create;
begin

end;

destructor TViewPaintNotifier.Destroy;
begin

  inherited;
end;

procedure TViewPaintNotifier.EditorIdle(const View: IOTAEditView);
begin

end;

procedure TViewPaintNotifier.BeginPaint(const View: IOTAEditView;
  var FullRepaint: Boolean);
begin

end;

procedure TViewPaintNotifier.EndPaint(const View: IOTAEditView);
begin

end;

procedure TViewPaintNotifier.PaintLine(const View: IOTAEditView;
  LineNumber: Integer; const LineText: PAnsiChar; const TextWidth: Word;
  const LineAttributes: TOTAAttributeArray; const Canvas: TCanvas;
  const TextRect, LineRect: TRect; const CellSize: TSize);
begin
  //use the canvas to draw something
  //LineRect is the position of the line on the canvas, draw it here for every line
end;

procedure TViewPaintNotifier.AfterSave;
begin

end;

procedure TViewPaintNotifier.BeforeSave;
begin

end;

procedure TViewPaintNotifier.Destroyed;
begin

end;

procedure TViewPaintNotifier.Modified;
begin

end;

With this notifier i can draw something with the canvas to get the attention of the user.

Upvotes: 2

Related Questions