[英]Use Ctrl+/ as shortcut in Delphi program
这甚至可能吗? 例如,Notepad ++可以实现,但只是尝试将其分配给操作或菜单项等组件不起作用。 它被分配的事件根本不会触发。
所以,我把我的问题提交给谷歌。 纳达。 然后,我尝试逐步执行各种快捷方式功能,在本例中为TextToShortCut和ShortCutToText。
第一个,TextToShortCut,将“Ctrl + A”(字符串)等内容转换为以下16位值:
(uint)A | (uint)Ctrl
大多数工作正常。 但是,我观察到以下奇怪之处:
// Try converting back and forward...
TextToShortCut('Ctrl+/') = 16495
// That's incorrect. It should be:
Ord('/') or scCtrl = 16431
// Incorrect too
ShortCutToText(16495) = 'Ctrl+/'
// This is the shortcut the first line actually creates (Ctrl+o)
Ord('o') or scCtrl = 16495 // wut?
// Which is invalid, cause only caps are used
ShortCutToText(16431) = ''
这里发生了什么? 现在,我认为错误在于TextToShortCut的最后部分:在处理+符号之前的部分(在本例中为“Ctrl”)之后,它将尝试找到剩余部分(“/”)的快捷方式。 但是,在其当前形式中,+之后的部分也必须是它自己的有效快捷方式。
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;
所以,因为:
ShortCutToText('/') = 0 (failure)
MapVirtualKey('/',MAPVK_VK_TO_VSC) = 0 (failure)
...循环无法将'/'检测为有效的快捷方式。
这是一些VCL错误还是我错过了什么?
这是一个概念证明(是的,我正在拍摄代码的截图,但是将它与Component Palette混合在一起比直接使用此代码更快):
编辑1:
编辑2:
手动将16431分配给菜单项不起作用。
如果将OnShortCut
事件处理程序分配给菜单的父TForm
,您将看到按Ctrl + /导致来自Menus.ShortCutFromMessage()
的TShortCut
值为16575,这是VCL在调度快捷键处理时的内部函数。
ShortCutToText(16495)
和ShortCutToText(16575)
返回'Ctrl+/'
,所以让我们将其分解:
scCtrl = $4000
16495 = $406F
16575 = $40BF
两个快捷方式都有scCtrl
标志。
ShortCutToText($6F)
和ShortCutToText($BF)
都返回'/'
。 这是因为MapVirtualKey()
为两个虚拟键$6F
( VK_DIVIDE
)和$BF
( VK_OEM_2
- 美国键盘的/?
键MapVirtualKey()
返回相同的扫描码($ 350000)。
在调度快捷方式时,VCL会对TShortCut
值进行精确比较。 因此,当您将16495指定为快捷方式时,它将不会触发,因为系统正在报告16575的快捷方式,即使它们都映射到Ctrl+/
。
当我给你16575的ShortCut
一的财产TMenuItem
或TAction
,按下Ctrl + /触发项目,符合市场预期。
因此,关键的是,该系统报告使用该快捷方式VK_OEM_2
的虚拟键/
,但你希望它使用VK_DIVIDE
虚拟键代替。
从OnKeyDown
事件处理程序对Key
的简单调查显示了两种不同类型的正斜杠:
/
在数字键盘上= 111
(结合CTRL = 16575
) /
shift键旁边= 191
(结合CTRL = 16495
) 无法创建响应两者的单个快捷方式。
但是,您可以附加具有SecondaryShortCuts
属性的操作,而不是在memu项目上设置快捷方式。 然后使用:
procedure TForm1.FormCreate(Sender: TObject);
begin
Action1.ShortCut := 16575;
Action1.SecondaryShortCuts.Add('Ctrl+/');
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.