You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过OTA拦截Delphi的Control+Click实现自定义查找声明快捷键?

如何通过OTA实现Delphi中自定义Control+Alt+Click跳转逻辑?

要实现这个需求,你需要借助Delphi的Open Tools API(OTA)拦截默认的「查找声明」命令,同时检测按键状态来分支执行逻辑。下面是具体的实现步骤:

1. 创建基础OTA插件框架

首先搭建一个OTA插件项目,核心是实现IOTAWizard(用于注册插件)和IOTAKeyboardBinding(用于拦截编辑器命令)两个接口:

unit CustomFindDeclWizard;

interface

uses
  ToolsAPI, SysUtils, Classes, Windows;

type
  TCustomFindDeclWizard = class(TInterfacedObject, IOTAWizard, IOTAKeyboardBinding)
  public
    // IOTAWizard 接口方法
    procedure Execute;
    function GetIDString: string;
    function GetName: string;
    function GetState: TWizardState;
    // IOTAKeyboardBinding 接口方法
    function GetBindingType: TBindingType;
    function GetDisplayName: string;
    function GetName: string;
    function Bindings: TKeyBindingArray;
    function ExecuteCommand(const Context: IOTAKeyContext;
      const Command: TCommand; var Handled: Boolean): Boolean;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterPackageWizard(TCustomFindDeclWizard.Create);
end;

// 接口方法实现见后续步骤

2. 拦截默认「查找声明」命令

默认的Control+Click触发的是cm_FindDeclaration命令,我们在ExecuteCommand方法中拦截这个命令,同时检测Alt键状态:

function TCustomFindDeclWizard.ExecuteCommand(const Context: IOTAKeyContext;
  const Command: TCommand; var Handled: Boolean): Boolean;
var
  Editor: IOTAEditor;
  SourceEditor: IOTASourceEditor;
  CursorPos: TOTAEditPos;
  AltPressed: Boolean;
begin
  Result := False;
  // 只拦截查找声明命令
  if Command = cm_FindDeclaration then
  begin
    // 检测Alt键是否按下(GetKeyState返回值<0表示按键处于按下状态)
    AltPressed := GetKeyState(VK_MENU) < 0;
    if AltPressed then
    begin
      Handled := True; // 标记为已处理,阻止默认逻辑执行
      // 获取当前激活的源代码编辑器
      Editor := Context.Editor;
      if Supports(Editor, IOTASourceEditor, SourceEditor) then
      begin
        CursorPos := SourceEditor.CursorPos;
        // 这里添加你的自定义逻辑:
        // 比如获取光标下的类型名称、自定义查找声明位置等
        ShowMessage('执行自定义Control+Alt+Click查找声明逻辑');
      end;
    end
    else
    begin
      Handled := False; // 不处理,让默认的Control+Click逻辑正常执行
    end;
  end;
end;

// 其他接口方法的默认实现
function TCustomFindDeclWizard.GetBindingType: TBindingType;
begin
  Result := btPartial; // 仅拦截指定命令,不覆盖所有绑定
end;

function TCustomFindDeclWizard.GetDisplayName: string;
begin
  Result := 'Custom Find Declaration with Alt';
end;

function TCustomFindDeclWizard.GetName: string;
begin
  Result := 'CustomFindDeclWizard.KeyBinding';
end;

function TCustomFindDeclWizard.Bindings: TKeyBindingArray;
begin
  Result := nil; // 无需新增快捷键,只拦截现有命令
end;

// IOTAWizard接口方法实现
procedure TCustomFindDeclWizard.Execute;
begin
  // 插件注册时无需执行额外操作
end;

function TCustomFindDeclWizard.GetIDString: string;
begin
  Result := 'YourCompany.CustomFindDeclWizard';
end;

function TCustomFindDeclWizard.GetName: string;
begin
  Result := 'Custom Find Declaration Wizard';
end;

function TCustomFindDeclWizard.GetState: TWizardState;
begin
  Result := [wsEnabled];
end;

3. 关键细节说明

  • 按键检测:用GetKeyState(VK_MENU)判断Alt键状态,返回值小于0表示按键处于按下状态。
  • 编辑器对象操作:通过Context.Editor获取当前激活编辑器,转换为IOTASourceEditor后可访问光标位置、源代码内容等信息。
  • 命令拦截控制:设置Handled := True会阻止Delphi执行默认逻辑;设为False则保留原有Control+Click的功能。

4. 编译与安装插件

将单元编译为Delphi包(.bpl),通过Delphi的「组件」→「安装包」菜单安装插件,重启Delphi后即可生效。

扩展提示

如果需要精准判断光标下的内容是否为类、接口等「类型」,可以借助OTA的IOTASyntaxServices分析源代码语法节点,识别当前选中的标识符类型。

内容的提问来源于stack exchange,提问作者Rodrigo Farias Rezino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:02:47