I'm writing a Delphi plugin and I need detect when the Modules (View - Debug windows - Modules) window is open (attached to IDE Editor). I'm using the IOTAEditorNotifier to get notified when a new Editor window is open, but only works for source files.
This is the code used to receive the notifications from the IDE Editor.
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.
How I can detect the modules window is open in the Delphi IDE Editor?
AFAIK the ToolsAPI doesn't provide any notifier for such situation. But you can try intercepting the windows activation using a WH_CBT
hook, try the HCBT_ACTIVATE
or HCBT_SETFOCUS
codes. For a Delphi sample check the answer to this question.