dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.09k stars 1.17k forks source link

[API Proposal]: Public the ScanCode property in KeyEventArgs #8473

Open lindexi opened 12 months ago

lindexi commented 12 months ago

Background and motivation

As https://github.com/unoplatform/uno/pull/14371#discussion_r1407800681 , the UNO for WPF will use reflection to get the ScanCode property in KeyEventArgs.

And the ScanCode property in KeyEventArgs is useful in many businesses code or framework code.

This property is rarely used in WPF today.

The code to get the ScanCode (only ways) : https://github.com/dotnet/wpf/blob/187be47c5554d4745e9b17385889a8086d6e4286/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndSource.cs#L2362

The code to use ScanCode (only ways) : https://github.com/dotnet/wpf/blob/187be47c5554d4745e9b17385889a8086d6e4286/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/TextCompositionManager.cs#L435

API Proposal

public class KeyEventArgs
{
    public int ScanCode { get; internal set; }
}

Or

public class KeyEventArgs
{
    public int ScanCode { get; set; }
}

API Usage

KeyEventArgs args = ...;
var scanCode = args.ScanCode.

Alternative Designs

No response

Risks

No response

miloush commented 12 months ago

Few things:

  1. Note that this is public on RawKeyboardInputReport. Also note that rather than reflection, people can use MapVirtualKey to get the SC from VK.
  2. This should be public get only like the other properties on KeyEventArgs.
  3. You need an information on the extended keys. A lazy option would be to make the IsExtendedKey public as well, but there is now MAPVK_VK_TO_VSC_EX which gives you the actual extended scancode. I would think that would be preferable.
  4. I am not entirely convinced this should be exposed on KeyEventArgs, because it doesn't even expose virtual keys. Maybe an interop method similar to getting VK would be more consistent.
lindexi commented 6 months ago

Few things:

1. Note that this is public on `RawKeyboardInputReport`. Also note that rather than reflection, people can use MapVirtualKey to get the SC from VK.

2. This should be public get only like the other properties on `KeyEventArgs`.

3. You need an information on the extended keys. A lazy option would be to make the `IsExtendedKey` public as well, but there is now `MAPVK_VK_TO_VSC_EX` which gives you the actual extended scancode. I would think that would be preferable.

4. I am not entirely convinced this should be exposed on `KeyEventArgs`, because it doesn't even expose virtual keys. Maybe an interop method similar to getting VK would be more consistent.

For 1.

        var key = e.Key;
        var virtualKey = KeyInterop.VirtualKeyFromKey(key);

        // MAPVK_VK_TO_VSC 0
        var scanCode = MapVirtualKeyW((uint) virtualKey, 0);

        var scanCodeFromWpf = typeof(KeyEventArgs).GetProperty("ScanCode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(e);

        Debug.Assert(scanCode == (int) scanCodeFromWpf!);

    [DllImport("User32.dll")]
    private static extern uint MapVirtualKeyW(uint code, uint mapType);