5

Delphi プラグインを作成していますが、モジュール (表示 - デバッグ ウィンドウ - モジュール) ウィンドウが開いている (IDE エディタに接続されている) ことを検出する必要があります。新しいエディタ ウィンドウが開いたときに通知を受け取るために IOTAEditorNotifier を使用していますが、ソース ファイルに対してのみ機能します。

これは、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.

モジュール ウィンドウが Delphi IDE エディタで開いていることを検出するにはどうすればよいですか?

4

1 に答える 1

2

私の知る限り、ToolsAPI はそのような状況に対する通知機能を提供していません。WH_CBT ただし、フックを使用して Windows のアクティベーションをインターセプトすることはでき ます。HCBT_ACTIVATEまたはHCBT_SETFOCUSコードを試してください。Delphi サンプルについては、この質問への回答を確認してください。

于 2014-05-07T17:09:09.943 に答える