mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
706 lines
26 KiB
C#
706 lines
26 KiB
C#
|
|
// 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.
|
|||
|
|
|
|||
|
|
// <summary>
|
|||
|
|
// Keyboard/Mouse hook callbacks, pre-process before calling to routines in Common.Event.
|
|||
|
|
// </summary>
|
|||
|
|
// <history>
|
|||
|
|
// 2008 created by Truong Do (ductdo).
|
|||
|
|
// 2009-... modified by Truong Do (TruongDo).
|
|||
|
|
// 2023- Included in PowerToys.
|
|||
|
|
// </history>
|
|||
|
|
using System;
|
|||
|
|
using System.Diagnostics.CodeAnalysis;
|
|||
|
|
using System.Globalization;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Runtime.InteropServices;
|
|||
|
|
using System.Windows.Forms;
|
|||
|
|
|
|||
|
|
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.InputHook.#MouseHookProc(System.Int32,System.Int32,System.IntPtr)", Justification = "Dotnet port with style preservation")]
|
|||
|
|
[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "MouseWithoutBorders.InputHook.#ProcessKeyEx(System.Int32,System.Int32)", Justification = "Dotnet port with style preservation")]
|
|||
|
|
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.InputHook.#Start()", Justification = "Dotnet port with style preservation")]
|
|||
|
|
|
|||
|
|
namespace MouseWithoutBorders.Class
|
|||
|
|
{
|
|||
|
|
internal class InputHook
|
|||
|
|
{
|
|||
|
|
internal delegate void MouseEvHandler(MOUSEDATA e, int dx, int dy);
|
|||
|
|
|
|||
|
|
internal delegate void KeybdEvHandler(KEYBDDATA e);
|
|||
|
|
|
|||
|
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
|
private struct MouseHookStruct
|
|||
|
|
{
|
|||
|
|
internal NativeMethods.POINT Pt;
|
|||
|
|
internal int Hwnd;
|
|||
|
|
internal int WHitTestCode;
|
|||
|
|
internal int DwExtraInfo;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// http://msdn.microsoft.com/en-us/library/ms644970(VS.85).aspx
|
|||
|
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
|
private struct MouseLLHookStruct
|
|||
|
|
{
|
|||
|
|
internal NativeMethods.POINT Pt;
|
|||
|
|
internal int MouseData;
|
|||
|
|
internal int Flags;
|
|||
|
|
internal int Time;
|
|||
|
|
internal int DwExtraInfo;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
|
private struct KeyboardHookStruct
|
|||
|
|
{
|
|||
|
|
internal int VkCode;
|
|||
|
|
internal int ScanCode;
|
|||
|
|
internal int Flags;
|
|||
|
|
internal int Time;
|
|||
|
|
internal int DwExtraInfo;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal event MouseEvHandler MouseEvent;
|
|||
|
|
|
|||
|
|
internal event KeybdEvHandler KeyboardEvent;
|
|||
|
|
|
|||
|
|
private int hMouseHook;
|
|||
|
|
private int hKeyboardHook;
|
|||
|
|
private static NativeMethods.HookProc mouseHookProcedure;
|
|||
|
|
private static NativeMethods.HookProc keyboardHookProcedure;
|
|||
|
|
|
|||
|
|
private static MouseLLHookStruct mouseHookStruct;
|
|||
|
|
private static KeyboardHookStruct keyboardHookStruct;
|
|||
|
|
private static MOUSEDATA hookCallbackMouseData;
|
|||
|
|
private static KEYBDDATA hookCallbackKeybdData;
|
|||
|
|
|
|||
|
|
private static bool winDown;
|
|||
|
|
private static bool altDown;
|
|||
|
|
private static bool shiftDown;
|
|||
|
|
|
|||
|
|
internal static bool RealData { get; set; } = true;
|
|||
|
|
|
|||
|
|
internal static int SkipMouseUpCount { get; set; }
|
|||
|
|
|
|||
|
|
internal static bool SkipMouseUpDown { get; set; }
|
|||
|
|
|
|||
|
|
internal static bool CtrlDown { get; private set; }
|
|||
|
|
|
|||
|
|
internal static bool EasyMouseKeyDown { get; set; }
|
|||
|
|
|
|||
|
|
internal InputHook()
|
|||
|
|
{
|
|||
|
|
Start();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
~InputHook()
|
|||
|
|
{
|
|||
|
|
Stop();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal void Start()
|
|||
|
|
{
|
|||
|
|
int le;
|
|||
|
|
bool er = false;
|
|||
|
|
|
|||
|
|
// Install Mouse Hook
|
|||
|
|
mouseHookProcedure = new NativeMethods.HookProc(MouseHookProc);
|
|||
|
|
hMouseHook = NativeMethods.SetWindowsHookEx(
|
|||
|
|
Common.WH_MOUSE_LL,
|
|||
|
|
mouseHookProcedure,
|
|||
|
|
Marshal.GetHINSTANCE(
|
|||
|
|
Assembly.GetExecutingAssembly().GetModules()[0]),
|
|||
|
|
0);
|
|||
|
|
|
|||
|
|
if (hMouseHook == 0)
|
|||
|
|
{
|
|||
|
|
le = Marshal.GetLastWin32Error();
|
|||
|
|
Common.Log("Error installing Mouse hook: " + le.ToString(CultureInfo.CurrentCulture));
|
|||
|
|
er = true;
|
|||
|
|
Stop();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Install Keyboard Hook
|
|||
|
|
keyboardHookProcedure = new NativeMethods.HookProc(KeyboardHookProc);
|
|||
|
|
hKeyboardHook = NativeMethods.SetWindowsHookEx(
|
|||
|
|
Common.WH_KEYBOARD_LL,
|
|||
|
|
keyboardHookProcedure,
|
|||
|
|
Marshal.GetHINSTANCE(
|
|||
|
|
Assembly.GetExecutingAssembly().GetModules()[0]),
|
|||
|
|
0);
|
|||
|
|
if (hKeyboardHook == 0)
|
|||
|
|
{
|
|||
|
|
le = Marshal.GetLastWin32Error();
|
|||
|
|
Common.Log("Error installing keyboard hook: " + le.ToString(CultureInfo.CurrentCulture));
|
|||
|
|
er = true;
|
|||
|
|
Stop();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (er)
|
|||
|
|
{
|
|||
|
|
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
|||
|
|
{
|
|||
|
|
_ = MessageBox.Show(
|
|||
|
|
"Error installing keyboard/Mouse hook!",
|
|||
|
|
Application.ProductName,
|
|||
|
|
MessageBoxButtons.OK,
|
|||
|
|
MessageBoxIcon.Error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Common.InitLastInputEventCount();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal void Stop()
|
|||
|
|
{
|
|||
|
|
if (hMouseHook != 0)
|
|||
|
|
{
|
|||
|
|
int retMouse = NativeMethods.UnhookWindowsHookEx(hMouseHook);
|
|||
|
|
hMouseHook = 0;
|
|||
|
|
if (retMouse == 0)
|
|||
|
|
{
|
|||
|
|
int errorCode = Marshal.GetLastWin32Error();
|
|||
|
|
|
|||
|
|
// throw new Win32Exception(errorCode);
|
|||
|
|
Common.Log("Exception uninstalling Mouse hook, error code: " + errorCode.ToString(CultureInfo.CurrentCulture));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (hKeyboardHook != 0)
|
|||
|
|
{
|
|||
|
|
int retKeyboard = NativeMethods.UnhookWindowsHookEx(hKeyboardHook);
|
|||
|
|
hKeyboardHook = 0;
|
|||
|
|
if (retKeyboard == 0)
|
|||
|
|
{
|
|||
|
|
int errorCode = Marshal.GetLastWin32Error();
|
|||
|
|
|
|||
|
|
// throw new Win32Exception(errorCode);
|
|||
|
|
Common.Log("Exception uninstalling keyboard hook, error code: " + errorCode.ToString(CultureInfo.CurrentCulture));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Better performance, compared to Marshal.PtrToStructure.
|
|||
|
|
private static MouseLLHookStruct LParamToMouseLLHookStruct(IntPtr lParam)
|
|||
|
|
{
|
|||
|
|
unsafe
|
|||
|
|
{
|
|||
|
|
return *(MouseLLHookStruct*)lParam;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static KeyboardHookStruct LParamToKeyboardHookStruct(IntPtr lParam)
|
|||
|
|
{
|
|||
|
|
unsafe
|
|||
|
|
{
|
|||
|
|
return *(KeyboardHookStruct*)lParam;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
|
|||
|
|
{
|
|||
|
|
int rv = 1, dx = 0, dy = 0;
|
|||
|
|
bool local = false;
|
|||
|
|
Common.InputEventCount++;
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (!RealData)
|
|||
|
|
{
|
|||
|
|
RealData = true;
|
|||
|
|
|
|||
|
|
// Common.Log("MouseHookProc: Not real data!");
|
|||
|
|
// return rv;
|
|||
|
|
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Common.RealInputEventCount++;
|
|||
|
|
|
|||
|
|
if (Common.NewDesMachineID == Common.MachineID || Common.NewDesMachineID == ID.ALL)
|
|||
|
|
{
|
|||
|
|
local = true;
|
|||
|
|
if (Common.MainFormVisible && !Common.IsDropping)
|
|||
|
|
{
|
|||
|
|
Common.MainFormDot();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (nCode >= 0 && MouseEvent != null)
|
|||
|
|
{
|
|||
|
|
if (wParam == Common.WM_LBUTTONUP && SkipMouseUpCount > 0)
|
|||
|
|
{
|
|||
|
|
Common.LogDebug($"{nameof(SkipMouseUpCount)}: {SkipMouseUpCount}.");
|
|||
|
|
SkipMouseUpCount--;
|
|||
|
|
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
|
|||
|
|
return rv;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ((wParam == Common.WM_LBUTTONUP || wParam == Common.WM_LBUTTONDOWN) && SkipMouseUpDown)
|
|||
|
|
{
|
|||
|
|
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
|
|||
|
|
return rv;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
mouseHookStruct = LParamToMouseLLHookStruct(lParam);
|
|||
|
|
hookCallbackMouseData.dwFlags = wParam;
|
|||
|
|
|
|||
|
|
// Use WheelDelta to store XBUTTON1/XBUTTON2 data.
|
|||
|
|
hookCallbackMouseData.WheelDelta = (short)((mouseHookStruct.MouseData >> 16) & 0xffff);
|
|||
|
|
|
|||
|
|
if (local)
|
|||
|
|
{
|
|||
|
|
hookCallbackMouseData.X = mouseHookStruct.Pt.x;
|
|||
|
|
hookCallbackMouseData.Y = mouseHookStruct.Pt.y;
|
|||
|
|
|
|||
|
|
if (Setting.Values.DrawMouse && Common.MouseCursorForm != null)
|
|||
|
|
{
|
|||
|
|
CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (Common.SwitchLocation.Count > 0 && Common.NewDesMachineID != Common.MachineID && Common.NewDesMachineID != ID.ALL)
|
|||
|
|
{
|
|||
|
|
Common.SwitchLocation.Count--;
|
|||
|
|
|
|||
|
|
if (Common.SwitchLocation.X > Common.XY_BY_PIXEL - 100000 || Common.SwitchLocation.Y > Common.XY_BY_PIXEL - 100000)
|
|||
|
|
{
|
|||
|
|
hookCallbackMouseData.X = Common.SwitchLocation.X - Common.XY_BY_PIXEL;
|
|||
|
|
hookCallbackMouseData.Y = Common.SwitchLocation.Y - Common.XY_BY_PIXEL;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
hookCallbackMouseData.X = (Common.SwitchLocation.X * Common.ScreenWidth / 65535) + Common.PrimaryScreenBounds.Left;
|
|||
|
|
hookCallbackMouseData.Y = (Common.SwitchLocation.Y * Common.ScreenHeight / 65535) + Common.PrimaryScreenBounds.Top;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Common.HideMouseCursor(false);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
dx = mouseHookStruct.Pt.x - Common.LastPos.X;
|
|||
|
|
dy = mouseHookStruct.Pt.y - Common.LastPos.Y;
|
|||
|
|
|
|||
|
|
hookCallbackMouseData.X += dx;
|
|||
|
|
hookCallbackMouseData.Y += dy;
|
|||
|
|
|
|||
|
|
if (hookCallbackMouseData.X < Common.PrimaryScreenBounds.Left)
|
|||
|
|
{
|
|||
|
|
hookCallbackMouseData.X = Common.PrimaryScreenBounds.Left - 1;
|
|||
|
|
}
|
|||
|
|
else if (hookCallbackMouseData.X > Common.PrimaryScreenBounds.Right)
|
|||
|
|
{
|
|||
|
|
hookCallbackMouseData.X = Common.PrimaryScreenBounds.Right + 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (hookCallbackMouseData.Y < Common.PrimaryScreenBounds.Top)
|
|||
|
|
{
|
|||
|
|
hookCallbackMouseData.Y = Common.PrimaryScreenBounds.Top - 1;
|
|||
|
|
}
|
|||
|
|
else if (hookCallbackMouseData.Y > Common.PrimaryScreenBounds.Bottom)
|
|||
|
|
{
|
|||
|
|
hookCallbackMouseData.Y = Common.PrimaryScreenBounds.Bottom + 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dx += dx < 0 ? -Common.MOVE_MOUSE_RELATIVE : Common.MOVE_MOUSE_RELATIVE;
|
|||
|
|
dy += dy < 0 ? -Common.MOVE_MOUSE_RELATIVE : Common.MOVE_MOUSE_RELATIVE;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
MouseEvent(hookCallbackMouseData, dx, dy);
|
|||
|
|
|
|||
|
|
Common.DragDropStep01(wParam);
|
|||
|
|
Common.DragDropStep09(wParam);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (local)
|
|||
|
|
{
|
|||
|
|
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception e)
|
|||
|
|
{
|
|||
|
|
Common.Log(e);
|
|||
|
|
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return rv;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam)
|
|||
|
|
{
|
|||
|
|
Common.InputEventCount++;
|
|||
|
|
if (!RealData)
|
|||
|
|
{
|
|||
|
|
return NativeMethods.CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Common.RealInputEventCount++;
|
|||
|
|
|
|||
|
|
keyboardHookStruct = LParamToKeyboardHookStruct(lParam);
|
|||
|
|
hookCallbackKeybdData.dwFlags = keyboardHookStruct.Flags;
|
|||
|
|
hookCallbackKeybdData.wVk = (short)keyboardHookStruct.VkCode;
|
|||
|
|
|
|||
|
|
if (nCode >= 0 && KeyboardEvent != null)
|
|||
|
|
{
|
|||
|
|
if (!ProcessKeyEx(keyboardHookStruct.VkCode, keyboardHookStruct.Flags, hookCallbackKeybdData))
|
|||
|
|
{
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Common.DesMachineID == ID.NONE || Common.DesMachineID == ID.ALL || Common.DesMachineID == Common.MachineID)
|
|||
|
|
{
|
|||
|
|
if (nCode >= 0 && Setting.Values.UseVKMap && Setting.Values.VKMap != null && Setting.Values.VKMap.ContainsKey(hookCallbackKeybdData.wVk) && !CtrlDown)
|
|||
|
|
{
|
|||
|
|
InputSimulation.SendKey(hookCallbackKeybdData);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return NativeMethods.CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Returns false if we do not want to redirect the keystrokes to other machine(s).
|
|||
|
|
private int ctrlTouchesDnIndex;
|
|||
|
|
|
|||
|
|
private int ctrlTouchesUpIndex = 1;
|
|||
|
|
private const int CONTROL_TOUCH = 4;
|
|||
|
|
private readonly long[] ctrlTouches = new long[CONTROL_TOUCH];
|
|||
|
|
|
|||
|
|
private bool ProcessKeyEx(int vkCode, int flags, KEYBDDATA hookCallbackKeybdData)
|
|||
|
|
{
|
|||
|
|
bool allTouched;
|
|||
|
|
|
|||
|
|
if ((flags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)
|
|||
|
|
{
|
|||
|
|
EasyMouseKeyDown = false;
|
|||
|
|
|
|||
|
|
switch ((VK)vkCode)
|
|||
|
|
{
|
|||
|
|
case VK.LWIN:
|
|||
|
|
case VK.RWIN:
|
|||
|
|
winDown = false;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.LCONTROL:
|
|||
|
|
case VK.RCONTROL:
|
|||
|
|
CtrlDown = false;
|
|||
|
|
|
|||
|
|
if (Setting.Values.HotKeySwitch2AllPC == 1)
|
|||
|
|
{
|
|||
|
|
ctrlTouches[ctrlTouchesUpIndex] = Common.GetTick();
|
|||
|
|
ctrlTouchesUpIndex = ((ctrlTouchesUpIndex % CONTROL_TOUCH) + 2) % CONTROL_TOUCH;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.LMENU:
|
|||
|
|
case VK.RMENU:
|
|||
|
|
altDown = false;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.LSHIFT:
|
|||
|
|
shiftDown = false;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
UpdateEasyMouseKeyDown((VK)vkCode);
|
|||
|
|
|
|||
|
|
switch ((VK)vkCode)
|
|||
|
|
{
|
|||
|
|
case VK.LWIN:
|
|||
|
|
case VK.RWIN:
|
|||
|
|
winDown = true;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.LCONTROL:
|
|||
|
|
case VK.RCONTROL:
|
|||
|
|
Common.LogDebug("VK.RCONTROL");
|
|||
|
|
CtrlDown = true;
|
|||
|
|
|
|||
|
|
if (Setting.Values.HotKeySwitch2AllPC == 1)
|
|||
|
|
{
|
|||
|
|
ctrlTouches[ctrlTouchesDnIndex] = Common.GetTick();
|
|||
|
|
ctrlTouchesDnIndex = (ctrlTouchesDnIndex + 2) % CONTROL_TOUCH;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
allTouched = true;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < CONTROL_TOUCH; i++)
|
|||
|
|
{
|
|||
|
|
if (ctrlTouches[i] == 0 || Common.GetTick() - ctrlTouches[i] > 400)
|
|||
|
|
{
|
|||
|
|
allTouched = false;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (allTouched && Common.GetTick() - Common.JustGotAKey > 1000)
|
|||
|
|
{
|
|||
|
|
ResetLastSwitchKeys();
|
|||
|
|
Common.SwitchToMultipleMode(Common.DesMachineID != ID.ALL, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.LMENU:
|
|||
|
|
case VK.RMENU:
|
|||
|
|
altDown = true;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.LSHIFT:
|
|||
|
|
shiftDown = true;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.DELETE:
|
|||
|
|
if (CtrlDown && altDown)
|
|||
|
|
{
|
|||
|
|
CtrlDown = altDown = false;
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
|
|||
|
|
if (Common.DesMachineID != ID.ALL)
|
|||
|
|
{
|
|||
|
|
Common.SwitchToMachine(Common.MachineName.Trim());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
#if CUSTOMIZE_LOGON_SCREEN
|
|||
|
|
Common.DoSomethingInUIThread(delegate()
|
|||
|
|
{
|
|||
|
|
Common.MainForm.LoadNewLogonBackground();
|
|||
|
|
});
|
|||
|
|
#endif
|
|||
|
|
* */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case (VK)'L':
|
|||
|
|
if (winDown)
|
|||
|
|
{
|
|||
|
|
winDown = false;
|
|||
|
|
|
|||
|
|
if (Common.DesMachineID != ID.ALL)
|
|||
|
|
{
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
Common.SwitchToMachine(Common.MachineName.Trim());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return ProcessHotKeys(vkCode, hookCallbackKeybdData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case VK.ESCAPE:
|
|||
|
|
if (Common.IsTopMostMessageNotNull())
|
|||
|
|
{
|
|||
|
|
Common.HideTopMostMessage();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
Common.LogDebug("X");
|
|||
|
|
return ProcessHotKeys(vkCode, hookCallbackKeybdData);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateEasyMouseKeyDown(VK vkCode)
|
|||
|
|
{
|
|||
|
|
EasyMouseOption easyMouseOption = (EasyMouseOption)Setting.Values.EasyMouse;
|
|||
|
|
|
|||
|
|
EasyMouseKeyDown = (easyMouseOption == EasyMouseOption.Ctrl && (vkCode == VK.LCONTROL || vkCode == VK.RCONTROL))
|
|||
|
|
|| (easyMouseOption == EasyMouseOption.Shift && (vkCode == VK.LSHIFT || vkCode == VK.RSHIFT));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static long lastHotKeyLockMachine;
|
|||
|
|
|
|||
|
|
private bool ProcessHotKeys(int vkCode, KEYBDDATA hookCallbackKeybdData)
|
|||
|
|
{
|
|||
|
|
if (vkCode == Setting.Values.HotKeyCaptureScreen && CtrlDown && shiftDown && !altDown &&
|
|||
|
|
(Common.DesMachineID == Common.MachineID || Common.DesMachineID == ID.ALL))
|
|||
|
|
{
|
|||
|
|
CtrlDown = shiftDown = false;
|
|||
|
|
|
|||
|
|
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
|||
|
|
{
|
|||
|
|
Common.PrepareScreenCapture();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (CtrlDown && altDown)
|
|||
|
|
{
|
|||
|
|
if (shiftDown && vkCode == Setting.Values.HotKeyExitMM &&
|
|||
|
|
(Common.DesMachineID == Common.MachineID || Common.DesMachineID == ID.ALL))
|
|||
|
|
{
|
|||
|
|
Common.DoSomethingInUIThread(() =>
|
|||
|
|
{
|
|||
|
|
Common.MainForm.NotifyIcon.Visible = false;
|
|||
|
|
|
|||
|
|
for (int i = 1; i < 10; i++)
|
|||
|
|
{
|
|||
|
|
Application.DoEvents();
|
|||
|
|
Thread.Sleep(20);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Common.MainForm.Quit(false, false);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
else if (vkCode == Setting.Values.HotKeySwitchMachine ||
|
|||
|
|
vkCode == Setting.Values.HotKeySwitchMachine + 1 ||
|
|||
|
|
vkCode == Setting.Values.HotKeySwitchMachine + 2 ||
|
|||
|
|
vkCode == Setting.Values.HotKeySwitchMachine + 3)
|
|||
|
|
{
|
|||
|
|
if (Switch2(vkCode - Setting.Values.HotKeySwitchMachine))
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (vkCode == Setting.Values.HotKeyLockMachine)
|
|||
|
|
{
|
|||
|
|
if (!Common.RunOnLogonDesktop
|
|||
|
|
&& !Common.RunOnScrSaverDesktop)
|
|||
|
|
{
|
|||
|
|
if (Common.GetTick() - lastHotKeyLockMachine < 500)
|
|||
|
|
{
|
|||
|
|
Common.SwitchToMultipleMode(true, true);
|
|||
|
|
|
|||
|
|
hookCallbackKeybdData.wVk = (short)VK.LCONTROL;
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
hookCallbackKeybdData.wVk = (short)VK.LMENU;
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
hookCallbackKeybdData.wVk = vkCode;
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
|
|||
|
|
hookCallbackKeybdData.dwFlags |= (int)Common.LLKHF.UP;
|
|||
|
|
|
|||
|
|
hookCallbackKeybdData.wVk = (short)VK.LCONTROL;
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
hookCallbackKeybdData.wVk = (short)VK.LMENU;
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
hookCallbackKeybdData.wVk = vkCode;
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
|
|||
|
|
Common.SwitchToMultipleMode(false, true);
|
|||
|
|
|
|||
|
|
_ = NativeMethods.LockWorkStation();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
KeyboardEvent(hookCallbackKeybdData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
lastHotKeyLockMachine = Common.GetTick();
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (vkCode == Setting.Values.HotKeyReconnect)
|
|||
|
|
{
|
|||
|
|
Common.ShowToolTip("Reconnecting...", 2000);
|
|||
|
|
Common.LastReconnectByHotKeyTime = Common.GetTick();
|
|||
|
|
Common.PleaseReopenSocket = Common.REOPEN_WHEN_HOTKEY;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
else if (vkCode == Setting.Values.HotKeySwitch2AllPC)
|
|||
|
|
{
|
|||
|
|
Common.SwitchToMultipleMode(Common.DesMachineID != ID.ALL, true);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
else if (vkCode == Setting.Values.HotKeyToggleEasyMouse)
|
|||
|
|
{
|
|||
|
|
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
|||
|
|
{
|
|||
|
|
EasyMouseOption easyMouseOption = (EasyMouseOption)Setting.Values.EasyMouse;
|
|||
|
|
|
|||
|
|
if (easyMouseOption is EasyMouseOption.Disable or EasyMouseOption.Enable)
|
|||
|
|
{
|
|||
|
|
Setting.Values.EasyMouse = (int)(easyMouseOption == EasyMouseOption.Disable ? EasyMouseOption.Enable : EasyMouseOption.Disable);
|
|||
|
|
|
|||
|
|
Common.ShowToolTip($"Easy Mouse has been toggled to [{(EasyMouseOption)Setting.Values.EasyMouse}] by a hotkey. You can change the hotkey in the Settings form.", 5000);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (shiftDown && Setting.Values.VKMap != null && vkCode == (Setting.Values.VKMap.ContainsKey(0) ? (int)Setting.Values.VKMap[0] : 'K'))
|
|||
|
|
{
|
|||
|
|
if (Common.DesMachineID == Common.MachineID || Common.DesMachineID == ID.ALL)
|
|||
|
|
{
|
|||
|
|
Setting.Values.UseVKMap = !Setting.Values.UseVKMap;
|
|||
|
|
return Common.DesMachineID == ID.ALL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static bool Switch2(int index)
|
|||
|
|
{
|
|||
|
|
if (Common.MachineMatrix != null && Common.MachineMatrix.Length > index)
|
|||
|
|
{
|
|||
|
|
string mcName = Common.MachineMatrix[index].Trim();
|
|||
|
|
if (!string.IsNullOrEmpty(mcName))
|
|||
|
|
{
|
|||
|
|
// Common.DoSomethingInUIThread(delegate()
|
|||
|
|
{
|
|||
|
|
Common.ReleaseAllKeys();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// );
|
|||
|
|
Common.SwitchToMachine(mcName);
|
|||
|
|
|
|||
|
|
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
|||
|
|
{
|
|||
|
|
Common.ShowToolTip(
|
|||
|
|
string.Format(
|
|||
|
|
CultureInfo.CurrentCulture,
|
|||
|
|
"Control has been switched to {0} by the hotkey Ctrl+Alt+{1}{2}",
|
|||
|
|
mcName,
|
|||
|
|
Setting.Values.HotKeySwitchMachine == (int)VK.F1 ? "F" : string.Empty,
|
|||
|
|
index + 1),
|
|||
|
|
3000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal void ResetLastSwitchKeys()
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < CONTROL_TOUCH; i++)
|
|||
|
|
{
|
|||
|
|
ctrlTouches[i] = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CtrlDown = winDown = altDown = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|