问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/23499166/how-i-can-detect-when-the-modules-window-is-open-in-the-delphi-ide