forked from kurumpa/dotSwitcher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LowLevelAdapter.cs
152 lines (132 loc) · 5.01 KB
/
LowLevelAdapter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.ComponentModel;
namespace dotSwitcher
{
public static partial class LowLevelAdapter
{
public static IntPtr SetHook(int type, HookProc callback)
{
var process = Process.GetCurrentProcess();
var module = process.MainModule;
var handle = GetModuleHandle(module.ModuleName);
return SetWindowsHookEx(type, callback, handle, 0);
}
public static void ReleaseHook(IntPtr id)
{
UnhookWindowsHookEx(id);
}
public static IntPtr NextHook(int nCode, IntPtr wParam, IntPtr lParam)
{
return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}
public static bool KeyPressed(Keys keyCode)
{
return (GetKeyState((int)keyCode) & 0x8000) == 0x8000;
}
//[DllImport("USER32.DLL")]
//public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
//private static string GetClassName(IntPtr handle)
//{
// StringBuilder className = new StringBuilder(100);
// GetClassName(handle, className, className.Capacity);
// return className.ToString();
//}
private static IntPtr GetFocusedHandle()
{
var threadId = GetCurrentThreadId();
var wndThreadId = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
if (threadId == wndThreadId)
{
return IntPtr.Zero;
}
AttachThreadInput(wndThreadId, threadId, true);
IntPtr focusedHandle = GetFocus();
AttachThreadInput(wndThreadId, threadId, false);
return focusedHandle;
}
public static void SetNextKeyboardLayout()
{
IntPtr hWnd = IntPtr.Zero;
var threadId = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
var info = new GUITHREADINFO();
info.cbSize = Marshal.SizeOf(info);
var success = GetGUIThreadInfo(threadId, ref info);
// target = hwndCaret || hwndFocus || (AttachThreadInput + GetFocus) || hwndActive || GetForegroundWindow
var focusedHandle = GetFocusedHandle();
if (success)
{
if (info.hwndCaret != IntPtr.Zero)
{
hWnd = info.hwndCaret;
}
else if (info.hwndFocus != IntPtr.Zero)
{
hWnd = info.hwndFocus;
}
else if (focusedHandle != IntPtr.Zero)
{
hWnd = focusedHandle;
}
else if (info.hwndActive != IntPtr.Zero)
{
hWnd = info.hwndActive;
}
}
else
{
hWnd = focusedHandle;
}
if(hWnd == IntPtr.Zero) { hWnd = GetForegroundWindow(); }
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_FORWARD, HKL_NEXT);
}
public static void SendKeyPress(Keys vkCode, bool shift = false)
{
var down = MakeKeyInput(vkCode, true);
var up = MakeKeyInput(vkCode, false);
if (shift)
{
var shiftDown = MakeKeyInput(Keys.ShiftKey, true);
var shiftUp = MakeKeyInput(Keys.ShiftKey, false);
SendInput(4, new INPUT[4] { shiftDown, down, up, shiftUp }, Marshal.SizeOf(typeof(INPUT)));
}
else
{
SendInput(2, new INPUT[2] { down, up }, Marshal.SizeOf(typeof(INPUT)));
}
}
public static void ReleasePressedFnKeys()
{
// temp solution
//ReleasePressedKey(Keys.LMenu, true),
//ReleasePressedKey(Keys.RMenu, true),
//ReleasePressedKey(Keys.LWin, true),
//ReleasePressedKey(Keys.RWin, true),
ReleasePressedKey(Keys.RControlKey, false);
ReleasePressedKey(Keys.LControlKey, false);
ReleasePressedKey(Keys.LShiftKey, false);
ReleasePressedKey(Keys.RShiftKey, false);
}
public static bool ReleasePressedKey(Keys keyCode, bool releaseTwice)
{
if (!KeyPressed(keyCode)) { return false; }
//Debug.WriteLine("{0} was down", keyCode);
var keyUp = MakeKeyInput(keyCode, false);
if (releaseTwice)
{
var secondDown = MakeKeyInput(keyCode, true);
var secondUp = MakeKeyInput(keyCode, false);
SendInput(3, new INPUT[3] { keyUp, secondDown, secondUp }, Marshal.SizeOf(typeof(INPUT)));
}
else
{
SendInput(1, new INPUT[1] { keyUp }, Marshal.SizeOf(typeof(INPUT)));
}
return true;
}
}
}