【问题标题】:How to get the string representation of a ShortCut Key including the SHIFTSTATE?如何获取包含 SHIFTSTATE 的快捷键的字符串表示形式?
【发布时间】:2023-03-25 05:29:01
【问题描述】:

在 Delphi 10.4.2 Win32 VCL 应用程序中,并基于问题 + 解决方案 here,它提供了一种获取快捷键的字符串表示的方法(但大概不可能也为快捷键传递 SHIFTSTATE关键)我写了这段代码:

function MyGetSpecialShortcutName(ShortCut: TShortCut): string;
// gets shortcut name for e.g. VK_NUMPAD0 where TMenuItem.Shortcut gets the wrong shortcut name
var
  ScanCode: Integer;
  KeyName: array[0..255] of Char;
begin
  Result := '';
  FillChar(KeyName, SizeOf(KeyName), 0);
  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;

function GetSpecialShortcutNameWithShiftState(const AScanCode: Word; const AShiftState: System.Classes.TShiftState = []): string;
begin
  Result := MyGetSpecialShortcutName(Vcl.Menus.ShortCut(AScanCode, AShiftState));
end;

用法:

Result := GetSpecialShortcutNameWithShiftState(VK_A, [ssCTRL]);

但是,结果是“A”,而预期的结果应该是“CTRL+A”。

如何获取包含 SHIFTSTATE 的快捷键的字符串表示形式?

【问题讨论】:

  • 您需要本地化修饰符吗? (例如,英语中的“Ctrl+A”和德语中的“Strg+A”。)
  • 是的!谢谢你的提问!

标签: delphi keyboard-shortcuts delphi-10.4-sydney


【解决方案1】:

OP 希望键名完全本地化,但为了完整起见,我首先表明 VCL 已经具有获取部分未本地化字符串的功能,即 Menus 单元中的 ShortCutToText

ShortCutToText(ShortCut(Ord('A'), [ssShift, ssAlt]))

这会在所有系统上返回 Shift+Alt+A

现在,使用Q中已经提到的Win32函数GetKeyNameText,很容易获得完全本地化的快捷字符串:

function GetKeyName(AKey: Integer): string;
var
  name: array[0..128] of Char;
begin
  FillChar(name, SizeOf(name), 0);
  GetKeyNameText(MapVirtualKey(AKey, 0) shl 16, @name[0], Length(name));
  Result := name;
end;

function ModifierVirtualKey(AModifier: Integer): Integer;
begin
  case AModifier of
    Ord(ssShift):
      Result := VK_SHIFT;
    Ord(ssCtrl):
      Result := VK_CONTROL;
    Ord(ssAlt):
      Result := VK_MENU;
  else
    Result := 0;
  end;
end;

function ShortcutToString(AKey: Integer; AShiftState: TShiftState = []): string;
begin
  Result := '';
  for var Modifier in AShiftState do
  begin
    var ModifierKey := ModifierVirtualKey(Ord(Modifier));
    if ModifierKey <> 0 then
      Result := Result + IfThen(not Result.IsEmpty, '+') + GetKeyName(ModifierKey);
  end;
  Result := Result + IfThen(not Result.IsEmpty, '+') + GetKeyName(AKey);
end;

(这里我使用来自StrUtilsIfThen overload。)

现在,

ShortcutToString(Ord('A'), [ssShift, ssAlt])

在我的瑞典系统上返回 SKIFT+ALT+ASKIFT 是,正如您可能已经猜到的那样,SHIFT 键的瑞典名称。

【讨论】:

  • 琐事:几乎没有德国人知道SHIFT 的语言环境名称(它是UMSCHALT)——每个人都使用这个英文术语。 ENTER 也一样。相反,语言环境STRG(代表CTRL)通常被认为代表“Strong”或“String”。
  • @AmigoJack 我认为你错了。并非所有德国人都是愚蠢的。
  • @AndreasRejbrand 这是最完整的ShortcutToString 函数,因为除了键名之外,它还处理修饰符!非常好的代码!
猜你喜欢
  • 2011-08-27
  • 1970-01-01
  • 2014-08-23
  • 1970-01-01
  • 2020-01-14
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多