mirror of
https://github.com/osukey/osukey.git
synced 2025-07-01 08:20:00 +09:00
Disable windows key while in gameplay.
This commit is contained in:
82
osu.Desktop/Windows/WindowsKey.cs
Normal file
82
osu.Desktop/Windows/WindowsKey.cs
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace osu.Desktop.Windows
|
||||
{
|
||||
internal class WindowsKey
|
||||
{
|
||||
private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KdDllHookStruct lParam);
|
||||
|
||||
private static bool isBlocked;
|
||||
|
||||
private const int wh_keyboard_ll = 13;
|
||||
private const int wm_keydown = 256;
|
||||
private const int wm_syskeyup = 261;
|
||||
|
||||
//Resharper disable once NotAccessedField.Local
|
||||
private static LowLevelKeyboardProcDelegate keyboardHookDelegate; // keeping a reference alive for the GC
|
||||
private static IntPtr keyHook;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct KdDllHookStruct
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public readonly int VkCode;
|
||||
|
||||
[FieldOffset(8)]
|
||||
public readonly int Flags;
|
||||
}
|
||||
|
||||
private static int lowLevelKeyboardProc(int nCode, int wParam, ref KdDllHookStruct lParam)
|
||||
{
|
||||
if (wParam >= wm_keydown && wParam <= wm_syskeyup)
|
||||
{
|
||||
switch (lParam.VkCode)
|
||||
{
|
||||
case 0x09 when lParam.Flags == 32: // alt + tab
|
||||
case 0x1b when lParam.Flags == 32: // alt + esc
|
||||
case 0x5B: // left windows key
|
||||
case 0x5C: // right windows key
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return callNextHookEx(0, nCode, wParam, ref lParam);
|
||||
}
|
||||
|
||||
internal static void Disable()
|
||||
{
|
||||
if (keyHook != IntPtr.Zero || isBlocked)
|
||||
return;
|
||||
|
||||
keyHook = setWindowsHookEx(wh_keyboard_ll, (keyboardHookDelegate = lowLevelKeyboardProc), Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0);
|
||||
|
||||
isBlocked = true;
|
||||
}
|
||||
|
||||
internal static void Enable()
|
||||
{
|
||||
if (keyHook == IntPtr.Zero || !isBlocked)
|
||||
return;
|
||||
|
||||
keyHook = unhookWindowsHookEx(keyHook);
|
||||
keyboardHookDelegate = null;
|
||||
|
||||
keyHook = IntPtr.Zero;
|
||||
|
||||
isBlocked = false;
|
||||
}
|
||||
|
||||
[DllImport(@"user32.dll", EntryPoint = @"SetWindowsHookExA")]
|
||||
private static extern IntPtr setWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);
|
||||
|
||||
[DllImport(@"user32.dll", EntryPoint = @"UnhookWindowsHookEx")]
|
||||
private static extern IntPtr unhookWindowsHookEx(IntPtr hHook);
|
||||
|
||||
[DllImport(@"user32.dll", EntryPoint = @"CallNextHookEx")]
|
||||
private static extern int callNextHookEx(int hHook, int nCode, int wParam, ref KdDllHookStruct lParam);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user