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

Function LowLevelMouseProc

source/hook.cpp:228–297  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

226
227
228LRESULT CALLBACK LowLevelMouseProc(int aCode, WPARAM wParam, LPARAM lParam)
229{
230 // code != HC_ACTION should be evaluated PRIOR to considering the values
231 // of wParam and lParam, because those values may be invalid or untrustworthy
232 // whenever code < 0.
233 if (aCode != HC_ACTION)
234 return CallNextHookEx(g_MouseHook, aCode, wParam, lParam);
235
236 MSLLHOOKSTRUCT &event = *(PMSLLHOOKSTRUCT)lParam; // For convenience, maintainability, and possibly performance.
237
238 // Make all mouse events physical to try to simulate mouse clicks in games that normally ignore
239 // artificial input.
240 //event.flags &= ~LLMHF_INJECTED;
241
242 if (!(event.flags & LLMHF_INJECTED)) // Physical mouse movement or button action (uses LLMHF vs. LLKHF).
243 g_TimeLastInputPhysical = g_TimeLastInputMouse = GetTickCount();
244 // Above: Don't use event.time, mostly because SendInput can produce invalid timestamps on such events
245 // (though in truth, that concern isn't valid because SendInput's input isn't marked as physical).
246 // Another concern is the comments at the other update of "g_TimeLastInputPhysical" elsewhere in this file.
247 // A final concern is that some drivers might be faulty and might not generate an accurate timestamp.
248
249 if (wParam == WM_MOUSEMOVE) // Only after updating for physical input, above, is this checked.
250 return (g_BlockMouseMove && !(event.flags & LLMHF_INJECTED)) ? 1 : CallNextHookEx(g_MouseHook, aCode, wParam, lParam);
251 // Above: In v1.0.43.11, a new mode was added to block mouse movement only since it's more flexible than
252 // BlockInput (which keybd too, and blocks all mouse buttons too). However, this mode blocks only
253 // physical mouse movement because it seems most flexible (and simplest) to allow all artificial
254 // movement, even if that movement came from a source other than an AHK script (such as some other
255 // macro program).
256
257 // MSDN: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL [, WM_MOUSEHWHEEL], WM_RBUTTONDOWN, or WM_RBUTTONUP.
258 // But what about the middle button? It's undocumented, but it is received.
259 // What about doubleclicks (e.g. WM_LBUTTONDBLCLK): I checked: They are NOT received.
260 // This is expected because each click in a doubleclick could be separately suppressed by
261 // the hook, which would make it become a non-doubleclick.
262 vk_type vk = 0;
263 sc_type sc = 0; // To be overridden if this even is a wheel turn.
264 short wheel_delta;
265 bool key_up = true; // Set default to safest value.
266
267 switch (wParam)
268 {
269 case WM_MOUSEWHEEL:
270 case WM_MOUSEHWHEEL: // v1.0.48: Lexikos: Support horizontal scrolling in Windows Vista and later.
271 // MSDN: "A positive value indicates that the wheel was rotated forward, away from the user;
272 // a negative value indicates that the wheel was rotated backward, toward the user. One wheel
273 // click is defined as WHEEL_DELTA, which is 120." Testing shows that on XP at least, the
274 // abs(delta) is greater than 120 when the user turns the wheel quickly (also depends on
275 // granularity of wheel hardware); i.e. the system combines multiple turns into a single event.
276 wheel_delta = GET_WHEEL_DELTA_WPARAM(event.mouseData); // Must typecast to short (not int) via macro, otherwise the conversion to negative/positive number won't be correct.
277 if (wParam == WM_MOUSEWHEEL)
278 vk = wheel_delta < 0 ? VK_WHEEL_DOWN : VK_WHEEL_UP;
279 else
280 vk = wheel_delta < 0 ? VK_WHEEL_LEFT : VK_WHEEL_RIGHT;
281 sc = (wheel_delta > 0 ? wheel_delta : -wheel_delta); // Note that sc is unsigned.
282 key_up = false; // Always consider wheel movements to be "key down" events.
283 break;
284 case WM_LBUTTONUP: vk = VK_LBUTTON; break;
285 case WM_RBUTTONUP: vk = VK_RBUTTON; break;

Callers

nothing calls this directly

Calls 1

LowLevelCommonFunction · 0.85

Tested by

no test coverage detected