MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / LowLevelKeybdProc

Function LowLevelKeybdProc

source/hook.cpp:157–224  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

155
156
157LRESULT CALLBACK LowLevelKeybdProc(int aCode, WPARAM wParam, LPARAM lParam)
158{
159 if (aCode != HC_ACTION) // MSDN docs specify that both LL keybd & mouse hook should return in this case.
160 return CallNextHookEx(g_KeybdHook, aCode, wParam, lParam);
161
162 KBDLLHOOKSTRUCT &event = *(PKBDLLHOOKSTRUCT)lParam; // For convenience, maintainability, and possibly performance.
163
164 // Change the event to be physical if that is indicated in its dwExtraInfo attribute.
165 // This is done for cases when the hook is installed multiple times and one instance of
166 // it wants to inform the others that this event should be considered physical for the
167 // purpose of updating modifier and key states:
168 if (event.dwExtraInfo == KEY_PHYS_IGNORE)
169 event.flags &= ~LLKHF_INJECTED;
170 else if (event.dwExtraInfo == KEY_BLOCK_THIS)
171 return TRUE;
172
173 // Make all keybd events physical to try to fool the system into accepting CTRL-ALT-DELETE.
174 // This didn't work, which implies that Ctrl-Alt-Delete is trapped at a lower level than
175 // this hook (folks have said that it's trapped in the keyboard driver itself):
176 //event.flags &= ~LLKHF_INJECTED;
177
178 // Note: Some scan codes are shared by more than one key (e.g. Numpad7 and NumpadHome). This is why
179 // the keyboard hook must be able to handle hotkeys by either their virtual key or their scan code.
180 // i.e. if sc were always used in preference to vk, we wouldn't be able to distinguish between such keys.
181
182 bool key_up = (wParam == WM_KEYUP || wParam == WM_SYSKEYUP);
183 vk_type vk = (vk_type)event.vkCode;
184 sc_type sc = (sc_type)event.scanCode;
185 if (vk && !sc) // Might happen if another app calls keybd_event with a zero scan code.
186 sc = vk_to_sc(vk);
187 // MapVirtualKey() does *not* include 0xE0 in HIBYTE if key is extended. In case it ever
188 // does in the future (or if event.scanCode ever does), force sc to be an 8-bit value
189 // so that it's guaranteed consistent and to ensure it won't exceed SC_MAX (which might cause
190 // array indexes to be out-of-bounds). The 9th bit is later set to 1 if the key is extended:
191 sc &= 0xFF;
192 // Change sc to be extended if indicated. But avoid doing so for VK_RSHIFT, which is
193 // apparently considered extended by the API when it shouldn't be. Update: Well, it looks like
194 // VK_RSHIFT really is an extended key, at least on WinXP (and probably be extension on the other
195 // NT based OSes as well). What little info I could find on the 'net about this is contradictory,
196 // but it's clear that some things just don't work right if the non-extended scan code is sent. For
197 // example, the shift key will appear to get stuck down in the foreground app if the non-extended
198 // scan code is sent with VK_RSHIFT key-up event:
199 if ((event.flags & LLKHF_EXTENDED)) // && vk != VK_RSHIFT)
200 sc |= 0x100;
201
202 // The below must be done prior to any returns that indirectly call UpdateKeybdState() to update
203 // modifier state.
204 // Update: It seems best to do the below unconditionally, even if the OS is Win2k or WinXP,
205 // since it seems like this translation will add value even in those cases:
206 // To help ensure consistency with Windows XP and 2k, for which this hook has been primarily
207 // designed and tested, translate neutral modifier keys into their left/right specific VKs,
208 // since beardboy's testing shows that NT4 receives the neutral keys like Win9x does:
209 switch (vk)
210 {
211 case VK_SHIFT: vk = (sc == SC_RSHIFT) ? VK_RSHIFT : VK_LSHIFT; break;
212 case VK_CONTROL: vk = (sc == SC_RCONTROL) ? VK_RCONTROL : VK_LCONTROL; break;
213 case VK_MENU: vk = (sc == SC_RALT) ? VK_RMENU : VK_LMENU; break;
214 }

Callers

nothing calls this directly

Calls 2

vk_to_scFunction · 0.85
LowLevelCommonFunction · 0.85

Tested by

no test coverage detected