In a Delphi 10.4.2 Win32 VCL Application in Windows 10 x64, I use this code to programmatically create a Shortcut STRING for the DELETE key on a popup menu item:
mGalleryDeleteSelected.Caption := mGalleryDeleteSelected.Caption + #9 + MyShortcutToString(VK_DELETE, []) + ' ';
This is the source-code:
function MyGetKeyName(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 MyModifierVirtualKey(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 MyShortcutToString(AKey: Integer; AShiftState: TShiftState = []): string;
begin
Result := '';
for var Modifier in AShiftState do
begin
var ModifierKey := MyModifierVirtualKey(Ord(Modifier));
if ModifierKey <> 0 then
Result := Result + IfThen(not Result.IsEmpty, '+') + MyGetKeyName(ModifierKey);
end;
Result := Result + IfThen(not Result.IsEmpty, '+') + MyGetKeyName(AKey);
end;
However, instead of getting the shortcut string for the normal DELETE key, I get the shortcut string for the (auxiliary?) Comma/Delete key on the Numeric keypad:
As I have a German language Windows, here are the translations:
KOMMA = comma
ZEHNERTASTATUR = numeric keypad
The default Delete key on a German keyboard has the label "entf" (abbreviation for "Entfernen")
The keypress of the comma key on the numeric keypad does work as a Delete command if the numeric keypad is set to work for navigation commands. However, I need to get the string for the NORMAL DELETE key. How can I do that?
From the documentation for GetKeyNameText
:
24 Extended-key flag. Distinguishes some keys on an enhanced keyboard.
This says that it uses bit 24 in the LPARAM-styled argument as the extended-key flag.
Then, in About Keyboard Input:
Extended-Key Flag
The extended-key flag indicates whether the keystroke message originated from one of the additional keys on the enhanced keyboard. The extended keys consist of the ALT and CTRL keys on the right-hand side of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad; the NUM LOCK key; the BREAK (CTRL+PAUSE) key; the PRINT SCRN key; and the divide (/) and ENTER keys in the numeric keypad. The extended-key flag is set if the key is an extended key.
(body text emphasis mine).
Therefore, I conclude, that you can use
function MyGetKeyName(AKey: Integer): string;
var
name: array[0..128] of Char;
begin
FillChar(name, SizeOf(name), 0); // ADD THIS!
GetKeyNameText(MapVirtualKey(AKey, 0) shl 16 or 1 shl 24, @name[0], Length(name));
Result := name;
end;
to get the name of the Del
key between the alphabetical and numeric parts of the keyboard.
Of course, you probably don't want to set this bit for other keys, so you need to refactor your code. Unfortunately, it seems like VK_DELETE
can map to two physical keys.
Here's one approach:
function MyGetKeyName(AKey: Integer; AExtended: Boolean = False): string;
var
name: array[0..128] of Char;
begin
FillChar(name, SizeOf(name), 0);
if // ADD THIS!
GetKeyNameText(MapVirtualKey(AKey, 0) shl 16 or Cardinal(Ord(AExtended)) shl 24,
@name[0], Length(name)) <> 0
then
Result := name
else
Result := '';
end;
and add this parameter to your MyShortcutToString
as well (which only need to pass it to MyGetKeyName
):
function MyShortcutToString(AKey: Integer; AShiftState: TShiftState = [];
AExtended: Boolean = False): string;
begin
Result := '';
for var Modifier in AShiftState do
begin
var ModifierKey := MyModifierVirtualKey(Ord(Modifier));
if ModifierKey <> 0 then
Result := Result + IfThen(not Result.IsEmpty, '+') + MyGetKeyName(ModifierKey);
end;
Result := Result + IfThen(not Result.IsEmpty, '+') + MyGetKeyName(AKey, AExtended);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With