summaryrefslogtreecommitdiff
path: root/plugins/HwHotKeys/src/HwHotKeys_KbdHook.cpp
blob: ac80b69036388fcae369b6e70391da6df2e37b08 (plain)
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
/* ============================================================================
Hardware HotKeys plugin for Miranda NG.
Copyright © Eugene f2065, http://f2065.narod.ru, f2065 mail.ru, ICQ 35078112

This program is free software; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111 - 1307, USA.
============================================================================ */

#include "HwHotKeys.h"

LRESULT CALLBACK key_hook(int nCode, WPARAM wParam, LPARAM lParam)  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644985%28v=vs.85%29.aspx
{
		KBDLLHOOKSTRUCT *pKbdLLHookStruct = (KBDLLHOOKSTRUCT *)lParam;
		if (nCode >= 0)
		{
			if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) // ïðè îòïóñêàíèè ëþáîé êíîïêè - ñáðàñûâàåì âñþ íàêîïëåííóþ êîìáèíàöèþ
			{
				key_code = 0;
			}
			else if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
			{
				if (!(pKbdLLHookStruct->scanCode & 0xFFFFFF00) && (pKbdLLHookStruct->scanCode & 0xFF)) // && !(pKbdLLHookStruct->flags & LLKHF_INJECTED)) 
					// 0xFFFFFF00 ôèëüòð äëÿ ñòðàííûõ äâîéíûõ ñêàíêîäîâ íàïðèìåð ïåðåä L_Alt/AltGr, 
					// 0xFF ôèëüòð äëÿ íóëåâûõ ñêàíêîäîâ(ïðèõîäÿò ïðè âñÿêîé òàì ýìóëÿöèè íàæàòèé è ò.ï.)
					// LLKHF_INJECTED ôèëüòð äëÿ ýìóëèðóåìûõ íàæàòèé, íî åñòü ïðîáëåìà ñ íåêîòîðûìè êëàâàìè
				{
					// ñòðîèì êîìïëåêñíûé êîä(ñêàíêîä + äîï.ôëàã LLKHF_EXTENDED), îò 0 äî 1FF
					key_code_raw = (LOBYTE(pKbdLLHookStruct->scanCode) | ((LOBYTE(pKbdLLHookStruct->flags)&1) << 8));

					if (hDialogWnd) // åñëè äèàëîã íàñòðîåê îòêðûò - âûâîäèì â íåãî íàæèìàåìûå êíîïîêè
					{
						StringCbPrintfA(key_name_buffer, sizeof(key_name_buffer), "%03X %s", key_code_raw, key_tab[(key_code_raw & 0x1FF)]);
						SetDlgItemTextA(hDialogWnd, dlg_scancode_edit, key_name_buffer);
					}

					switch (key_code_raw) // ïðîâåðÿåì êíîïêè ìîäèôèêàòîðîâ
						{
						case 0x01D: // L_Ctrl
							key_code |= key_flag_cl;
							break;   // ïîñëå ìîäèôèêàòîðîâ - íè÷åãî íå äåëàåì, âûõîä èç õóêà.
						case 0x11D: // R_Ctrl
							key_code |= key_flag_cr;
							break;
						case 0x038: // L_Alt
							key_code |= key_flag_al;
							break;
						case 0x138: // R_Alt
							key_code |= key_flag_ar;
							break;
						case 0x15B: // L_Win
							key_code |= key_flag_wl;
							break;
						case 0x15C: // R_Win
							key_code |= key_flag_wr;
							break;
						case 0x02A: // L_Shift
							key_code |= key_flag_sl;
							break;
						case 0x036: // R_Shift
							key_code |= key_flag_sr;
							break;
						case 0x12A: // L_Shift_fake
							key_code |= key_flag_sl;
							break;
						case 0x136: // R_Shift_fake
							key_code |= key_flag_sr;
							break; 
						default:  // åñëè ýòî íå êíîïêà ìîäèôèêàòîðà - òî äàëüíåéøàÿ îáðàáîòêà
							key_code = (LOWORD(key_code_raw)) | (key_code & 0xFFFF0000); // â ñòàðøåé ïîëîâèíå òàì ëåæàò áèòû ìîäèôèêàòîðîâ - èõ îñòàâëÿåì (îíè òàì ìîãóò áûòü îò ïðåäûäóùåãî ðàçà)
							if (hDialogWnd) // åñëè äèàëîã íàñòðîåê îòêðûò - âûâîäèì â íåãî êîìïëåêñíóþ êîìáèíàöèþ (òèïà Shift+Key), êîòîðóþ ïîòîì ìîæíî íàçíà÷èòü;
							{
								if (IsDlgButtonChecked(hDialogWnd, dlg_combine)) // ëåâûå/ïðàâûå ìîäèôèêàòîðû îáúåäèíÿòü â îäèí?
								{
									DWORD tmp1, tmp2;
									tmp1 = ((key_code >> 4) | (key_code >> 8)) & 0x00F00000;
									tmp2 = LOWORD(key_code) | tmp1;
									tmp2 &= 0x00F001FF;
									key_code_assign = tmp2;
								}
								else
								{
									key_code_assign = key_code;
								}
								HwHotKeys_PrintFullKeyname(key_code_assign);
								SetDlgItemTextA(hDialogWnd, dlg_keyname_edit, key_name_buffer);
							}
							else // õîòêåé âûïîëíÿþò äåéñòâèÿ òîëüêî åñëè çàêðûò äèàëîã íàñòðîåê (÷òîáû íå ìåøàë íàñòðàèâàòü)
							{
								if (HwHotKeys_CompareCurrentScancode(code_Close)) // õîòêåé ïîëíîãî çàêðûòèÿ Miranda
								{
									// Beep(300, 200);
									CallService("CloseAction", 0, 0);
									return 1;
								}
								else if (HwHotKeys_CompareCurrentScancode(code_HideShow)) // õîòêåé ñâîðà÷èâàíèÿ/ðàçâîðà÷èâàíèÿ ãëàâíîãî îêíà Miranda
								{
									// Beep(700, 200);
									pcli->pfnShowHide(0, 0); // åñòü âàðèàíòû
									return 1;
								}
								else if (HwHotKeys_CompareCurrentScancode(code_ReadMsg)) // õîòêåé ÷òåíèÿ ñîîáùåíèÿ
								{
									// Beep(1500, 200);
									if (pcli->pfnEventsProcessTrayDoubleClick(0) != 0) // êëèê ïî òðåþ äëÿ ñòàíäàðòíîãî îòêðûòèÿ ñîîáùåíèÿ
									{ // èíà÷å - îêíî ÷àòà óæå îòêðûòî è íàäî åãî âûòàùèòü íàâåðõ...
										SetForegroundWindow(pcli->hwndContactList);
										SetFocus(pcli->hwndContactList);
										// õîòÿ âñ¸ ðàâíî ýòî íå î÷åíü ðàáîòàåò â íîâîé âèíäå
										// íàäî http://www.rsdn.ru/article/qna/ui/wndsetfg.xml
										// íî ïîêà íåçíàþ ãäå òóò âçÿòü õýíäë îêíà ÷àòà(ïðè÷¸ì èìåííî äëÿ
										// âûáðàííîãî êîíòàêòà, èõ æå íåñêîëüêî ìîæåò áûòü åñëè ïðîñòîé srmm)
										// ó ìèðàíäû â hkRead òàêèå æå ïðîáëåìû
									}
									return 1; // âîçâðàò 1 çàïðåùàåò äàëüíåéøóþ ðàáîòó êíîïêè, ò.å. êíîïêà ïîñëå íàøåãî ïëàãèíà íèêîìó áîëåå íå äîñòàíåòñÿ
								}
							}
						}
				}
			}
		}
	return CallNextHookEx(hHook, nCode, wParam, lParam);
}