Добавить пункт меню в контекстное меню вкладки устройства в Delphi IDE с помощью ToolsAPI
Я ищу, чтобы выяснить, какие сервисы / интерфейс мне нужно использовать для добавления элемента в контекстное меню исходного файла в Delphi IDE.
Например, если я щелкну правой кнопкой мыши на вкладке устройства, у него есть пункты "Закрыть страницу", "Закрыть все другие страницы", "Свойства" и т. Д. Я хочу добавить пользовательские элементы в это меню, если это возможно.
Я просмотрел блок ToolsAPI, но понятия не имею, с чего начать. Я предполагаю, что есть интерфейс, который я могу использовать для перечисления элементов и добавления элементов, но я не знаю, с чего начать.
Если это невозможно, я бы согласился на контекстное меню редактора кода.
Может быть, есть несколько примеров в Интернете для этого, но я все еще ищу и не нашел ни одного.
Любая помощь приветствуется.
1 ответ
Реми Лебо указал вам в правильных направлениях своей ссылкой на руководство GExperts.
Если вы еще не делали такого рода вещи раньше, то, возможно, начнете писать собственную надстройку для IDE, и это может быть чем-то вроде производительности, поэтому ниже я приведу минимальный пример того, как добавить элемент в всплывающее меню редактора кода.
Очевидно, что вы делаете, чтобы создать новый пакет, добавить нижеприведенный модуль и затем установить пакет в IDE. Призыв к Register
в модуле делает все необходимое для установки нового пункта во всплывающем меню редактора.
Убедитесь, что редактор кода открыт во время установки пакета. Причина в том, что, как вы увидите, код проверяет, есть ли активный редактор в данный момент. Я оставил, как обеспечить добавление всплывающего элемента, даже если в данный момент нет активного редактора кода. Подсказка: если вы посмотрите на модуль ToolsAPI.Pas для какой-либо версии Delphi, которую вы используете, вы обнаружите, что он включает в себя различные виды уведомлений, и вы можете использовать уведомление хотя бы от одного из них, чтобы отложить проверку, если есть Является ли редактор активным до тех пор, пока он, вероятно, не будет.
Кстати, код добавляет пункт меню в контекстное меню, которое всплывает над окном редактора, а не на активной вкладке. Часть удовольствия с надстройками IDE - это удовольствие от экспериментов, чтобы увидеть, сможете ли вы получить именно то, что вы хотите. Я сам не пробовал, но сомневаюсь, что добавить пункт меню в контекстное меню одной из вкладок редактора было бы очень сложно - поскольку Delphi IDE является приложением Delphi, как вы можете видеть из приведенного ниже кода, Вы можете использовать FindComponent (или просто перебрать коллекцию компонентов), чтобы найти то, что вы хотите. Тем не менее, лучше, если вы можете найти вещи через интерфейсы ToolsAPI. Смотрите обновление ниже.
interface
uses
Classes, Windows, Menus, Dialogs, ToolsAPI;
type
TIDEMenuItem = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
function GetName: string;
function GetIDString: string;
function GetMenuText: string;
function GetState: TWizardState;
procedure Execute;
end;
TIDEMenuHandler = class(TObject)
procedure HandleClick(Sender: TObject);
end;
procedure Register;
implementation
var
MenuItem: TMenuItem;
IDEMenuHandler: TIDEMenuHandler;
EditorPopUpMenu : TPopUpMenu;
procedure TIDEMenuItem.Execute;
begin
ShowMessage('Execute');
end;
function TIDEMenuItem.GetIDString: string;
begin
Result := 'IDEMenuItemID';
end;
function TIDEMenuItem.GetMenuText: string;
begin
Result := 'IDEMenuItemText';
end;
function TIDEMenuItem.GetName: string;
begin
Result := 'IDEMenuItemName';
end;
function TIDEMenuItem.GetState: TWizardState;
begin
Result := [wsEnabled];
end;
procedure TIDEMenuHandler.HandleClick(Sender: TObject);
begin
ShowMessage(TIDEMenuItem(Sender).GetName + ' Clicked');
end;
procedure AddIDEMenu;
var
NTAServices: INTAServices40;
EditorServices: IOTAEditorServices;
EditView: IOTAEditView;
begin
NTAServices := BorlandIDEServices as INTAServices40;
EditorServices := BorlandIDEServices as IOTAEditorServices;
EditView := EditorServices.TopView;
if Assigned(EditView) then begin
EditorPopUpMenu := TPopUpMenu(EditView.GetEditWindow.Form.FindComponent('EditorLocalMenu'));
Assert(EditorPopUpMenu <>Nil);
IDEMenuHandler := TIDEMenuHandler.Create;
MenuItem := TMenuItem.Create(Nil);
MenuItem.Caption := 'Added IDE editor menu item';
MenuItem.OnClick := IDEMenuHandler.HandleClick;
EditorPopUpMenu.Items.Add(MenuItem)
end
else
ShowMessage('Code editor not active');
end;
procedure RemoveIDEMenu;
begin
if MenuItem <> Nil then begin
EditorPopUpMenu.Items.Remove(MenuItem);
FreeAndNil(MenuItem);
IDEMenuHandler.Free;
end;
end;
procedure Register;
begin
RegisterPackageWizard(TIDEMenuItem.Create);
AddIDEMenu;
end;
initialization
finalization
RemoveIDEMenu;
end.
Обновление: следующий код находит TabControl окна редактора и добавляет пункт меню в его контекстное меню. Однако обратите внимание, что он не учитывает наличие второго открытого окна редактора.
procedure AddIDEMenu;
var
NTAServices: INTAServices40;
EditorServices: IOTAEditorServices;
EditView: IOTAEditView;
TabControl : TTabControl;
function FindTabControl(AComponent : TComponent) : TTabControl;
var
i : Integer;
begin
Result := Nil;
if CompareText(AComponent.ClassName, 'TXTabControl') = 0 then begin
Result := TTabControl(AComponent);
exit;
end
else begin
for i := 0 to AComponent.ComponentCount - 1 do begin
if CompareText(AComponent.Components[i].ClassName, 'TXTabControl') = 0 then begin
Result := TTabControl(AComponent.Components[i]);
exit;
end
else begin
Result := FindTabControl(AComponent.Components[i]);
if Result <> Nil then
exit;
end;
end;
end;
end;
begin
NTAServices := BorlandIDEServices as INTAServices40;
EditorServices := BorlandIDEServices as IOTAEditorServices;
EditView := EditorServices.TopView;
if Assigned(EditView) then begin
TabControl := FindTabControl(EditView.GetEditWindow.Form);
Assert(TabControl <> Nil, 'TabControl not found');
EditorPopUpMenu := TabControl.PopupMenu;
Assert(EditorPopUpMenu <> Nil, 'PopUP menu not found');
//EditorPopUpMenu := TPopUpMenu(EditView.GetEditWindow.Form.FindComponent('EditorLocalMenu'));
Assert(EditorPopUpMenu <>Nil);
IDEMenuHandler := TIDEMenuHandler.Create;
MenuItem := TMenuItem.Create(Nil);
MenuItem.Caption := 'Added IDE editor menu item';
MenuItem.OnClick := IDEMenuHandler.HandleClick;
EditorPopUpMenu.Items.Add(MenuItem)
end
else
ShowMessage('No editor active');
end;