关于Action快捷键和小键盘的问题

在使用全尺寸键盘的时候 键盘右边都有一排小键盘

但是这个小键盘的数字键值和普通键盘的数字键值是不一样的

在ANSI码里 标准数字键值是$30..$39, 而小键盘的键值是$60..$69

这样问题就来了 , 我们在属性编辑器里设置Action的ShortCut的时候, 使用的都是文字表示, 而VCL架构里, ShortCut的文字表示是不区分大小键盘数字键的

我们先看一下文字是真么转换成ShortCut的:

在Menus单元: TextToShortCut(Text: string): TShortCut; 函数

function TextToShortCut(Text: string): TShortCut;

  { If the front of Text is equal to Front then remove the matching piece
    from Text and return True, otherwise return False }

  function CompareFront(var Text: string; const Front: string): Boolean;
  begin
    Result := False;
    if (Length(Text) >= Length(Front)) and
      (AnsiStrLIComp(PChar(Text), PChar(Front), Length(Front)) = 0) then
    begin
      Result := True;
      Delete(Text, 1, Length(Front));
    end;
  end;

var
  Key: TShortCut;
  Shift: TShortCut;
begin
  Result := 0;
  Shift := 0;
  while True do
  begin
    if CompareFront(Text, MenuKeyCaps[mkcShift]) then Shift := Shift or scShift
    else if CompareFront(Text, ‘^‘) then Shift := Shift or scCtrl
    else if CompareFront(Text, MenuKeyCaps[mkcCtrl]) then Shift := Shift or scCtrl
    else if CompareFront(Text, MenuKeyCaps[mkcAlt]) then Shift := Shift or scAlt
    else Break;
  end;
  if Text = ‘‘ then Exit;
  for Key := $08 to $255 do { Copy range from table in ShortCutToText }
    if AnsiCompareText(Text, ShortCutToText(Key)) = 0 then
    begin
      Result := Key or Shift;
      Exit;
    end;
end;

注意加亮的那几行, 实际上就是吧$08~$255的所有字符和传入的做个比较, 那么我们的焦点就关注到ShortCutToText上了:

function ShortCutToText(ShortCut: TShortCut): string;
var
  Name: string;
begin
  case WordRec(ShortCut).Lo of
    $08, $09:
      Name := MenuKeyCaps[TMenuKeyCap(Ord(mkcBkSp) + WordRec(ShortCut).Lo - $08)];
    $0D: Name := MenuKeyCaps[mkcEnter];
    $1B: Name := MenuKeyCaps[mkcEsc];
    $20..$28:
      Name := MenuKeyCaps[TMenuKeyCap(Ord(mkcSpace) + WordRec(ShortCut).Lo - $20)];
    $2D..$2E:
      Name := MenuKeyCaps[TMenuKeyCap(Ord(mkcIns) + WordRec(ShortCut).Lo - $2D)];
    $30..$39: Name := Chr(WordRec(ShortCut).Lo - $30 + Ord(‘0‘));
    $41..$5A: Name := Chr(WordRec(ShortCut).Lo - $41 + Ord(‘A‘));
    $60..$69: Name := Chr(WordRec(ShortCut).Lo - $60 + Ord(‘0‘));
    $70..$87: Name := ‘F‘ + IntToStr(WordRec(ShortCut).Lo - $6F);
  else
    Name := GetSpecialName(ShortCut);
  end;
  if Name <> ‘‘ then
  begin
    Result := ‘‘;
    if ShortCut and scShift <> 0 then Result := Result + MenuKeyCaps[mkcShift];
    if ShortCut and scCtrl <> 0 then Result := Result + MenuKeyCaps[mkcCtrl];
    if ShortCut and scAlt <> 0 then Result := Result + MenuKeyCaps[mkcAlt];
    Result := Result + Name;
  end
  else Result := ‘‘;
end;

很明显, 这里面把标准数字键和小键盘数字键全部映射成0~9了, 那么自然在TextToShortCut的时候就只会认出标准键盘了

所以, 一般情况下, 是没办法在属性编辑器里设置小键盘热键的, 只能通过代码解决:

在代码模式下, Action的ShortCut属性是一个TShortCut类型: TShortCut = Low(Word)..High(Word); 也就是说, 是Ansi字符

那么我们就可以直接使用键值来设置ShortCut, 而绕过Text转换的步骤, 从而能够达到使用小键盘快捷键的目的:

  Action1.ShortCut := Menus.ShortCut(VK_NUMPAD0, [ssCtrl]);

这样就很简单的设置了一个ctrl+小键盘0的快捷键

那么, 如果要同时设置标准键0和小键盘0都能激活这个Action怎么做呢

这就要使用另一个属性: SecondaryShortCuts, 这个实际上是一个TStringList

  property SecondaryShortCuts: TShortCutList

  TShortCutList = class(TStringList)
  private
    function GetShortCuts(Index: Integer): TShortCut;
  public
    function Add(const S: String): Integer; override;
    function IndexOfShortCut(const Shortcut: TShortCut): Integer;
    property ShortCuts[Index: Integer]: TShortCut read GetShortCuts;
  end;

OK, 现在出现了另一个问题, 我们向SecondaryShortCuts里写入多个快捷键, 是使用的Add, 可惜....Add的是一个文本, 这样我们又回到开始的问题了, 文本没办法区分大小键盘数字键, 咋办...-_-

有人会说, 吧小键盘设置到ShortCut上, 大键盘用SecondaryShortCuts, OK, 这当然没问题....不过始终不是正统的解决办法(程序员的偏执)

研究代码吧:

function TShortCutList.Add(const S: String): Integer;
begin
  Result := inherited Add(S);
  Objects[Result] := TObject(TextToShortCut(S));
end;

function TShortCutList.GetShortCuts(Index: Integer): TShortCut;
begin
  Result := TShortCut(Objects[Index]);
end;

似乎有办法解决, add的时候实际上是吧ShortCut强制转换为TObject类型保存进Objects里了(其实是个取巧的办法, 我自己也总这么干...^_^)

而读取ShortCut的时候根本没读String, 直接读的就是Objects, 那么我们如果直接写Objects能否可行? 试试看:

  Action1.SecondaryShortCuts.AddObject(‘Ctrl+Num0‘, TObject(Menus.ShortCut(VK_NUMPAD0, [ssCtrl])));

OK, 测试完全可行......问题完美解决了

关于Action快捷键和小键盘的问题

时间: 2024-08-30 11:31:57

关于Action快捷键和小键盘的问题的相关文章

PowerDesigner从Sqlserver中反转为带注释的字典及快捷键操作

PowerDesigner的操作经常忘记,所以把常用的功能记录下来备忘. 1.修改反转过来的字段 PowerDesigner从数据库反转的时候,默认不带注释,需要先进行修改. 输入如下脚本: {OWNER, TABLE, S, COLUMN, DTTPCODE, LENGTH, SIZE, PREC, COMPUTE, NOTNULL, IDENTITY, DOMAIN, DEFAULT, COMMENT, ExtIdentityIncrement, ExtIdentitySeed} selec

PowerDesigner快捷键【转】

一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 F9 预览图窗口 F10 在图窗口中以一幅视图的高度显示图 Shift+单击对象 连续选择对象 alt+0 显示或隐藏浏览器窗口 alt+1 显示或隐藏输出窗口 alt+2 显示或隐藏结果列表窗口 ctrl+双击或ctrl+"+" 打开包图 ctrl+tab 在图窗口中切换大小,在文本中

【转】PowerDesigner快捷键

一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 F9 预览图窗口 F10 在图窗口中以一幅视图的高度显示图 Shift+单击对象 连续选择对象 alt+0 显示或隐藏浏览器窗口 alt+1 显示或隐藏输出窗口 alt+2 显示或隐藏结果列表窗口 ctrl+双击或ctrl+"+" 打开包图 ctrl+tab 在图窗口中切换大小,在文本中

第一次使用 idea,mybatis 获取 数据库 中的 数据 2017-9-14

1,在本机上安装 idea(安装步骤不在这说明了). 2,打开 idea 配置   maven 2.1 打开idea 需要一段时间,请耐心等待, 3,创建项目project idea 里只能有一个projiect 可以有多个module . 3.1 创建project 点击next 点击next 在点击上面的+号 archetypeCatalog=internal 在点击next 点击    finish 就行了 然后在看看下面的一行代码 -DarchetypeCatalog=internal

QPushButton 响应回车 设置默认按钮

ui.pushButton->setFocus(); //设置默认焦点 ui.pushButton->setShortcut( QKeySequence::InsertParagraphSeparator ); //设置快捷键为键盘的"回车"键 ui.pushButton->setShortcut(Qt::Key_Enter); //设置快捷键为enter键 ui.pushButton->setShortcut(Qt::Key_Return); //设置快捷键为

Altium_Designer-各种布线总结

1.常规布线:不详细说了,是个人就知道怎么弄.需要说明的是在布线过程中,可按小键盘的*键或大键盘的数字2键添加一个过孔:按L键可以切换布线层:按数字3可设定最小线宽.典型线宽.最大线宽的值进行切换. 2. 总线式布线:通俗的讲就是多条网络同事布线的问题.具体方法是,按住SHIFT,然后依次用光标移到要布线的网络,点击鼠标左键即可选中一条网络,选中所需的所有网络以后,单击工具栏汇的总线布线图标,在被选网络中任意单击即可开始多条网络同时布线.布线过程中可以按键盘上左右尖括号<>调节线间距. 3.差

怎么学习PS快?

? PS快速入门笔记 软件界面: 菜单栏, 工具箱 工具属性栏 悬浮面板 画布 ctrl + N 新建画布 ? 如果需要出图:分辨率:300 颜色模式:CMYK 屏幕显示: 分辨率: 72 颜色模式: RGB ? ? 切换画布的三种显示方式: F ? 针对画面显示的缩放:. 1: 缩放工具: Z 暂时切换到抓手工具: 按住 空格 满画布显示当前画面: ctrl + 0 (数字) ? 针对画面显示放大:ctrl + 加号. 针对画面显示缩小:ctrl + 减号. ? 切换到: 暂时切换到: ? L

PyCharm/IDEA 使用技巧总结

基本概念 IDEA 没有类似 Eclipse 的工作空间的概念(workspace),最大单元就是 Project.这里可以把 Project 理解为 Eclipse 中的 workspace.Module 可以理解为 Eclipse 中的 project.一个 工程(Project) 下可以创建多个 模块(Moudle). src 目录,用于存放代码 .idea 目录和 project01.iml 文件都是 IDEA 工程特有的. 删除 module ,这样不会删除代码文件,只是从 Proje

phpstorm分别在Mac和Windows下启动命令行,并启用ssh

Mac:在terminal下运行 sudo -i 输入密码  就可以用ssh IP:端口  命令行登录了 DAssist是一个命令行开发辅助,可直接在系统命令行工具中使用,Linux和MacOS等自带命令终端的系统好说,windows下也有cmd和powerShell.那么如何结合开发IDE工具进行使用?这要求编程使用的IDE必须支持terminal(默认支持或者插件扩展支持均可),PHP Web开发常用工具有jetBrains系列的phpStorm.WebStorm,也有用Sublime Te