123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797 |
- {
- TIGCC IDE
- Copyright (C) 2004 Fréderic Bour
- Copyright (C) 2004 Sebastian Reichelt
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- }
- unit CompletionForm;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, MasterUnit,
- Dialogs, StdCtrls, ComCtrls, CodeCompletion, SourceFileUnit, UtilsDos, MemoComponentUnit,
- HtFormatting, Menus, ActnList;
- const
- SymbolFileNotFound = 'Symbol %s is declared in %s, but file can''t be found!';
- AddTemplatesMsg = 'To add templates, go to Preferences->Coding';
- type
- TCompForm = class(TForm)
- CompList: TListBox;
- CompStatus: TStatusBar;
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure FormDeactivate(Sender: TObject);
- procedure CompListDrawItem(Control: TWinControl; Index: Integer;
- Rect: TRect; State: TOwnerDrawState);
- procedure CompListDblClick(Sender: TObject);
- procedure CompListKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure CompListKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure CompListKeyPress(Sender: TObject; var Key: Char);
- private
- procedure SetEditor(const Value: TMemoComponent);
- protected
- { Déclarations protégées }
- C: TCompletionList;
- CompRow: Integer;
- StopKey: Boolean;
- HintWindow: THtHintWindow;
- FSourceFile: TSourceFile;
- FEditor: TMemoComponent;
- procedure CreateParams(var Params: TCreateParams); override;
- function GetFileData(const F: string): string;
- procedure NeedFile(const FileName: string; out CCFData: string);
- protected
- // Be informed when active control change :)
- OldActiveControlChange: TNotifyEvent;
- procedure ActiveControlChange(Sender: TObject);
- public
- { Déclarations publiques }
- // Get & Replace word under caret
- procedure DelimitateWord(const Line: string; var StartPos: Integer; out EndPos: Integer);
- function GetWord(Full, RemoveSpace: Boolean): string;
- procedure SetWord(const Value: string);
- // Show Completion Windows
- property List: TCompletionList read C;
- procedure RebuildList;
- procedure ShowCompletion;
- procedure CloseCompletion;
- procedure ApplyCompletion;
- // Show an hint window about the symbol Symbol, or symbol under caret if ''
- function ShowSymbolInfo(Symbol: string = ''): Boolean;
- procedure CloseSymbolInfo;
- // Find symbol declaration
- procedure FindSymbolDecl;
- protected
- OldChange: TNotifyEvent;
- OldKeyDown: TKeyEvent;
- OldKeyPress: TKeyPressEvent;
- // Redirect Event from Editor
- procedure Editor_Enter(Sender: TMemoComponent);
- procedure Editor_Exit(Sender: TObject);
- procedure Editor_KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
- procedure Editor_KeyPress(Sender: TObject; var Key: Char);
- procedure Editor_Change(Sender: TObject);
- public
- property Editor: TMemoComponent read FEditor write SetEditor;
- end;
- var
- CompForm: TCompForm;
- // TIGCC integration
- function SourceFileFromEditor(M: TMemoComponent): TSourceFile;
- procedure InsertAction(Owner: TComponent; After: TMenuItem; Action: TBasicAction);
- procedure InsertsAction(Owner: TComponent; const Afters: array of TMenuItem; Action: TBasicAction);
- implementation
- uses Types, StrUtils, Math, TmpltForm, MainUnit;
- {$R *.dfm}
- function SourceFileFromEditor(M: TMemoComponent): TSourceFile;
- var
- i: Integer;
- Lst: TSourceFiles;
- Src: TSourceFile;
- begin
- Lst := MainForm.SourceFiles;
- for i := 0 to Lst.Count - 1 do
- begin
- Src := TSourceFile(Lst.Items[i]);
- if Src.Editor = M then
- begin
- Result := Src;
- Exit;
- end;
- end;
- Result := nil;
- end;
- procedure InsertAction(Owner: TComponent; After: TMenuItem; Action: TBasicAction);
- var
- Item: TMenuItem;
- begin
- Item := TMenuItem.Create(Owner);
- Item.Action := Action;
- with After.Parent do
- Insert(IndexOf(After) + 1, Item);
- end;
- procedure InsertsAction(Owner: TComponent; const Afters: array of TMenuItem; Action: TBasicAction);
- var
- i: Integer;
- begin
- for i := Low(Afters) to High(Afters) do
- InsertAction(Owner, Afters[i], Action);
- end;
- // GUI Methods
- procedure TCompForm.FormCreate(Sender: TObject);
- begin
- C := TCompletionList.Create;
- C.OnNeedFile := NeedFile;
- HintWindow := THtHintWindow.Create(Self);
- OldActiveControlChange := Screen.OnActiveControlChange;
- Screen.OnActiveControlChange := ActiveControlChange;
- end;
- procedure TCompForm.FormDestroy(Sender: TObject);
- begin
- if Assigned(Screen.OnActiveControlChange) then
- Screen.OnActiveControlChange := OldActiveControlChange;
- HintWindow.Free;
- C.Free;
- end;
- procedure TCompForm.FormDeactivate(Sender: TObject);
- var
- M: TMemoComponent;
- begin
- M := Editor;
- if (M = nil) or (not M.Focused) then
- CloseCompletion;
- end;
- procedure TCompForm.CreateParams(var Params: TCreateParams);
- begin
- inherited;
- Params.Style := WS_POPUP or WS_SYSMENU or WS_THICKFRAME;
- end;
- procedure TCompForm.CompListDrawItem(Control: TWinControl; Index: Integer;
- Rect: TRect; State: TOwnerDrawState);
- const
- MinWidth = 62;
- var
- C: TCompletionItem;
- S: string;
- Cnv: TCanvas;
- Selected: Boolean;
- W: Integer;
- begin
- if (Index >= 0) and (Index < List.Count) then
- begin
- Cnv := CompList.Canvas;
- Selected := odSelected in State;
- C := List.Completion[Index];
- S := List[Index];
- if Assigned(C) then
- begin
- Cnv.Font.Style := [];
- DrawHtText(C.Left, Rect, Cnv, W, Selected);
- Inc(Rect.Left, W);
- end;
- if Rect.Left < MinWidth then
- Rect.Left := MinWidth;
- Inc(Rect.Left, 2);
- Cnv.Font.Style := [fsBold];
- DrawHtText(S, Rect, Cnv, W, Selected);
- Inc(Rect.Left, W + 2);
- if Assigned(C) then
- begin
- Cnv.Font.Style := [];
- DrawHtText(C.Right, Rect, CompList.Canvas, Rect.Left, Selected);
- if Selected then
- CompStatus.SimpleText := C.Description;
- end;
- end;
- end;
- procedure TCompForm.CompListDblClick(Sender: TObject);
- begin
- ApplyCompletion;
- end;
- // Completion Tools
- procedure TCompForm.RebuildList;
- var
- S: TSourceFile;
- begin
- List.Clear;
- S := SourceFileFromEditor(Editor);
- if Assigned(S) then
- begin
- if S is TCSourceFile then
- List.AddCompletion(MakeCCF_C(ExtractFileName(S.FileName), TCSourceFile(S)))
- else if S is THeaderSourceFile then
- List.AddCompletion(MakeCCF_H(ExtractFileName(S.FileName), THeaderSourceFile(S).SourceEditor.Lines));
- end;
- CompList.Count := List.Count;
- end;
- procedure TCompForm.ShowCompletion;
- var
- M: TMemoComponent;
- P: TPoint;
- i: Integer;
- begin
- M := Editor;
- CloseSymbolInfo;
- if Assigned(M) then
- begin
- RebuildList;
- CompRow := M.Selection.StartRowCol.Row;
- P := M.Selection.StartPoint;
- P := M.ClientToScreen(P);
- Left := P.X + 4;
- Top := P.Y + 20;
- List.Find(GetWord(True, False), i);
- CompList.ItemIndex := i;
- LockWindowUpdate(M.ParentWindow);
- Show;
- M.SetFocus;
- LockWindowUpdate(0);
- end;
- end;
- procedure TCompForm.CloseCompletion;
- begin
- Hide;
- end;
- function TCompForm.ShowSymbolInfo(Symbol: string = ''): Boolean;
- function Similarity(const A, B: string): Integer;
- var
- i, l: Integer;
- begin
- l := Min(Length(A), Length(B));
- i := 1;
- while (i <= l) and (UpCase(A[i]) = UpCase(B[i])) do
- Inc(i);
- Result := Abs(i - l);
- end;
- function Similar(const A, B: string): Boolean;
- var
- l: Integer;
- begin
- l := Min(Length(A), Length(B));
- Result := Similarity(A, B) < (l shr 1);
- end;
- var
- M: TMemoComponent;
- P: TPoint;
- R: TRect;
- i: Integer;
- C: TCompletionItem;
- T: string;
- begin
- CloseCompletion;
- Result := False;
- if Symbol = '' then
- Symbol := GetWord(False, True);
- if Symbol = '' then
- begin
- CloseSymbolInfo;
- Exit;
- end;
- M := Editor;
- if Assigned(M) then
- begin
- RebuildList;
- // Find Symbol
- if List.Find(Symbol, i) then
- T := ''
- else if (i >= 0) and (i < List.Count) then
- begin
- if i = 0 then
- begin
- if Similar(Symbol, List[i]) then
- T := List[i] + ' ?'#13#10
- else
- Exit;
- end
- else
- begin
- if Similarity(Symbol, List[i - 1]) > Similarity(Symbol, List[i]) then
- Dec(i);
- if Similar(Symbol, List[i]) then
- T := List[i] + ' ?'#13#10
- else
- Exit;
- end;
- end
- else
- Exit;
- // Show Symbol info
- C := List.Completion[i];
- if Assigned(C) then
- begin
- T := T + C.Left + ' ' + C.Right + #13#10 + C.Description;
- // Calc hint window position
- CompRow := M.Selection.StartRowCol.Row;
- P := M.ClientToScreen(M.Selection.StartPoint);
- R := HintWindow.CalcHintRect(Screen.Width, T, nil);
- Inc(R.Left, P.X + 4);
- Inc(R.Right, P.X + 4);
- Inc(R.Top, P.Y + 20);
- Inc(R.Bottom, P.Y + 20);
- LockWindowUpdate(M.ParentWindow);
- HintWindow.ActivateHint(R, T);
- Result := True;
- M.SetFocus;
- // Bug with TSourceFileForm ??!!
- if Assigned(M.Parent) and (M.Parent is TForm) then
- M.Parent.BringToFront;
- LockWindowUpdate(0);
- end;
- end;
- end;
- procedure TCompForm.CloseSymbolInfo;
- begin
- if IsWindowVisible(HintWindow.Handle) then
- ShowWindow(HintWindow.Handle, SW_HIDE);
- end;
- procedure TCompForm.ApplyCompletion;
- var
- i: Integer;
- begin
- i := CompList.ItemIndex;
- if (i >= 0) and (i < List.Count) then
- begin
- SetWord(List[i]);
- CloseCompletion;
- end;
- end;
- // Find Files
- function TCompForm.GetFileData(const F: string): string;
- var
- S: TSourceFile;
- Folder: string;
- begin
- S := MainForm.SourceFiles.FindFileNameOnly(F);
- Folder := WithBackslash(TIGCCFolder);
- if Assigned(S) and (S is TSourceTextSourceFile) then
- Result := TSourceTextSourceFile(S).Content
- else if FileExists(ExpandFileName(F)) then
- Result := FileToString(ExpandFileName(F))
- else if FileExists(Folder + CIncludeLocation + F) then
- Result := FileToString(Folder + CIncludeLocation + F)
- else if FileExists(Folder + ASMIncludeLocation + F) then
- Result := FileToString(Folder + ASMIncludeLocation + F)
- else
- Result := '';
- end;
- procedure TCompForm.NeedFile(const FileName: string; out CCFData: string);
- var
- CCFName: string;
- Lst: TStringList;
- begin
- // Search CCF file
- CCFName := WithBackslash(TIGCCFolder) + CompletionLocation + ChangeFileExt(FileName, '.ccf');
- if FileExists(CCFName) then
- CCFData := FileToString(CCFName)
- else
- begin
- // No CCF ? Generate info from header...
- if UpperCase(ExtractFileExt(FileName)) = '.H' then
- begin
- Lst := TStringList.Create;
- Lst.Text := GetFileData(FileName);
- if Lst.Count > 0 then
- CCFData := MakeCCF_H(FileName, Lst);
- Lst.Free;
- end;
- end;
- end;
- // Word manipulations
- procedure TCompForm.DelimitateWord(const Line: string; var StartPos: Integer; out EndPos: Integer);
- const
- ValidChars = ['A'..'Z', 'a'..'z', '0'..'9', '_', '$', '#'];
- var
- i, j, l: Integer;
- begin
- i := StartPos - 1;
- j := StartPos - 1;
- l := Length(Line);
- // Find start pos
- while (i > 0) and (i <= l) and (Line[i] in ValidChars) do
- Dec(i);
- // Find end pos
- while (j > 0) and (j <= l) and (Line[j] in ValidChars) do
- Inc(j);
- if j = StartPos - 1 then
- begin
- j := StartPos;
- while (j > 0) and (j <= l) and (Line[j] in ValidChars) do
- Inc(j);
- end;
- Dec(j);
- Inc(i);
- StartPos := i;
- EndPos := j;
- end;
- function TCompForm.GetWord(Full, RemoveSpace: Boolean): string;
- var
- M: TMemoComponent;
- S: string;
- T: TTextCell;
- StPos, EndPos, l: Integer;
- begin
- M := Editor;
- Result := '';
- if Assigned(M) then
- begin
- T := M.Selection.StartRowCol;
- if (T.Row > 0) and (T.Row <= M.LineCount) then
- begin
- S := M.Lines[T.Row - 1];
- StPos := T.Col;
- l := Length(S);
- if RemoveSpace and (StPos > 1) and (StPos <= l) then
- begin
- if S[StPos - 1] = ' ' then
- Dec(StPos);
- while (StPos > 1) and (S[StPos] in ['(', ' ']) do
- Dec(StPos);
- end;
- DelimitateWord(S, StPos, EndPos);
- if Full then
- Result := Trim(Copy(S, StPos, EndPos - StPos + 1))
- else
- Result := Trim(Copy(S, StPos, T.Col - StPos));
- end;
- end;
- end;
- procedure TCompForm.SetWord(const Value: string);
- var
- M: TMemoComponent;
- begin
- M := Editor;
- if Assigned(M) then
- begin
- with M.Selection do
- begin
- SelectWord;
- Text := Value;
- end;
- end;
- end;
- // Editor Events
- procedure TCompForm.Editor_KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
- procedure Select(Direction, Page: Boolean);
- var
- HowMany, i, c: Integer;
- begin
- i := CompList.ItemIndex;
- c := List.Count;
- if Page then
- HowMany := CompList.Height div CompList.ItemHeight
- else
- HowMany := 1;
- if Direction then
- Inc(i, HowMany)
- else
- Dec(i, HowMany);
- if i <= 0 then
- CompList.ItemIndex := 0
- else if i >= c then
- CompList.ItemIndex := c - 1
- else
- CompList.ItemIndex := i;
- end;
- var
- NewKey: Word;
- begin
- if Assigned(OldKeyDown) then
- OldKeyDown(Sender, Key, Shift);
- if Visible then
- begin
- NewKey := 0;
- case Key of
- VK_ESCAPE: Close;
- VK_RETURN:
- begin
- ApplyCompletion;
- StopKey := True;
- end;
- VK_UP: Select(False, False);
- VK_DOWN: Select(True, False);
- VK_PRIOR: Select(False, True);
- VK_NEXT: Select(True, True);
- VK_HOME: CompList.ItemIndex := 0;
- VK_END: CompList.ItemIndex := List.Count - 1;
- VK_LEFT, VK_RIGHT:
- begin
- Editor_Change(Sender);
- NewKey := Key;
- end;
- else
- NewKey := Key;
- end;
- Key := NewKey;
- end
- else if (ssCtrl in Shift) and (Key = VK_SPACE) then
- begin
- Key := 0;
- StopKey := True;
- ShowCompletion;
- end
- else if (ssCtrl in Shift) and (Key = Ord('J')) then
- begin
- Key := 0;
- StopKey := True;
- if TemplateForm.Templates.Count > 0 then
- TemplateForm.Show
- else
- ShowMessage(AddTemplatesMsg);
- end
- else if (Key in [VK_BACK, VK_ESCAPE]) then // or not (Key in [Ord('A')..Ord('Z'), Ord('0')..Ord('9')
- CloseSymbolInfo;
- end;
- procedure TCompForm.Editor_KeyPress(Sender: TObject; var Key: Char);
- begin
- if Assigned(OldKeyPress) then
- OldKeyPress(Sender, Key);
- if StopKey then
- begin
- Key := #0;
- StopKey := False;
- end
- else
- begin
- case Key of
- '(': if Visible or not IsWindowVisible(HintWindow.Handle) then ShowSymbolInfo;
- ')': CloseSymbolInfo;
- end;
- end;
- end;
- procedure TCompForm.Editor_Change(Sender: TObject);
- var
- i: Integer;
- M: TMemoComponent;
- begin
- if Assigned(OldChange) then
- OldChange(Sender);
- M := Editor;
- if Visible then
- begin
- if Assigned(M) then
- begin
- if CompRow <> M.Selection.StartRowCol.Row then
- CloseCompletion
- else
- begin
- List.Find(GetWord(False, False), i);
- CompList.ItemIndex := i;
- end;
- end
- else
- CloseCompletion;
- end
- else if Assigned(M) and (CompRow <> M.Selection.StartRowCol.Row) then
- CloseSymbolInfo;
- end;
- procedure TCompForm.Editor_Enter(Sender: TMemoComponent);
- begin
- if Assigned(Sender) then
- begin
- FEditor := Sender;
- CloseCompletion;
- CloseSymbolInfo;
- OldKeyDown := Editor.OnKeyDown;
- OldKeyPress := Editor.OnKeyPress;
- OldChange := Editor.OnChange;
- Editor.OnKeyDown := Editor_KeyDown;
- Editor.OnKeyPress := Editor_KeyPress;
- Editor.OnChange := Editor_Change;
- Editor.OnSelectionChange := Editor_Change;
- end
- else
- begin
- FEditor := nil;
- OldKeyDown := nil;
- OldKeyPress := nil;
- OldChange := nil;
- end;
- end;
- procedure TCompForm.Editor_Exit(Sender: TObject);
- begin
- if Assigned(Editor) then
- begin
- Editor.OnKeyDown := OldKeyDown;
- Editor.OnKeyPress := OldKeyPress;
- Editor.OnChange := OldChange;
- Editor.OnSelectionChange := OldChange;
- end;
- CloseSymbolInfo;
- if not Focused then
- begin
- FEditor := nil;
- CloseCompletion;
- end;
- end;
- procedure TCompForm.CompListKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- var
- M: TMemoComponent;
- begin
- M := Editor;
- if Assigned(M) then
- begin
- M.HandleKeyDown(Key, Shift);
- M.SetFocus;
- Key := 0;
- end
- else
- CloseCompletion;
- end;
- procedure TCompForm.CompListKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- var
- M: TMemoComponent;
- begin
- M := Editor;
- if Assigned(M) then
- begin
- M.HandleKeyUp(Key, Shift);
- M.SetFocus;
- Key := 0;
- end
- else
- CloseCompletion;
- end;
- procedure TCompForm.CompListKeyPress(Sender: TObject; var Key: Char);
- var
- M: TMemoComponent;
- begin
- M := Editor;
- if Assigned(M) then
- begin
- M.HandleKeyPress(Key);
- M.SetFocus;
- end;
- end;
- procedure TCompForm.FindSymbolDecl;
- var
- i, p: Integer;
- Symbol, S: string;
- C: TCompletionItem;
- SourceFile: TSourceFile;
- begin
- RebuildList;
- Symbol := GetWord(True, True);
- if (Symbol <> '') and List.Find(Symbol, i) then
- begin
- C := List.Completion[i];
- if Assigned(C) and (C.SourceFileName <> '') then
- begin
- SourceFile := MainForm.SourceFiles.FindFileNameOnly(C.SourceFileName);
- if SourceFile = nil then
- begin
- if FileExists(ExpandFileName(C.SourceFileName)) then
- SourceFile := MainForm.AddSourceFile(ExpandFileName(C.SourceFileName), True)
- else if FileExists(WithBackslash(TIGCCFolder) + CIncludeLocation + C.SourceFileName) then
- SourceFile := MainForm.AddSourceFile(WithBackslash(TIGCCFolder) + CIncludeLocation + C.SourceFileName, True)
- else if FileExists(WithBackslash(TIGCCFolder) + ASMIncludeLocation + C.SourceFileName) then
- SourceFile := MainForm.AddSourceFile(WithBackslash(TIGCCFolder) + ASMIncludeLocation + C.SourceFileName, True)
- end;
- if Assigned(SourceFile) and (SourceFile is TTextSourceFile) then
- with TTextSourceFile(SourceFile).TextEditor do
- begin
- if (C.Line < Cardinal(Lines.Count)) then
- begin
- S := Lines[C.Line];
- p := Pos(Symbol, S);
- if p = 0 then
- p := 1;
- end
- else
- p := 1;
- Selection.StartRowCol := TextCell(C.Line + 1, p);
- Selection.RLength := 0;
- Selection.ScrollInView(4);
- end
- else
- ShowMessageFmt(SymbolFileNotFound, [Symbol, C.SourceFileName]);
- end;
- end;
- end;
- procedure TCompForm.ActiveControlChange(Sender: TObject);
- var
- W: TWinControl;
- begin
- W := Screen.ActiveControl;
- if (W = Editor) or (W = Self) or (W = CompList) or (W = TemplateForm) or (W = TemplateForm.TmpltList) then
- Exit;
- if Assigned(W) and (W is TMemoComponent) then
- Editor := TMemoComponent(W)
- else
- Editor := nil;
- if Assigned(OldActiveControlChange) then
- OldActiveControlChange(Sender);
- end;
- procedure TCompForm.SetEditor(const Value: TMemoComponent);
- begin
- if Value <> FEditor then
- begin
- Editor_Exit(Self);
- Editor_Enter(Value);
- FEditor := Value;
- end;
- end;
- end.
|