mirror of
https://github.com/PowerShell/PSReadLine
synced 2026-06-08 12:12:13 +00:00
There are likely issues introduced by this PR, but I'm merging for a new Beta so this code gets more testing. * Introduce PSKeyInfo type alias * Explicit conversions b/w ConsoleKeyInfo and PSKeyInfo * Change tests to use actual ConsoleKeyInfo data * Add fr-FR keyboard layout tests * Add KeyInfo-ru-RU-windows.json (#839) All impossible without Shift shortcuts labeled as "Investigate: true" Alt+Spacebar tracked by windows itself * Add KeyInfo for Polish (Programmers) layout on Windows and Linux (#870) On Windows *Alt+Spacebar* is hijacked by Windows On Linux any *Alt+F1-12* combination was not detected
104 lines
3.2 KiB
C#
104 lines
3.2 KiB
C#
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using Xunit;
|
|
|
|
namespace Test
|
|
{
|
|
public class WindowsConsoleFixtureHelper
|
|
{
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
static extern IntPtr GetKeyboardLayout(uint idThread);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
static extern int GetKeyboardLayoutList(int nBuff, [Out] IntPtr[] lpList);
|
|
|
|
// For set:
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
|
|
|
|
// For get:
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
static extern IntPtr GetForegroundWindow();
|
|
|
|
const int WM_INPUTLANGCHANGEREQUEST = 0x0050;
|
|
|
|
private static string GetLayoutNameFromHKL(IntPtr hkl)
|
|
{
|
|
var lcid = (int)((uint)hkl & 0xffff);
|
|
return (new CultureInfo(lcid)).Name;
|
|
}
|
|
|
|
public static IEnumerable<string> GetKeyboardLayoutList()
|
|
{
|
|
int cnt = GetKeyboardLayoutList(0, null);
|
|
var list = new IntPtr[cnt];
|
|
GetKeyboardLayoutList(list.Length, list);
|
|
|
|
foreach (var layout in list)
|
|
{
|
|
yield return GetLayoutNameFromHKL(layout);
|
|
}
|
|
}
|
|
|
|
public static string GetKeyboardLayout()
|
|
{
|
|
var layout = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), out var processId));
|
|
return GetLayoutNameFromHKL(layout);
|
|
}
|
|
|
|
public static IntPtr SetKeyboardLayout(string lang)
|
|
{
|
|
var layoutId = (new CultureInfo(lang)).KeyboardLayoutId;
|
|
var layout = LoadKeyboardLayout(layoutId.ToString("x8"), 0x80);
|
|
// Hacky, but tests are probably running in a console app and the layout change
|
|
// is ignored, so post the layout change to the foreground window.
|
|
PostMessage(GetForegroundWindow(), WM_INPUTLANGCHANGEREQUEST, 0, layoutId);
|
|
Thread.Sleep(500);
|
|
return layout;
|
|
}
|
|
}
|
|
|
|
public class ConsoleFixture : IDisposable
|
|
{
|
|
public KeyboardLayout KbLayout { get; private set; }
|
|
public string Lang { get; private set; }
|
|
public string Os { get; private set; }
|
|
|
|
public ConsoleFixture()
|
|
{
|
|
Lang = "";
|
|
Os = "";
|
|
}
|
|
|
|
public void Initialize(string lang, string os)
|
|
{
|
|
if (!string.Equals(lang, Lang) || !string.Equals(os, Os))
|
|
{
|
|
Lang = lang;
|
|
Os = os;
|
|
KbLayout = new KeyboardLayout(lang, "windows");
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return Lang + "-" + Os;
|
|
}
|
|
}
|
|
}
|
|
|