Thema: Delphi AutoComplete mit SynEdit

Einzelnen Beitrag anzeigen

schöni

Registriert seit: 23. Jan 2005
Ort: Dresden
445 Beiträge
 
Delphi 7 Personal
 
#7

Re: AutoComplete mit SynEdit

  Alt 26. Jan 2010, 14:48
Hallo!

Kann mir wirklich niemend helfen bei der Codevervollständigung des SynEdit Projektes?

Hier ist das Demo Beispiel. Das funktioniert.

Warum aber funktioniert dann mein Lösung nicht? Die ist im Quellcode mit der Methode
Assign

Delphi-Quellcode:
unit frmMain1;

{$I SynEdit.inc}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  SynEditHighlighter, SynHighlighterPas, SynEdit, SynEditKeyCmds,
  SynEditAutoComplete, Menus;

type
  TForm1 = class(TForm)
    SynEdit1: TSynEdit;
    SynPasSyn1: TSynPasSyn;
    MainMenu1: TMainMenu;
    miNewForm: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure miNewFormClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    fAutoComplete: TSynAutoComplete;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  if Application.MainForm = nil then begin
    fAutoComplete := TSynAutoComplete.Create(Self);
    fAutoComplete.Editor := SynEdit1;
    fAutoComplete.AutoCompleteList.LoadFromFile('Delphi32.dci');
  end else
    Form1.fAutoComplete.AddEditor(SynEdit1);
  SynEdit1.AddKey(ecAutoCompletion, word('J'), [ssCtrl], 0, []);
end;

procedure TForm1.miNewFormClick(Sender: TObject);
begin
  with TForm1.Create(Application) do
    Show;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

end.

//Schöni-Lösung:
//Diese wird bei jedem Öffnen eines neuen Editors aufgerufen
procedure TfpasIDE.AssignCodeCompletion(AEditor: TSynEdit);
begin
  if Assigned(AutoCompleter) then
  begin
    if AutoCompleter.AutoCompleteList.Count = 0 then AutoCompleter.LoadFromFile('fp.dci');
    //Damit die Datei mit den Codevervollständigungen nur einmal beim ersten Aufruf der
   //Methode gelesen und später nur noch verwendet wird.
    AutoCompleter.Editor := AEditor;
    //AddEditor wird intern aufgerufen und Editor ist der aktuelle Editor
    if Assigned(AutoCompleter.Editor) then
    AutoCompleter.Editor.AddKey(ecAutoCompletion, word('J'), [ssCtrl], 0, []);
    //Der Editor wird nicht zugewiesen, was ich daran sehe, das ich ohne die "If Assigned() Abfrage
    //eine Exception erhalte und zwar eine EAccessViolation. Der Debugger springt dann in AddKey von
    //TCustomSynEdit.
    //Warum aber wird der Editor nicht zugewiesen?
  end;
end;

//Mein AutoCompleter sieht so aus:
unit CompleteManager;

interface

uses
  Sysutils, Classes, SynEditAutoComplete, SynCompletionProposal, SynEdit;

type
//Der TAutoCompleteManager ist entstanden, weil ich mir auch die Demos von
//TSynCompletionProposal angeguckt habe und dort die Codes und die Vervollständigungen
//in 2 verschidenen Listen verwaltet werden und ich eine Vereinfachung des resultierenden
//Codes haben will.

  TAutoCompleteManager = class(SynCompletionProposal.TSynCompletionProposal)
  private
  public
   //Hier kann ich die AutoCompleteList aus dem AutoCompleter zuweisen
    procedure Assign(AList: TStrings);
    //Hier weise ich die beiden gtrennten Listen zu, wie das im Demobeispiel
    //vorgeführt wird, allerdings ohne diese Klasse. Dort passiert das einfach
    //im Quellcode unter Nutzung der Originalklasse TSynCompletionProposal
    procedure AssignList(AList: TStrings; Separator: String; AComments: TStrings);
  end;

//Hier ist nun eine verbesserte AutoComplete Klasse
  TAutoCompleter = class(SynEditAutoComplete.TSynAutoComplete)
  private
    FCompleteManager: TAutoCompleteManager;
  public
    procedure Assign(AList: TStrings);
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
   procedure LoadFromFile(Filename: String);
   
   //Falls ich in der Finalversion die Funktionalitäten beider Kompnenten
   //zusammenfassen muss, um ein optimales Ergebnis zu erhalten.
    property CompleteManager: TAutoCompleteManager read FCompleteManager;
  end;

var
  AutoCompleter: TAutoCompleter;
  AutoCompleteManager: TAutoCompleteManager;

implementation

type
  TManagerContainer = class(SynCompletionProposal.TSynAutoComplete)
  private
  public
  end;
//Diese Klasse TSynAutoComplete ist namensgleich mit TSynAutoComplete in
//TSynEditAutoComplete. Deshalb habe ich auch die Unitnamen vor den Namen
//der Vorfahrklasse gesetzt. Die namensgleiche Klasse in der Unit mit dem
//Namen TSynCompletionProposal ist jedoch anders inmlementiert, als die
//gleichnamige Klasse in der Unit SynEditAutoComplete, die ich für die
//Codevervollständigung verwende. Falls die TSynAutoComplete-Klasse des
//hiesigen Imlementationsteils zur Unterstützung des AutoComplete-Managers,
//abgeleitet von TSynCompltionProposal, benötigt wird, ist sie hier als
//Typdefinition vorhanden. Sollte sie hier nicht gebraucht werden in der
//Finalversion dieser Unit, werde ich sie später entfernen.



{ TAutoCompleteManager }

procedure TAutoCompleteManager.Assign(AList: TStrings);
begin
  ItemList.Assign(AList);
end;

procedure TAutoCompleteManager.AssignList(AList: TStrings; Separator: String; AComments: TStrings);
var Counter: Integer;
begin
  InsertList.Assign(AList);
  for Counter := 0 to AComments.Count - 1 do
       ItemList.Add(AList[Counter]+Separator+AComments[Counter]);
end;


{ TAutoComplete }

procedure TAutoCompleter.Assign(AList: TStrings);
begin
  AutoCompleteList.Assign(AList);
end;

constructor TAutoCompleter.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCompleteManager := TAutoCompleteManager.Create(AOwner);
  AutoCompleteManager := FCompleteManager;
  AutoCompleter := self;
end;

destructor TAutoCompleter.Destroy;
begin
  FCompleteManager.Free;
  inherited Destroy;
end;

procedure TAutoCompleter.LoadFromFile(FileName: String);
begin
  AutoCompleteList.LoadFromFile(FileName);
end;

end.
Warum wird mein Editor nicht korrekt zugewiesen. Im übergeordneten Programm habe ich bereits meinen zuzuweisenden Editor auf NIL getestet. Mein zuzuweisender Editor ist gültig, das heißt er ist nicht NIL und ich erhalten den Quelltext des Editors, für den ich die Codevervollständigung realisieren will. Der AutoCompleter ist auch zugewiesen. Nur der Editor lässt sich aus mir rätselhaftem Grund nicht an die Editoreigenschaft des AutoCompleters zuweisen.

Wer kann mir hier helfen?
Damit der Topf nicht explodiert, lässt man es ab und zu mal zischen.
  Mit Zitat antworten Zitat