Reputation: 148
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
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