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

D10 Seattle IDE插件开发:如何通过OTA调用Find Declaration功能

我正好有过Delphi 10 Seattle IDE插件开发的相关经验,针对你遇到的集成Find Declaration功能的问题,给你几个实用的解决方案:

直接调用核心功能的最优方案

Delphi的*Open Tools API(OTA)*提供了直接触发Find Declaration的途径,这比绕路上下文菜单更可靠,步骤如下:

  • 首先获取IDE命令服务,找到内置的Find Declaration命令:
    var CmdSvc: IOTAIDECommands;
        FindDeclCmd: IOTAIDECommand;
    begin
      if Supports(BorlandIDEServices, IOTAIDECommands, CmdSvc) then
      begin
        // 找到Find Declaration对应的命令
        FindDeclCmd := CmdSvc.IDECommandByName('cm_FindDeclaration');
        if Assigned(FindDeclCmd) then
          FindDeclCmd.Execute;
      end;
    end;
    
  • 关于面包屑记录:在执行命令前,你可以通过OTA的IOTAEditorHistory接口手动添加当前位置到导航历史:
    var EditorSvc: IOTAEditorServices;
        EditView: IOTAEditView;
        EditorHistory: IOTAEditorHistory;
    begin
      if Supports(BorlandIDEServices, IOTAEditorServices, EditorSvc) then
      begin
        EditView := EditorSvc.TopView;
        if Assigned(EditView) and Supports(EditView.Buffer, IOTAEditorHistory, EditorHistory) then
        begin
          // 添加当前光标位置到面包屑历史
          EditorHistory.AddHistoryEntry(EditView.Buffer.FileName, 
                                        EditView.CursorPos.Line, 
                                        EditView.CursorPos.Col);
        end;
      end;
    end;
    
    把这段代码放在执行Find Declaration命令之前,就能满足先添加面包屑的需求。
上下文菜单替代方案(备用)

如果因为某些版本兼容性问题无法直接调用OTA命令,你可以通过模拟触发上下文菜单的方式实现,但这个方法稳定性稍差,依赖菜单文本和ID:

  • 核心思路是通过Windows API找到IDE上下文菜单中「Find Declaration」的菜单项ID,然后发送点击消息:
    function FindMenuItemID(MenuHandle: HMENU; const ItemText: string): Integer;
    var
      I: Integer;
      MenuItemInfo: TMenuItemInfo;
      Buffer: array[0..255] of Char;
    begin
      Result := -1;
      for I := 0 to GetMenuItemCount(MenuHandle) - 1 do
      begin
        ZeroMemory(@MenuItemInfo, SizeOf(TMenuItemInfo));
        MenuItemInfo.cbSize := SizeOf(TMenuItemInfo);
        MenuItemInfo.fMask := MIIM_STRING or MIIM_ID;
        MenuItemInfo.cch := SizeOf(Buffer);
        MenuItemInfo.dwTypeData := Buffer;
        if GetMenuItemInfo(MenuHandle, I, True, MenuItemInfo) then
        begin
          if AnsiSameText(Buffer, ItemText) then
          begin
            Result := MenuItemInfo.wID;
            Break;
          end;
        end;
      end;
    end;
    
    // 调用示例
    var MainIDEHandle: HWND;
        ContextMenu: HMENU;
        DeclMenuItemID: Integer;
    begin
      // 获取IDE主窗口句柄
      MainIDEHandle := BorlandIDEServices.GetMainHandle;
      // 获取编辑器上下文菜单(需确保当前编辑器处于激活状态)
      ContextMenu := GetSystemMenu(MainIDEHandle, False); // 实际需调整为编辑器的上下文菜单,这里仅作示例
      DeclMenuItemID := FindMenuItemID(ContextMenu, 'Find Declaration');
      if DeclMenuItemID <> -1 then
        SendMessage(MainIDEHandle, WM_COMMAND, DeclMenuItemID, 0);
    end;
    
    注意:如果是中文版本的IDE,要把'Find Declaration'换成对应的中文文本「查找声明」,而且菜单ID可能随版本变化,所以优先推荐第一种OTA方案。
额外提示
  • 确保你的插件初始化时正确获取了BorlandIDEServices接口,这是访问OTA所有功能的基础。
  • 测试时要保证当前编辑器中有有效的标识符(比如光标停在变量、函数名上),否则Find Declaration不会生效。

内容的提问来源于stack exchange,提问作者mether

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:55:33