2014-05-06 12 views
5

Ich schreibe ein Delphi-Plugin und ich muss feststellen, wenn das Fenster Module (View - Debug windows - Modules) geöffnet ist (an den IDE Editor angehängt). Ich verwende den IOTAEditorNotifier, um benachrichtigt zu werden, wenn ein neues Editor-Fenster geöffnet ist, aber nur für Quelldateien.Wie kann ich erkennen, wenn das Modulfenster in der Delphi-IDE geöffnet ist?

Dies ist der Code, der zum Empfangen der Benachrichtigungen vom IDE-Editor verwendet wird.

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. 

Wie kann ich erkennen, dass das Modulfenster im Delphi IDE Editor geöffnet ist?

+0

Ich denke, Sie haben völlig falschen Code angenommen. 'Module' sind OTA-Begriffe haben nichts mit Prozess-Modulen im allgemeinen Sinne Win32 Debugging-Begriffe zu tun. Es gibt keine OTA-Dienste dafür, Sie sollten auf VCL-Ebene gehen und nach der entsprechenden ** Form ** suchen. –

Antwort

2

AFAIK die ToolsAPI stellt keinen Notifier für eine solche Situation bereit. Aber Sie können versuchen, die Windows-Aktivierung mit einem WH_CBT Haken abzufangen, versuchen Sie die HCBT_ACTIVATE oder HCBT_SETFOCUS Codes. Für ein Delphi-Beispiel überprüfen Sie die Antwort zu diesem question.