-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfrmMain.cs
137 lines (115 loc) · 4.69 KB
/
frmMain.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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
// using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
// ... { GLOBAL HOOK }
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
const int WH_KEYBOARD_LL = 13; // Keyboard hook id
// Some key ids
const int WM_ACTIVATE = 0x006;
const int WM_SETFOCUS = 0x007;
const int WM_KILLFOCUS = 0x008;
const int WM_KEYUP = 0x101;
const int WM_KEYDOWN = 0x100;
const int WM_CHAR = 0x102;
const int WM_DEADCHAR = 0x103;
const int WM_SYSKEYDOWN = 0x104;
const int WM_SYSKEYUP = 0x105;
const int WM_SYSDEADCHAR = 0x107;
const int WM_UNICHAR = 0x109;
const int WM_HOTKEY = 0x312;
const int WM_APPCOMMAND = 0x319;
const int VK_SHIFT = 0x10;
const int VK_CONTROL = 0x11;
const int VK_BACKSPACE = 0x08;
private LowLevelKeyboardProc _proc = hookProc;
private static IntPtr hhook = IntPtr.Zero;
static Dictionary<char, char> special_keys = new Dictionary<char, char> { { 'c', 'ĉ' }, { 'C', 'Ĉ' }, { 'g', 'ĝ' }, { 'G', 'Ĝ' }, { 'h', 'ĥ' }, { 'H', 'Ĥ' }, { 'j', 'ĵ' }, { 'J', 'Ĵ' }, { 's', 'ŝ' }, { 'S', 'Ŝ' }, { 'u', 'ŭ' }, { 'U', 'Ŭ' } };
static char lastChar = 'a';
static bool insertBefore = true;
public NotifyIcon trayIcon;
public ContextMenu trayMenu;
public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (wParam != (IntPtr) WM_KEYDOWN)
return CallNextHookEx(hhook, code, (int) wParam, lParam);
char vkCode = (char) Marshal.ReadInt32(lParam);
// if not on [a-z,A-Z] char range then return
if ((vkCode < 65 || vkCode > 90) && (vkCode < 97 || vkCode > 122)) {
if (vkCode == VK_BACKSPACE) {
lastChar = '_';
}
return (IntPtr) 0;
}
// Upper case if caps xor shift is pressed (if both are pressed, then it is not upper case, right?)
if (Control.IsKeyLocked(Keys.CapsLock) ^ ((ModifierKeys & Keys.Shift) == Keys.Shift))
vkCode = Char.ToUpper(vkCode);
else
vkCode = Char.ToLower(vkCode);
if (insertBefore) {
if (char.ToLower(lastChar) == 'x') {
if (special_keys.ContainsKey(vkCode)) {
SendKeys.Send(special_keys[vkCode].ToString());
lastChar = '_';
return (IntPtr) 1;
}
} else if (char.ToLower(vkCode) == 'x') {
lastChar = vkCode;
return (IntPtr) 1;
}
} else {
if (char.ToLower(vkCode) == 'x') {
char value;
if (special_keys.TryGetValue(lastChar, out value)) {
SendKeys.Send("{backspace}" + value.ToString());
return (IntPtr) 1;
}
}
}
lastChar = vkCode;
return (IntPtr) 0;
}
public void SetHook(Boolean enable)
{
if (enable) {
IntPtr hInstance = LoadLibrary("User32");
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
} else {
UnhookWindowsHookEx(hhook);
}
}
private void cbtAtivar_CheckedChanged(object sender, EventArgs e)
{
SetHook(cbtAtivar.Checked);
}
private void rbBefore_CheckedChanged(object sender, EventArgs e)
{
insertBefore = true;
}
private void rbAfter_CheckedChanged(object sender, EventArgs e)
{
insertBefore = false;
}
}
}