Add Keyboard Hook mechanism

This commit is contained in:
Noraa Junker
2025-12-01 23:25:10 +01:00
parent 17af826408
commit 9afa3a1ecc
14 changed files with 487 additions and 87 deletions

View File

@@ -0,0 +1,61 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace RunnerV2.Helpers
{
internal static class COMUtils
{
public static void InitializeCOMSecurity(string securityDescriptor)
{
if (!NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptorW(
securityDescriptor,
1,
out IntPtr pSD,
out _))
{
return;
}
uint absoluteSDSize = 0;
uint daclSize = 0;
uint groupSize = 0;
uint ownerSize = 0;
uint saclSize = 0;
if (!NativeMethods.MakeAbsoluteSD(pSD, IntPtr.Zero, ref absoluteSDSize, IntPtr.Zero, ref daclSize, IntPtr.Zero, ref saclSize, IntPtr.Zero, ref ownerSize, IntPtr.Zero, ref groupSize))
{
return;
}
IntPtr absoluteSD = Marshal.AllocHGlobal((int)absoluteSDSize);
IntPtr dacl = Marshal.AllocHGlobal((int)daclSize);
IntPtr sacl = Marshal.AllocHGlobal((int)saclSize);
IntPtr owner = Marshal.AllocHGlobal((int)ownerSize);
IntPtr group = Marshal.AllocHGlobal((int)groupSize);
if (!NativeMethods.MakeAbsoluteSD(pSD, absoluteSD, ref absoluteSDSize, dacl, ref daclSize, sacl, ref saclSize, owner, ref ownerSize, group, ref groupSize))
{
return;
}
_ = NativeMethods.CoInitializeSecurity(
absoluteSD,
-1,
IntPtr.Zero,
IntPtr.Zero,
6, // RPC_C_AUTHN_LEVEL_PKT_PRIVACY
2, // RPC_C_IMP_LEVEL_IDENTIFY
IntPtr.Zero,
64 | 4096, // EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA
IntPtr.Zero);
}
}
}

View File

@@ -0,0 +1,169 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Windows.System;
namespace RunnerV2.Helpers
{
internal static class CentralizedKeyboardHookManager
{
private static readonly UIntPtr _ignoreKeyEventFlag = 0x5555;
private static readonly Dictionary<string, List<(HotkeySettings HotkeySettings, Action Action)>> _keyboardHooks = [];
private static HotkeySettingsControlHook _hotkeySettingsControlHook = new(OnKeyDown, OnKeyUp, IsActive, (_, specialFlags) => specialFlags != _ignoreKeyEventFlag);
private static void OnKeyDown(int key)
{
switch ((VirtualKey)key)
{
case VirtualKey.Control:
case VirtualKey.LeftControl:
case VirtualKey.RightControl:
_ctrlState = true;
break;
case VirtualKey.Menu:
case VirtualKey.LeftMenu:
case VirtualKey.RightMenu:
_altState = true;
break;
case VirtualKey.Shift:
case VirtualKey.LeftShift:
case VirtualKey.RightShift:
_shiftState = true;
break;
case VirtualKey.LeftWindows:
case VirtualKey.RightWindows:
_winState = true;
break;
}
SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyDown);
}
private static void OnKeyUp(int key)
{
switch ((VirtualKey)key)
{
case VirtualKey.Control:
case VirtualKey.LeftControl:
case VirtualKey.RightControl:
_ctrlState = false;
break;
case VirtualKey.Menu:
case VirtualKey.LeftMenu:
case VirtualKey.RightMenu:
_altState = false;
break;
case VirtualKey.Shift:
case VirtualKey.LeftShift:
case VirtualKey.RightShift:
_shiftState = false;
break;
case VirtualKey.LeftWindows:
case VirtualKey.RightWindows:
_winState = false;
break;
default:
OnKeyboardEvent(new HotkeySettings
{
Code = key,
Ctrl = _ctrlState,
Alt = _altState,
Shift = _shiftState,
Win = _winState,
});
break;
}
SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyUp);
}
private static bool _ctrlState;
private static bool _altState;
private static bool _shiftState;
private static bool _winState;
private static bool _isActive;
private static bool IsActive()
{
return _isActive;
}
public static void AddKeyboardHook(string moduleName, HotkeySettings hotkeySettings, Action action)
{
#pragma warning disable CA1854 // Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method
if (!_keyboardHooks.ContainsKey(moduleName))
{
_keyboardHooks[moduleName] = [];
}
#pragma warning restore CA1854 // Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method
_keyboardHooks[moduleName].Add((hotkeySettings, action));
}
public static void RemoveAllHooksFromModule(string moduleName)
{
_keyboardHooks.Remove(moduleName);
}
private static void OnKeyboardEvent(HotkeySettings pressedHotkey)
{
foreach (var moduleHooks in _keyboardHooks.Values)
{
foreach (var (hotkeySettings, action) in moduleHooks)
{
if (hotkeySettings == pressedHotkey)
{
action();
}
}
}
}
public static void Start()
{
if (_hotkeySettingsControlHook.GetDisposedState())
{
_hotkeySettingsControlHook = new(OnKeyDown, OnKeyUp, IsActive, (_, specialFlags) => specialFlags != _ignoreKeyEventFlag);
}
_isActive = true;
}
public static void Stop()
{
_isActive = false;
_hotkeySettingsControlHook.Dispose();
}
// Function to send a single key event to the system which would be ignored by the hotkey control.
private static void SendSingleKeyboardInput(short keyCode, uint keyStatus)
{
NativeKeyboardHelper.INPUT inputShift = new()
{
type = NativeKeyboardHelper.INPUTTYPE.INPUT_KEYBOARD,
data = new NativeKeyboardHelper.InputUnion
{
ki = new NativeKeyboardHelper.KEYBDINPUT
{
wVk = keyCode,
dwFlags = keyStatus,
dwExtraInfo = _ignoreKeyEventFlag,
},
},
};
NativeKeyboardHelper.INPUT[] inputs = [inputShift];
_ = NativeMethods.SendInput(1, inputs, NativeKeyboardHelper.INPUT.Size);
}
}
}

View File

@@ -14,6 +14,7 @@ using System.Threading;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.Interop;
using RunnerV2.ModuleInterfaces;
using Update;
using Windows.Media.Devices;

View File

@@ -0,0 +1,112 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
using PowerToys.GPOWrapper;
using PowerToys.Interop;
namespace RunnerV2.ModuleInterfaces
{
internal sealed class AdvancedPasteModuleInterface : IPowerToysModule, IDisposable
{
public string Name => "AdvancedPaste";
public bool Enabled => new SettingsUtils().GetSettings<GeneralSettings>().Enabled.AdvancedPaste;
public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredAdvancedPasteEnabledValue();
public void Disable()
{
if (_ipc != null)
{
_ipc.Send("TerminateApp");
_ipc.End();
_ipc = null;
}
Task.Run(async () =>
{
await Task.Delay(500);
foreach (var process in Process.GetProcessesByName("PowerToys.AdvancedPaste.exe"))
{
process.Kill();
}
});
}
private TwoWayPipeMessageIPCManaged? _ipc;
public void Enable()
{
if (Process.GetProcessesByName("PowerToys.AdvancedPaste.exe").Length > 0)
{
return;
}
string ipcName = @"\\.\pipe\PowerToys.AdvancedPaste";
_ipc = new TwoWayPipeMessageIPCManaged(string.Empty, ipcName, (_) => { });
_ipc.Start();
if (Shortcuts.Count == 0)
{
PopulateShortcuts();
}
Process.Start("WinUI3Apps\\PowerToys.AdvancedPaste.exe", $"{Environment.ProcessId} {ipcName}");
}
public void OnSettingsChanged()
{
PopulateShortcuts();
}
public void PopulateShortcuts()
{
ArgumentNullException.ThrowIfNull(_ipc);
Shortcuts.Clear();
AdvancedPasteSettings settings = new SettingsUtils().GetSettings<AdvancedPasteSettings>();
Shortcuts.Add((settings.Properties.AdvancedPasteUIShortcut, () =>
_ipc.Send("ShowUI")
));
Shortcuts.Add((settings.Properties.PasteAsPlainTextShortcut, TryToPasteAsPlainText));
Shortcuts.Add((settings.Properties.PasteAsMarkdownShortcut, () => _ipc.Send("PasteMarkdown")));
Shortcuts.Add((settings.Properties.PasteAsJsonShortcut, () => _ipc.Send("PasteJson")));
HotkeyAccessor[] hotkeyAccessors = settings.GetAllHotkeyAccessors();
for (int i = 4; i < hotkeyAccessors.Length; i++)
{
HotkeyAccessor hotkeyAccessor = hotkeyAccessors[i];
Shortcuts.Add((hotkeyAccessor.Value, () => _ipc.Send($"CustomPaste {i}")));
}
}
private void TryToPasteAsPlainText()
{
if (Clipboard.ContainsText())
{
string text = Clipboard.GetText();
SendKeys.SendWait(text);
}
throw new NotImplementedException();
}
public void Dispose()
{
_ipc?.Dispose();
}
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = [];
}
}

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.GPOWrapper;

View File

@@ -5,9 +5,11 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.GPOWrapper;
namespace ManagedCommon
namespace RunnerV2.ModuleInterfaces
{
public interface IPowerToysModule
{
@@ -23,6 +25,8 @@ namespace ManagedCommon
public Dictionary<HotkeyEx, Action> Hotkeys { get => []; }
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get => []; }
public Dictionary<string, Action> CustomActions { get => []; }
public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties)

View File

@@ -3,13 +3,8 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.GPOWrapper;

View File

@@ -5,6 +5,7 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using Microsoft.PowerToys.Settings.UI.Helpers;
namespace RunnerV2
{
@@ -186,5 +187,48 @@ namespace RunnerV2
[MarshalAs(UnmanagedType.LPWStr)]
public string LpszClassName;
}
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
internal delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("Advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptorW(
[MarshalAs(UnmanagedType.LPWStr)] string StringSecurityDescriptor,
uint StringSDRevision,
out IntPtr SecurityDescriptor,
out uint SecurityDescriptorSize);
[DllImport("Advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool MakeAbsoluteSD(
IntPtr pSelfRelativeSD,
IntPtr pAbsoluteSD,
ref uint lpdwAbsoluteSDSize,
IntPtr pDacl,
ref uint lpdwDaclSize,
IntPtr pSacl,
ref uint lpdwSaclSize,
IntPtr pOwner,
ref uint lpdwOwnerSize,
IntPtr pPrimaryGroup,
ref uint lpdwPrimaryGroupSize);
[DllImport("ole32.dll", SetLastError = true)]
internal static extern int CoInitializeSecurity(
IntPtr pSecDesc,
int cAuthSvc,
IntPtr asAuthSvc,
IntPtr pReserved1,
uint dwAuthnLevel,
uint dwImpLevel,
IntPtr pAuthList,
uint dwCapabilities,
IntPtr pReserved3);
[DllImport("user32.dll")]
internal static extern uint SendInput(uint nInputs, NativeKeyboardHelper.INPUT[] pInputs, int cbSize);
}
}

View File

@@ -22,6 +22,20 @@ internal sealed class Program
private static void Main(string[] args)
{
string securityDescriptor =
"O:BA" // Owner: Builtin (local) administrator
+ "G:BA" // Group: Builtin (local) administrator
+ "D:"
+ "(A;;0x7;;;PS)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Personal self
+ "(A;;0x7;;;IU)" // Access allowed on COM_RIGHTS_EXECUTE for Interactive Users
+ "(A;;0x3;;;SY)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Local system
+ "(A;;0x7;;;BA)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Builtin (local) administrator
+ "(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability
+ "S:"
+ "(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level
COMUtils.InitializeCOMSecurity(securityDescriptor);
switch (ShouldRunInSpecialMode(args))
{
case SpecialMode.None:

View File

@@ -15,8 +15,8 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ManagedCommon;
using RunnerV2.Helpers;
using RunnerV2.ModuleInterfaces;
using Update;
using static RunnerV2.NativeMethods;
@@ -28,11 +28,6 @@ namespace RunnerV2
private const string TrayWindowClassName = "pt_tray_icon_window_class";
static Runner()
{
InitializeTrayWindow();
}
public static List<IPowerToysModule> LoadedModules { get; } = [];
public static FrozenSet<IPowerToysModule> ModulesToLoad { get; } =
@@ -40,10 +35,12 @@ namespace RunnerV2
new ModuleInterfaces.AlwaysOnTopModuleInterface(),
new ModuleInterfaces.HostsModuleInterface(),
new ModuleInterfaces.PowerAccentModuleInterface(),
new ModuleInterfaces.AdvancedPasteModuleInterface(),
];
internal static bool Run(Action afterInitializationAction)
{
InitializeTrayWindow();
TrayIconManager.StartTrayIcon();
Task.Run(UpdateUtilities.UninstallPreviousMsixVersions);
@@ -53,6 +50,8 @@ namespace RunnerV2
ToggleModuleStateBasedOnEnabledProperty(module);
}
CentralizedKeyboardHookManager.Start();
afterInitializationAction();
MessageLoop();
@@ -116,16 +115,23 @@ namespace RunnerV2
{
/* Todo: conflict manager */
if (!LoadedModules.Contains(module))
{
module.Enable();
LoadedModules.Add(module);
}
// ToArray is called to mitigate mutations while the foreach is executing
foreach (var hotkey in module.Hotkeys.ToArray())
{
HotkeyManager.EnableHotkey(hotkey.Key, hotkey.Value);
}
if (!LoadedModules.Contains(module))
CentralizedKeyboardHookManager.RemoveAllHooksFromModule(module.Name);
foreach (var shortcut in module.Shortcuts.ToArray())
{
module.Enable();
LoadedModules.Add(module);
CentralizedKeyboardHookManager.AddKeyboardHook(module.Name, shortcut.Hotkey, shortcut.Action);
}
return;
@@ -149,6 +155,8 @@ namespace RunnerV2
HotkeyManager.DisableHotkey(hotkey.Key);
}
CentralizedKeyboardHookManager.RemoveAllHooksFromModule(module.Name);
LoadedModules.Remove(module);
}
catch (IOException)

View File

@@ -16,6 +16,7 @@
<ItemGroup>
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
<ProjectReference Include="..\..\settings-ui\Settings.UI\PowerToys.Settings.csproj" />
<ProjectReference Include="..\..\Update\Update.csproj" />
</ItemGroup>
</Project>

View File

@@ -25,13 +25,6 @@
<DefineConstants>DISABLE_XAML_GENERATED_MAIN,TRACE</DefineConstants>
</PropertyGroup>
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
<PropertyGroup>
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
</PropertyGroup>
<ItemGroup>
<None Remove="AdvancedPasteXAML\Controls\ClipboardHistoryItemPreviewControl.xaml" />
<None Remove="AdvancedPasteXAML\Controls\PromptBox.xaml" />
@@ -108,9 +101,9 @@
<ItemGroup>
<!-- HACK: Common.UI is referenced, even if it is not used, to force dll versions to be the same as in other projects that use it. It's still unclear why this is the case, but this is need for flattening the install directory. -->
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
<ProjectReference Include="..\..\..\common\GPOWrapperProjection\GPOWrapperProjection.csproj" />
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\..\common\LanguageModelProvider\LanguageModelProvider.csproj" />
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
<ProjectReference Include="..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
</ItemGroup>

View File

@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO.Abstractions;
using System.Linq;
@@ -22,6 +23,7 @@ using Microsoft.Extensions.Hosting;
using Microsoft.PowerToys.Telemetry;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using PowerToys.Interop;
using Windows.Graphics;
using WinUIEx;
@@ -132,47 +134,44 @@ namespace AdvancedPaste
if (cmdArgs?.Length > 2)
{
ProcessNamedPipe(cmdArgs[2]);
TwoWayPipeMessageIPCManaged ipc = new(cmdArgs[2], string.Empty, async (m) => await OnNamedPipeMessage(m));
ipc.Start();
}
}
private void ProcessNamedPipe(string pipeName)
{
void OnMessage(string message) => _dispatcherQueue.TryEnqueue(async () => await OnNamedPipeMessage(message));
Task.Run(async () => await NamedPipeProcessor.ProcessNamedPipeAsync(pipeName, connectTimeout: TimeSpan.FromSeconds(10), OnMessage, CancellationToken.None));
}
private async Task OnNamedPipeMessage(string message)
{
var messageParts = message.Split();
var messageType = messageParts.First();
_dispatcherQueue.TryEnqueue(async () =>
{
var messageParts = message.Split();
var messageType = messageParts.First();
if (messageType == PowerToys.Interop.Constants.AdvancedPasteShowUIMessage())
{
await ShowWindow();
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteMarkdownMessage())
{
await viewModel.ExecutePasteFormatAsync(PasteFormats.Markdown, PasteActionSource.GlobalKeyboardShortcut);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteJsonMessage())
{
await viewModel.ExecutePasteFormatAsync(PasteFormats.Json, PasteActionSource.GlobalKeyboardShortcut);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteAdditionalActionMessage())
{
await OnAdvancedPasteAdditionalActionHotkey(messageParts);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteCustomActionMessage())
{
await OnAdvancedPasteCustomActionHotkey(messageParts);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteTerminateAppMessage())
{
Dispose();
Environment.Exit(0);
}
if (messageType == PowerToys.Interop.Constants.AdvancedPasteShowUIMessage())
{
await ShowWindow();
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteMarkdownMessage())
{
await viewModel.ExecutePasteFormatAsync(PasteFormats.Markdown, PasteActionSource.GlobalKeyboardShortcut);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteJsonMessage())
{
await viewModel.ExecutePasteFormatAsync(PasteFormats.Json, PasteActionSource.GlobalKeyboardShortcut);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteAdditionalActionMessage())
{
await OnAdvancedPasteAdditionalActionHotkey(messageParts);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteCustomActionMessage())
{
await OnAdvancedPasteCustomActionHotkey(messageParts);
}
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteTerminateAppMessage())
{
Dispose();
Environment.Exit(0);
}
});
}
private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)

View File

@@ -7,16 +7,16 @@ using System.Runtime.InteropServices;
namespace Microsoft.PowerToys.Settings.UI.Helpers
{
internal static class NativeKeyboardHelper
public static class NativeKeyboardHelper
{
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct INPUT
public struct INPUT
{
internal INPUTTYPE type;
internal InputUnion data;
public INPUTTYPE type;
public InputUnion data;
internal static int Size
public static int Size
{
get { return Marshal.SizeOf<INPUT>(); }
}
@@ -24,49 +24,49 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
[StructLayout(LayoutKind.Explicit)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct InputUnion
public struct InputUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
public MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
public KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct MOUSEINPUT
public struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal uint dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
public int dx;
public int dy;
public int mouseData;
public uint dwFlags;
public uint time;
public UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct KEYBDINPUT
public struct KEYBDINPUT
{
internal short wVk;
internal short wScan;
internal uint dwFlags;
internal int time;
internal UIntPtr dwExtraInfo;
public short wVk;
public short wScan;
public uint dwFlags;
public int time;
public UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct HARDWAREINPUT
public struct HARDWAREINPUT
{
internal int uMsg;
internal short wParamL;
internal short wParamH;
public int uMsg;
public short wParamL;
public short wParamH;
}
internal enum INPUTTYPE : uint
public enum INPUTTYPE : uint
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
@@ -74,7 +74,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
}
[Flags]
internal enum KeyEventF
public enum KeyEventF
{
KeyDown = 0x0000,
ExtendedKey = 0x0001,