关于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)) = ) then
- begin
- Result := True;
- Delete(Text, , Length(Front));
- end;
- end;
- var
- Key: TShortCut;
- Shift: TShortCut;
- begin
- Result := ;
- Shift := ;
- 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 := $ to $ do { Copy range from table in ShortCutToText }
- if AnsiCompareText(Text, ShortCutToText(Key)) = 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
- $, $:
- Name := MenuKeyCaps[TMenuKeyCap(Ord(mkcBkSp) + WordRec(ShortCut).Lo - $)];
- $0D: Name := MenuKeyCaps[mkcEnter];
- $1B: Name := MenuKeyCaps[mkcEsc];
- $..$:
- Name := MenuKeyCaps[TMenuKeyCap(Ord(mkcSpace) + WordRec(ShortCut).Lo - $)];
- $2D..$2E:
- Name := MenuKeyCaps[TMenuKeyCap(Ord(mkcIns) + WordRec(ShortCut).Lo - $2D)];
- $..$: Name := Chr(WordRec(ShortCut).Lo - $ + Ord(''));
- $..$5A: Name := Chr(WordRec(ShortCut).Lo - $ + Ord('A'));
- $..$: Name := Chr(WordRec(ShortCut).Lo - $ + Ord(''));
- $..$: Name := 'F' + IntToStr(WordRec(ShortCut).Lo - $6F);
- else
- Name := GetSpecialName(ShortCut);
- end;
- if Name <> '' then
- begin
- Result := '';
- if ShortCut and scShift <> then Result := Result + MenuKeyCaps[mkcShift];
- if ShortCut and scCtrl <> then Result := Result + MenuKeyCaps[mkcCtrl];
- if ShortCut and scAlt <> 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快捷键和小键盘的问题的更多相关文章
- PowerDesigner从Sqlserver中反转为带注释的字典及快捷键操作
PowerDesigner的操作经常忘记,所以把常用的功能记录下来备忘. 1.修改反转过来的字段 PowerDesigner从数据库反转的时候,默认不带注释,需要先进行修改. 输入如下脚本: {OWN ...
- power designer 一般常用快捷键(转)
一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 ...
- 【转】PowerDesigner快捷键
一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 ...
- PowerDesigner快捷键【转】
一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 ...
- IntelliJ IDEA 快捷键(一)(window版)
一.高效定位代码 1.跳转 1.项目之间的跳转 Next Project Window 快捷键 Ctrl + Alt + 左方括号. Previous Project Window 快捷键 Ctrl ...
- PowerDesigner 快捷键
一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 ...
- Android Studio笔记之快捷键
Android Studio h2{ color: #4abcde; } pre{ background-color: #f8f8f8; border: solid 1px #ccc; border- ...
- PowerDesigner常用快捷键
一般快捷键 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部 ...
- AD各种布线方法总结
1.常规布线:不详细说了,是个人就知道怎么弄.需要说明的是在布线过程中,可按小键盘的*键或大键盘的数字2键添加一个过孔:按L键可以切换布线层:按数字3可设定最小线宽.典型线宽.最大线宽的值进行切换. ...
随机推荐
- NoSQL-Redis【1】-控制台配置密码
1.设置密码为123456 CONFIG SET requirepass 123456 2.验证密码 AUTH 123456 3.redis-cli连接 @ECHO OFF redis-cli.exe ...
- COGS1752 [BOI2007]摩基亚Mokia(CDQ分治 + 二维前缀和 + 线段树)
题目这么说的: 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它 ...
- Js提示框
百度搜索 1.artDialog 2.ymPrompt 以下网站提供资料参考 http://www.17sucai.com/ http://www.juheweb.com/ http://www.5i ...
- HDU5709 : Claris Loves Painting
对于每个点维护两棵线段树$T1[x],T2[x]$: $T1[x]$维护$x$子树内,深度在$[l,r]$内的点数,同种颜色有多个的话,保留深度最小的那个. $T2[x]$维护$x$子树内每种颜色的最 ...
- Redis内存缓存系统入门
网站:http://redis.io/ key-value cache and store data structure server 1. 服务器端 1.1 安装 下载安装包:http://r ...
- Android 读取蓝牙设备信息开发
(1)Android手机一般以客户端的角色主动连接SPP协议设备(接上蓝牙模块的数字传感器),连接流程是: 1.使用registerReceiver注册BroadcastReceiver来获取蓝牙状态 ...
- Android --时间控件的使用
1. mian.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: ...
- 配置1000条ACE的脚本
配置1000条ACE的脚本 测试 python 引言 在路由器或者交换机产品中,手工配置大量shell命令时,难免繁琐且效率低下,鉴于CRT中支持多种脚本语言,因此可通过脚本执行大量重复的shell配 ...
- Controller 通信 发布接收广播
在Angularjs开发一些经验总结随笔中提到我们需要按照业务却分angular controller,避免过大无所不能的上帝controller,我们把controller分离开了,但是有时候我们需 ...
- nginx和tomcat实现反向代理、负载均衡和session共享
这类的文章很多,nginx和tomcat实现反向代理.负载均衡实现很容易,可以参照http://blog.csdn.net/liuzhigang1237/article/details/8880752 ...