如何显示“数字键盘";分配给`VK_NUMPAD0`的菜单项快捷方式? [英] How to show "NUMERIC KEYPAD" for menu item shortcut assigned with `VK_NUMPAD0`?

查看:134
本文介绍了如何显示“数字键盘";分配给`VK_NUMPAD0`的菜单项快捷方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Windows 10 X64(德语)上的Delphi 10.4.2 Win32 VCL应用程序中,我以编程方式设置了某些菜单项的快捷方式:

  mRasterizedDoubleSize.Shortcut:= VK_ADD;mRasterizedHalveSize.Shortcut:= VK_SUBTRACT;mRasterizedResetToOriginalSVGSize.Shortcut:= VK_NUMPAD0; 

这将在运行时显示以下菜单:

("ZEHNERTASTATUR"是德语的NUMERIC KEYPAD)

为什么要使用"Zehnertastatur"(数字键盘)没有显示在第三个菜单项上?

如何显示"ZEHNERTASTATUR"?(NUMERIC KEYPAD)分配给 VK_NUMPAD0 ?

的菜单项快捷方式

我已在Vcl.Menus中为此错误提交了质量报告:

不存在翻译单词"NUMPAD"的功能吗?在运行时转换为当前的系统语言?

EDIT2 :我已经尝试过此操作,以获取 VK_NUMPAD0 快捷方式的字眼,但它只给出相同的"0"字样.没有"NUMPAD"后缀:

  var s:TShortCut;s:= ShortCut(VK_NUMPAD0,[]);CodeSite.Send('TformMain.FormCreate:ShortCutToText(s)',ShortCutToText(s)); 

EDIT3 :我现在已经调试了 Vcl.Menus :该错误似乎在 Vcl.Menus.ShortCutToText 中:在VK_ADD ($ 6B)已由 GetSpecialName(ShortCut)正确翻译, VK_NUMPAD0 ($ 60)未由 GetSpecialName(ShortCut)进行翻译代码>!

EDIT4 :我找到了解决方法:

  function MyGetSpecialName(ShortCut:TShortCut):字符串;变种ScanCode:整数;关键字名称:字符数组[0..255];开始结果:='';ScanCode:= Winapi.Windows.MapVirtualKey(LoByte(Word(ShortCut)),0)shl 16;如果ScanCode<>然后0开始如果Winapi.Windows.GetKeyNameText(ScanCode,KeyName,Length(KeyName))<>然后0结果:= KeyName;结尾;结尾;var s:System.Classes.TShortCut;s:= ShortCut(VK_NUMPAD0,[]);CodeSite.Send('ShortCutToText',MyGetSpecialName(s)); 

解决方案

一种方法是这样的:

使用 TActionList .一般而言,这是一种好习惯.在此列表中定义您的操作,然后将它们简单地映射到菜单项,按钮,复选框等.操作列表功能是VCL IMHO最好的部分之一.

现在,使用 Caption ='Reset zoom'#9'Numpad 0'和NO ShortCut 创建一个名为 aResetZoom 的操作.将其放在菜单栏上.

然后,创建一个名为 aResetZoomShortcut new 动作,该动作具有相同的 OnExecute (可能还具有相同的 OnUpdate )和快捷方式 Num 0 (在设计时设置或在运行时以编程方式设置).不要将其放在主菜单上.

结果:

当我按下数字键盘0(而不是Alpha 0)时,就会触发该动作.

此方法有很多变体.也许您可以通过单个动作使它工作,而没有 ShortCut ,但是在其 SecondaryShortCuts 列表中为Num 0.或者,您可以使用表单的 KeyPreview OnKeyPress 属性,而不是使用虚拟"属性.行动.

许多选项.选择最适合您的特定情况的一种.

赠言

请注意,完全有可能在设计时使用对象检查器设置带有选项卡的字幕.参见

在我的系统上.

In a Delphi 10.4.2 Win32 VCL Application, on Windows10 X64 (German language) I set the shortcuts for some menu items programmatically:

mRasterizedDoubleSize.Shortcut := VK_ADD;
mRasterizedHalveSize.Shortcut := VK_SUBTRACT;
mRasterizedResetToOriginalSVGSize.Shortcut := VK_NUMPAD0;

This results in the following menu at run-time:

("ZEHNERTASTATUR" is German for NUMERIC KEYPAD)

Why "Zehnertastatur" (numeric keypad) is not shown for the third menu item?

How can I show "ZEHNERTASTATUR" (NUMERIC KEYPAD) for the menu item shortcut assigned with VK_NUMPAD0?

I have filed a Quality Report for this bug in Vcl.Menus: https://quality.embarcadero.com/browse/RSP-33296 Please vote for it!

EDIT: I have tried Andreas' advice, but it does work only programmatically at run-time, not at design-time in the Object Inspector:

mRasterizedResetToOriginalSVGSize.Caption := mRasterizedResetToOriginalSVGSize.Caption + #9 + '0 (NUMPAD)  ';

Isn't there a function that translates the word "NUMPAD" into the current system language at-run-time?

EDIT2: I have tried this to get the word for the VK_NUMPAD0 shortcut, but it only gives back the same "0" without the "NUMPAD" suffix:

var s: TShortCut;
s := ShortCut(VK_NUMPAD0, []);
CodeSite.Send('TformMain.FormCreate: ShortCutToText(s)', ShortCutToText(s));

EDIT3: I now have debugged Vcl.Menus: The bug seems to be in Vcl.Menus.ShortCutToText: While VK_ADD ($6B) is correctly translated by GetSpecialName(ShortCut), VK_NUMPAD0 ($60) is NOT being translated by GetSpecialName(ShortCut)!

EDIT4: I have found the solution:

function MyGetSpecialName(ShortCut: TShortCut): string;
var
  ScanCode: Integer;
  KeyName: array[0..255] of Char;
begin
  Result := '';
  ScanCode := Winapi.Windows.MapVirtualKey(LoByte(Word(ShortCut)), 0) shl 16;
  if ScanCode <> 0 then
  begin
    if Winapi.Windows.GetKeyNameText(ScanCode, KeyName, Length(KeyName)) <> 0 then
      Result := KeyName;
  end;
end;

var s: System.Classes.TShortCut;
s := ShortCut(VK_NUMPAD0, []);
CodeSite.Send('ShortCutToText', MyGetSpecialName(s));

解决方案

One approach is like this:

Use a TActionList. This is good practice in general. Define your actions within this list, and then simply map them to menu items, buttons, check boxes, etc. The action list facility is one of the very best parts of the VCL IMHO.

Now, create an action named aResetZoom with Caption = 'Reset zoom'#9'Numpad 0' and NO ShortCut. Put this on the menu bar.

Then, create a new action named aResetZoomShortcut with the same OnExecute (and possibly the same OnUpdate) and shortcut Num 0 (set at design time or programmatically at run time). Don't put this on the main menu.

The result:

and the action is triggered when I press numpad 0 (but not the alpha 0).

There are many variants to this approach. Maybe you can make it work with a single action with no ShortCut but with Num 0 in its SecondaryShortCuts list. Or you can use the form's KeyPreview and OnKeyPress properties instead of the "dummy" action.

Many options. Choose the one that is best suited for your particular scenario.

Bonus remarks

Please note it is perfectly possibly to set captions with tabs at design time using the Object Inspector. See example video.

You can probably do localisation using the Win32 GetKeyNameText function. The following code is adapted from the VCL:

var
  name: array[0..128] of Char;
begin
  FillChar(name, SizeOf(name), 0);
  GetKeyNameText(MapVirtualKey(VK_NUMPAD0, 0) shl 16, @name[0], Length(name));
  // string(name) now is 'NUM 0' on my system

That being said, personally I don't mind if shortcut descriptions are non-localized or manually localised -- like the rest of the application.

Update

A clarification on how to use the localisation code:

procedure TForm5.FormCreate(Sender: TObject);
var
  name: array[0..128] of Char;
  NameAsANormalString: string;
begin
  FillChar(name, SizeOf(name), 0);
  GetKeyNameText(MapVirtualKey(VK_NUMPAD0, 0) shl 16, @name[0], Length(name));
  NameAsANormalString := name;
  ShowMessage(name);
end;

produces

on my system.

这篇关于如何显示“数字键盘";分配给`VK_NUMPAD0`的菜单项快捷方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆