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接口手动添加当前位置到导航历史:
把这段代码放在执行Find Declaration命令之前,就能满足先添加面包屑的需求。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;
上下文菜单替代方案(备用)
如果因为某些版本兼容性问题无法直接调用OTA命令,你可以通过模拟触发上下文菜单的方式实现,但这个方法稳定性稍差,依赖菜单文本和ID:
- 核心思路是通过Windows API找到IDE上下文菜单中「Find Declaration」的菜单项ID,然后发送点击消息:
注意:如果是中文版本的IDE,要把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;'Find Declaration'换成对应的中文文本「查找声明」,而且菜单ID可能随版本变化,所以优先推荐第一种OTA方案。
额外提示
- 确保你的插件初始化时正确获取了
BorlandIDEServices接口,这是访问OTA所有功能的基础。 - 测试时要保证当前编辑器中有有效的标识符(比如光标停在变量、函数名上),否则Find Declaration不会生效。
内容的提问来源于stack exchange,提问作者mether
相关产品推荐
相关产品推荐

