【问题标题】:How do I add the key binding Shift+Ctrl+H X to the Delphi IDE using the ToolsApi?如何使用 ToolsApi 将键绑定 Shift+Ctrl+H X 添加到 Delphi IDE?
【发布时间】:2016-01-31 16:37:47
【问题描述】:

向 Delphi IDE 添加一个新的 ShortCut 并不难,因为 Open Tools API 为此提供了服务。我正在尝试一些显然更复杂的东西:添加一个 Wordstar,比如额外的 ShortCut:

我希望用户按下时发生一些事情

Shift+Ctrl+H 后跟单键 X

无论 Shift 键的状态如何,X 都应该在哪里工作。

这是我的代码:

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 是在没有修饰键的情况下添加的。

有什么想法吗?这可能是 Delphi IDE/Open Tools API 的已知限制/错误吗?有已知的解决方法吗?

我在 Delphi 2007 和 Delphi 10 Seattle 中尝试过,没有区别。

【问题讨论】:

  • 您是否尝试过SecondShortcut := Shortcut(Ord('x'), []);(即指定小写x)?毕竟,要获得大写的 X 键,您通常也按 Shift 键。 (是的,我知道这是一个老问题)。

标签: delphi otapi


【解决方案1】:

您应该可以使用 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;

结束;

【讨论】:

  • 谢谢,这是一个通用检查热键的解决方案,但它不适用于我没有处理 OnKeyDown 的表单的特殊情况。 (除此之外:多次调用 IsKeyDown 似乎性能不佳,我可能只调用一次 GetKeyState 并检查组合键。)
  • 您仍然可以处理应用程序的 wm_keydown 消息。
  • 是的,我可以。如果我找不到使用 Open Tools API 的解决方案,我可能会这样做。不幸的是,我还必须阻止 IDE 甚至看到可能需要一些额外代码的密钥。但是当我到达那里时,我会过那座桥。
【解决方案2】:

好的,显然没有人找到答案,这就是我最终要做的:

我已经计划显示一个提示窗口,列出第二个键的所有可能字符(实际上,该代码已经运行良好,使用 Helen Fairgrieve 在回答这个问题时建议的方法)。相反,我现在只注册一个一键快捷方式:

BindingServices.AddKeyBinding([FirstShortCut],
  TwoKeyBindingHandler, nil,
  DefaultKeyBindingsFlag, '', '');

在 TwoKeyBindingHandler 方法中,我显示了一个弹出菜单,其中包含这些字符作为快捷方式。然后 IDE/VCL/Windows 会为我处理剩下的事情。

这是它的样子:

这不是对实际问题的回答,但它解决了我的问题。抱歉,如果您期待更多内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2018-11-17
    • 2012-08-21
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    相关资源
    最近更新 更多