There are a number of problems with that code:
- the wScanCode parameter of ToUnicodeEx() is not optional. Unfortunately, the OnKeyUp event does not give you the original scan code that the OS provided in the WM_KEYUP message. However, in this case, since only bit 15 of the scan code is really needed, you can fake it. For a KeyUp event, bit 15 needs to be set to 1, not 0.
- you are not populating the TKeyboardState before passing it in to ToUnicodeEx(). You need to call GetKeyboardState() first.
- you are passing in a single WideChar for the output buffer to ToUnicodeEx(), but you are telling ToUnicodeEx() that the buffer is large enough to hold 255 WideChars, which is a lie. The output of the conversion can be more than 1 WideChar, so you need to allocate enough space to hold the entire result. The return value will tell you how many WideChars were actually written to the buffer.
- ToUnicodeEx() alters the keyboard state while translating the key, unless you ask it not to (Windows 10+ only).
- WideCharToString() expects a null-terminated PWideChar string, not a single WideChar.
With that said, try something more like this instead:
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
buf: array[0..15] of WideChar;
KSta: TKeyboardState;
numChars: Integer;
begin
Winapi.Windows.GetKeyboardState(ksta);
numChars := Winapi.Windows.ToUnicodeEx(key, $8000, ksta, buf, Length(buf)-1, 4, 0);
if numChars > 0 then
begin
buf[numChars] := #0;
log.Lines.Add('KeyUp : ' + IntToStr(Key) + ' = ' + WideCharToString(buf));
end
else if numChars = 0 then
log.Lines.Add('KeyUp : ' + IntToStr(Key) + ' = (no translation)')
end else
log.Lines.Add('KeyUp : ' + IntToStr(Key) + ' = (dead key)');
end;
However, if you really want to handle individual key presses, you should be using the OnKeyPress event of the OnKey[Down|Up] events, as previously stated. The OnKeyPress event gives you translated Unicode characters, not virtual key codes.
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
log.Lines.Add('KeyPress : ' + IntToStr(Key) + ' = ' + Key);
end;