Как добавить связывание клавиш Shift+Ctrl+H X в Delphi IDE с помощью ToolsApi?
Добавление нового ShortCut в Delphi IDE не так уж сложно, поскольку API Open Tools предоставляет для этого сервис. Я пытаюсь сделать что-то более сложное: добавить Wordstar, как дополнительный ShortCut:
Я хочу, чтобы что-то произошло, когда пользователь нажимает
Shift+Ctrl+H, сопровождаемый единственной клавишей X
где X должен работать независимо от состояния клавиши Shift.
Это мой код:
procedure TGxKeyboardBinding.BindKeyboard(const BindingServices: IOTAKeyBindingServices);
const
DefaultKeyBindingsFlag = kfImplicitShift + kfImplicitModifier + kfImplicitKeypad;
var
GExpertsShortcut: Byte;
ShiftState: TShiftState;
FirstShortCut: TShortCut;
SecondShortCut: TShortCut;
begin
GExpertsShortcut := Ord('H');
ShiftState := [ssShift, ssCtrl];
FirstShortCut := ShortCut(GExpertsShortcut, ShiftState);
SecondShortCut := ShortCut(Ord('X'), []);
BindingServices.AddKeyBinding([FirstShortCut, SecondShortCut],
TwoKeyBindingHandler, nil,
DefaultKeyBindingsFlag, '', '');
end;
Итак, если я установлю ShiftState:= [ssCtrl] нажав
Ctrl+H X
вызывает мой метод TwoKeyBindingHandler.
Но с ShiftState:= [ssShift, ssCtrl] нажатие
Shift+Ctrl+H X
ничего не делает.
Как ни странно, при указании ShiftState:= [ssShift, ssCtrl] (который должен влиять только на первую клавишу) нажатие
Shift+Ctrl+H Shift+X
вызывает мой метод TwoKeyBindingHandler, хотя второй ShortCut добавляется без клавиши-модификатора.
Любая идея? Может быть, это известное ограничение / ошибка API Delphi IDE/Open Tools? Есть ли известный обходной путь?
Я пробовал это в Delphi 2007 и Delphi 10 Seattle, без разницы.
2 ответа
Вы должны быть в состоянии сделать это, используя функцию GetKeyState.
У программы есть две операции - Думайте об этом как об открытии пункта выпадающего меню. При нажатии ctr-shift-h вашей программе нужно будет отметить, что "Меню" теперь открыто и что последующие нажатия клавиш либо активируют опцию, либо закрывают "Меню", если нажата недопустимая клавиша.
function IsKeyDown(const VK: integer): boolean;
begin
IsKeyDown := GetKeyState(VK) and $8000 <> 0;
end;
procedure Form1.OnkeyDown(...)
begin
if Not H_MenuOpen then
if IsKeyDown(vk_Control) and IskeyDown(vk_Shift) and IsKeyDown(vk_H) then
begin
//Some Boolean in the form
H_MenuOpen:=True;
//Will probably need to invalidate some parameters here so that
//no control tries to process the key
exit;
end;
if H_MenuOpen then
begin
if key=vk_X then
begin
//x has been pressed
*Your code here*
//possibly invalidate some of the params again
exit;
end;
//Nothing valid
H_MenuOpen:=False;
end;
конец;
Хорошо, так как, очевидно, никто не нашел ответа, вот что я в итоге сделал:
Я уже планировал показать окно подсказки со списком всех возможных символов для второго ключа (фактически этот код уже работал нормально, используя подход, предложенный Хелен Фэргрив в ее ответе на этот вопрос). Вместо этого я теперь регистрирую только комбинацию клавиш:
BindingServices.AddKeyBinding([FirstShortCut],
TwoKeyBindingHandler, nil,
DefaultKeyBindingsFlag, '', '');
А в методе TwoKeyBindingHandler я показываю всплывающее меню, которое содержит эти символы в качестве ярлыков. Затем IDE/VCL/Windows обрабатывает все остальное для меня.
Это не ответ на актуальный вопрос, но он решает мою проблему. Извините, если вы попали сюда, ожидая чего-то большего.