unit HighLightfrm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SynEdit, SynEditHighlighter, SynHighlighterPas, StdCtrls,
  SynHighlighterGeneral, SynHighlighterTclTk, SynHighlighterCache,
  SynHighlighterSQL;

type

  PGlobalDLLData = ^TGlobalDLLData;
  TGlobalDLLData = record
    TheHighLighter: TSynSQLSyn;
  end;

  TfrmHighLighter = class(TForm)
    btnClose: TButton;
    SynEdit1: TSynEdit;
    SynSQLSyn1: TSynSQLSyn;
    procedure btnCloseClick(Sender: TObject);
  private
    FDefaultHightLighter: string;
    { Private declarations }
  public
    property DefaultHightLighter: string read FDefaultHightLighter;
    { Public declarations }
  end;

var
  frmHighLighter: TfrmHighLighter;

  procedure OpenSharedData;
  procedure CloseSharedData;
  procedure GetDLLData(var AGlobalData: PGlobalDLLData); export; StdCall;
  procedure Initial(AHighLighters: String); export; stdcall;
  function GetHighLighters(ADefault: Boolean = False): string; export; stdcall;
  function GetExample: string; export; stdcall;

const
  cMMFileName: PChar = 'SharedMapData';

implementation

{$R *.dfm}

var
  GlobalData : PGlobalDLLData;
  MapHandle  : THandle;
  
procedure Initial(AHighLighters: String);
var
  I: Integer;
  sHighLigher: string;
  lstHighLights: TStringList;
  procedure ConfigHighLight(AHighLighter: string; Attributes: TSynHighlighterAttributes);
  var
    lstHighLight: TStringList;
  begin
    lstHighLight := TStringList.Create;
    lstHighLight.CommaText := AHighLighter;
    if lstHighLight.Count > 6 then
    begin
      Attributes.Foreground := StrToIntDef(lstHighLight.Strings[1], 0);
      Attributes.Background := StrToIntDef(lstHighLight.Strings[2], 0);
      Attributes.Style := [];
      if SameText(lstHighLight.Strings[3], '1')  then
      begin
        Attributes.Style := Attributes.Style + [fsBold];
      end;
      if SameText(lstHighLight.Strings[4], '1')  then
      begin
        Attributes.Style := Attributes.Style + [fsItalic];
      end;
      if SameText(lstHighLight.Strings[5], '1')  then
      begin
        Attributes.Style := Attributes.Style + [fsUnderline];
      end;
      if SameText(lstHighLight.Strings[6], '1')  then
      begin
        Attributes.Style := Attributes.Style + [fsStrikeOut];
      end;
    end;
    lstHighLight.Free;
  end;
begin
  if not SameText(AHighLighters, '') then
  begin
    lstHighLights := TStringList.Create;
    lstHighLights.Delimiter := ';';
    lstHighLights.DelimitedText := AHighLighters;
    for I := 1 to lstHighLights.Count - 1 do
    begin
      sHighLigher := lstHighLights.Strings[I];
      Case I of
        1: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.CommentAttri);
        2: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.ConditionalCommentAttri);
        3: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.DataTypeAttri);
        4: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.DefaultPackageAttri);
        5: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.DelimitedIdentifierAttri);
        6: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.ExceptionAttri);
        7: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.FunctionAttri);
        8: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.IdentifierAttri);
        9: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.KeyAttri);
        10: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.NumberAttri);
        11: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.PLSQLAttri);
        12: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.SpaceAttri);
        13: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.SQLPlusAttri);
        14: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.StringAttri);
        15: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.SymbolAttri);
        16: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.TableNameAttri);
        17: ConfigHighLight(sHighLigher, frmHighLighter.SynSQLSyn1.VariableAttri);
      end;
    end;
    lstHighLights.Free;
  end;
end;

function GetExample: string;
begin
  Result := frmHighLighter.SynEdit1.Lines.Text;
end;  

function GetHighLighters(ADefault: Boolean = False): string;
const
  arrStyle: array[Boolean] of string = ('0', '1');
var
  lstHighLights: TStringList;
  function GetHighLight(ATitle: string; Attributes: TSynHighlighterAttributes): string;
  var
    lstHighLight: TStringList;
  begin
    lstHighLight := TStringList.Create;
    lstHighLight.Add(ATitle);
    lstHighLight.Add(IntToStr(Attributes.Foreground));
    lstHighLight.Add(IntToStr(Attributes.Background));
    lstHighLight.Add(arrStyle[(Attributes.Style * [fsBold]) = [fsBold]]);
    lstHighLight.Add(arrStyle[(Attributes.Style * [fsItalic]) = [fsItalic]]);
    lstHighLight.Add(arrStyle[(Attributes.Style * [fsUnderline]) = [fsUnderline]]);
    lstHighLight.Add(arrStyle[(Attributes.Style * [fsStrikeOut]) = [fsStrikeOut]]);
    Result := lstHighLight.CommaText;
    lstHighLight.Free;
  end;
begin

  if ADefault then
  begin
    Result := frmHighLighter.DefaultHightLighter;
  end
  else begin
    lstHighLights := TStringList.Create;
    lstHighLights.Add('背景色,' + IntToStr(frmHighLighter.SynEdit1.ActiveLine.Background) + ','
      + IntToStr(frmHighLighter.SynEdit1.Color) + ',' + '0,0,0,0');
    lstHighLights.Add(GetHighLight('注释', frmHighLighter.SynSQLSyn1.CommentAttri));
    lstHighLights.Add(GetHighLight('条件注释', frmHighLighter.SynSQLSyn1.ConditionalCommentAttri));
    lstHighLights.Add(GetHighLight('数据类型', frmHighLighter.SynSQLSyn1.DataTypeAttri));
    lstHighLights.Add(GetHighLight('缺省包', frmHighLighter.SynSQLSyn1.DefaultPackageAttri));
    lstHighLights.Add(GetHighLight('分隔标识符', frmHighLighter.SynSQLSyn1.DelimitedIdentifierAttri));
    lstHighLights.Add(GetHighLight('异常', frmHighLighter.SynSQLSyn1.ExceptionAttri));
    lstHighLights.Add(GetHighLight('函数', frmHighLighter.SynSQLSyn1.FunctionAttri));
    lstHighLights.Add(GetHighLight('标识符', frmHighLighter.SynSQLSyn1.IdentifierAttri));
    lstHighLights.Add(GetHighLight('关键字', frmHighLighter.SynSQLSyn1.KeyAttri));
    lstHighLights.Add(GetHighLight('数字', frmHighLighter.SynSQLSyn1.NumberAttri));
    lstHighLights.Add(GetHighLight('PLSQL', frmHighLighter.SynSQLSyn1.PLSQLAttri));

    lstHighLights.Add(GetHighLight('Space', frmHighLighter.SynSQLSyn1.SpaceAttri));
    lstHighLights.Add(GetHighLight('SQLPlus', frmHighLighter.SynSQLSyn1.SQLPlusAttri));
    lstHighLights.Add(GetHighLight('字符串', frmHighLighter.SynSQLSyn1.StringAttri));
    lstHighLights.Add(GetHighLight('符号', frmHighLighter.SynSQLSyn1.SymbolAttri));
    lstHighLights.Add(GetHighLight('表名', frmHighLighter.SynSQLSyn1.TableNameAttri));
    lstHighLights.Add(GetHighLight('变量', frmHighLighter.SynSQLSyn1.VariableAttri));

    lstHighLights.Delimiter := ';';
    Result := lstHighLights.DelimitedText;
    lstHighLights.Free;
  end;
end;

procedure GetDLLData(var AGlobalData: PGlobalDLLData); StdCall;
begin
  AGlobalData := GlobalData;
end;

procedure OpenSharedData;
var
   Size: Integer;
begin
  Size := SizeOf(TGlobalDLLData);

  MapHandle := CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0, Size, cMMFileName);

  if MapHandle > 0 then
  begin
    GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);
    GlobalData^.TheHighLighter := frmHighLighter.SynSQLSyn1;
    if GlobalData = nil then
    begin
      CloseHandle(MapHandle);
    end;
  end;
end;

procedure CloseSharedData;
begin
  UnmapViewOfFile(GlobalData);
  CloseHandle(MapHandle);
end;


procedure TfrmHighLighter.btnCloseClick(Sender: TObject);
begin
  Close;
end;

initialization
  frmHighLighter := TfrmHighLighter.Create(Application);
  frmHighLighter.FDefaultHightLighter := GetHighLighters;

finalization
  frmHighLighter.Free;

end.
 
