2014-05-06 12 views
5

Piszę wtyczkę Delphi i potrzebuję wykryć, gdy okno Moduły (Widok - Debuguj okna - Moduły) jest otwarte (dołączone do edytora IDE). Używam IOTAEditorNotifier, aby otrzymywać powiadomienia, gdy nowe okno edytora jest otwarte, ale działa tylko dla plików źródłowych.Jak mogę wykryć, kiedy okno modułów jest otwarte w IDE Delphi?

Jest to kod używany do odbierania powiadomień z edytora IDE.

uses 
    Classes, SysUtils, ToolsAPI; 

type 
    TSourceEditorNotifier = class(TNotifierObject, IOTANotifier, IOTAEditorNotifier) 
    private 
    FEditor: IOTASourceEditor; 
    FIndex: Integer; 
    { IOTANotifier } 
    procedure Destroyed; 
    { IOTAEditorNotifier } 
    procedure ViewActivated(const View: IOTAEditView); 
    procedure ViewNotification(const View: IOTAEditView; Operation: TOperation); 
    public 
    constructor Create(AEditor: IOTASourceEditor); 
    destructor Destroy; override; 
    end; 

    TIDENotifier = class(TNotifierObject, IOTANotifier, IOTAIDENotifier) 
    private 
    { IOTAIDENotifier } 
    procedure FileNotification(NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); 
    procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); overload; 
    procedure AfterCompile(Succeeded: Boolean); overload; 
    end; 

procedure Register; 

implementation 

uses 
    Dialogs, 
    Windows, 
    Forms; 

var 
    SourceEditorNotifiers: TList = nil; 
    IDENotifierIndex: Integer = -1; 

procedure ClearSourceEditorNotifiers; 
var 
    I: Integer; 
begin 
    if Assigned(SourceEditorNotifiers) then 
    for I := SourceEditorNotifiers.Count - 1 downto 0 do 
     TSourceEditorNotifier(SourceEditorNotifiers[I]).Destroyed; 
end; 

procedure InstallSourceEditorNotifiers(Module: IOTAModule); 
var 
    I: Integer; 
    SourceEditor: IOTASourceEditor; 
begin 
    for I := 0 to Module.ModuleFileCount - 1 do 
    if Supports(Module.ModuleFileEditors[I], IOTAEditor, SourceEditor) then 
    begin 
     SourceEditorNotifiers.Add(TSourceEditorNotifier.Create(SourceEditor)); 
     SourceEditor := nil; 
    end; 
end; 

procedure Register; 
var 
    Services: IOTAServices; 
    ModuleServices: IOTAModuleServices; 
    EditorServices: IOTAEditorServices; 
    EditorTopView: IOTAEditView; 
    I, J: Integer; 
begin 
    SourceEditorNotifiers := TList.Create; 

    // install IDE notifier so that we can install editor notifiers for any newly opened module 
    Services := BorlandIDEServices as IOTAServices; 
    IDENotifierIndex := Services.AddNotifier(TIDENotifier.Create); 

    // install editor notifiers for all currently open modules 
    ModuleServices := BorlandIDEServices as IOTAModuleServices; 
    if ModuleServices.ModuleCount = 0 then 
    Exit; 
    for I := 0 to ModuleServices.ModuleCount - 1 do 
    InstallSourceEditorNotifiers(ModuleServices.Modules[I]); 

    // hook currently active module 
    EditorServices := BorlandIDEServices as IOTAEditorServices; 
    if not Assigned(EditorServices) then 
    Exit; 

    EditorTopView := EditorServices.TopView; 
    if not Assigned(EditorTopView) then 
    Exit; 

    for I := 0 to SourceEditorNotifiers.Count - 1 do 
    with TSourceEditorNotifier(SourceEditorNotifiers[I]) do 
     for J := 0 to FEditor.EditViewCount - 1 do 
     if FEditor.EditViews[J] = EditorTopView then 
     begin 
      ViewActivated(EditorTopView); 
      Exit; 
     end; 
end; 


procedure RemoveIDENotifier; 
var 
    Services: IOTAServices; 
begin 
    Services := BorlandIDEServices as IOTAServices; 
    if Assigned(Services) then 
    Services.RemoveNotifier(IDENotifierIndex); 
end; 

procedure TSourceEditorNotifier.Destroyed; 
begin 
    FEditor.RemoveNotifier(FIndex); 
end; 

procedure TSourceEditorNotifier.ViewActivated(const View: IOTAEditView); 
begin 
    // Do nothing 
end; 

procedure TSourceEditorNotifier.ViewNotification(const View: IOTAEditView; Operation: TOperation); 
begin 
    if Operation=opInsert then 
    ShowMessage('ViewNotification opInsert'); 
end; 

constructor TSourceEditorNotifier.Create(AEditor: IOTASourceEditor); 
begin 
    inherited Create; 
    FEditor := AEditor; 
    FIndex := FEditor.AddNotifier(Self); 
end; 

destructor TSourceEditorNotifier.Destroy; 
begin 
    SourceEditorNotifiers.Remove(Self); 
    FEditor := nil; 
    inherited Destroy; 
end; 

procedure TIDENotifier.AfterCompile(Succeeded: Boolean); 
begin 
    // do nothing 
end; 

procedure TIDENotifier.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); 
begin 
    // do nothing 
end; 

procedure TIDENotifier.FileNotification(NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); 
var 
    ModuleServices: IOTAModuleServices; 
    Module: IOTAModule; 
begin 
    case NotifyCode of 
    ofnFileOpened: 
     begin 
     ModuleServices := BorlandIDEServices as IOTAModuleServices; 
     Module := ModuleServices.FindModule(FileName); 
     if Assigned(Module) then 
      InstallSourceEditorNotifiers(Module); 
     end; 
    end; 
end; 

initialization 

finalization 
    RemoveIDENotifier; 
    ClearSourceEditorNotifiers; 
    FreeAndNil(SourceEditorNotifiers); 


end. 

Jak mogę wykryć okno modułów jest otwarte w edytorze Delphi IDE?

+0

Myślę, że przyjąłeś całkowicie błędny kod. 'Moduły' to terminy OTA nie mają nic wspólnego z modułami procesowymi w zdroworozsądkowych terminach debugowania Win32. Nie ma na to usługi OTA, powinieneś przejść do poziomu VCL i poszukać odpowiedniego ** formularza **. –

Odpowiedz

2

AFAIK the ToolsAPI nie zapewnia żadnego zgłaszającego dla takiej sytuacji. Ale możesz spróbować przechwycić aktywację okna za pomocą haka WH_CBT, wypróbować kody HCBT_ACTIVATE lub HCBT_SETFOCUS. Dla próbki Delphi sprawdź odpowiedź na tę question.

Powiązane problemy