Anonymous
Лаг мыши при аппаратном автокликере – почему курсор так задерживается и как это исправить?
Сообщение
Anonymous » 08 фев 2026, 19:29
Что делает программа:
Программа распознает реальные физические щелчки мышью и быстро имитирует дополнительные щелчки, пока кнопка удерживается, с разной частотой для левой и правой кнопок. Он использует низкоуровневый крючок мыши Windows и функцию SendInput() для генерации щелчков мышью в режиме реального времени и обеспечивает чистый выход с помощью клавиши ALT.
Проблема:
Курсор мыши сильно запаздывает и очень медленно реагирует во время работы программы. Это происходит потому, что низкоуровневый перехватчик обрабатывает каждое событие мыши, а также отправляет быстрые имитированные щелчки, что перегружает систему. Высокие показатели CPS и потоковая модель программы создают задержки, вызывающие заметную задержку ввода. Как можно устранить эту задержку, сохранив при этом работоспособность автокликера?
Код:
Код: Выделить всё
import ctypes
import time
import threading
import win32con
from ctypes import wintypes
WH_MOUSE_LL = 14
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
WM_RBUTTONDOWN = 0x0204
WM_RBUTTONUP = 0x0205
LLMHF_INJECTED = 0x00000001
LEFT_CPS = 12
RIGHT_CPS = 8
EXIT_KEY = win32con.VK_MENU
left_button_physically_pressed = False
right_button_physically_pressed = False
running = True
hook_id = None
class POINT(ctypes.Structure):
_fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]
class MSLLHOOKSTRUCT(ctypes.Structure):
_fields_ = [
("pt", POINT),
("mouseData", wintypes.DWORD),
("flags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.WPARAM)
]
user32 = ctypes.WinDLL('user32', use_last_error=True)
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
if ctypes.sizeof(ctypes.c_void_p) == 8:
LRESULT = ctypes.c_int64
else:
LRESULT = ctypes.c_long
user32.CallNextHookEx.argtypes = [wintypes.HHOOK, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM]
user32.CallNextHookEx.restype = LRESULT
user32.SetWindowsHookExW.argtypes = [ctypes.c_int, wintypes.HANDLE, wintypes.HINSTANCE, wintypes.DWORD]
user32.SetWindowsHookExW.restype = wintypes.HHOOK
LowLevelMouseProc = ctypes.WINFUNCTYPE(LRESULT, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM)
def low_level_mouse_callback(nCode, wParam, lParam):
global left_button_physically_pressed, right_button_physically_pressed
if nCode >= 0:
try:
mouse_event = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT)).contents
is_injected = (mouse_event.flags & LLMHF_INJECTED) != 0
if not is_injected:
if wParam == WM_LBUTTONDOWN:
left_button_physically_pressed = True
elif wParam == WM_LBUTTONUP:
left_button_physically_pressed = False
elif wParam == WM_RBUTTONDOWN:
right_button_physically_pressed = True
elif wParam == WM_RBUTTONUP:
right_button_physically_pressed = False
except Exception:
pass
return user32.CallNextHookEx(None, nCode, wParam, lParam)
def send_mouse_click(button):
class MOUSEINPUT(ctypes.Structure):
_fields_ = [
("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", ctypes.POINTER(ctypes.c_ulong))
]
class INPUT(ctypes.Structure):
class _INPUT(ctypes.Union):
_fields_ = [("mi", MOUSEINPUT)]
_anonymous_ = ("_input",)
_fields_ = [("type", ctypes.c_ulong), ("_input", _INPUT)]
INPUT_MOUSE = 0
MOUSEEVENTF_LEFTDOWN = 0x0002
MOUSEEVENTF_LEFTUP = 0x0004
MOUSEEVENTF_RIGHTDOWN = 0x0008
MOUSEEVENTF_RIGHTUP = 0x0010
if button == 'left':
input_down = INPUT(); input_down.type = INPUT_MOUSE
input_down.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_LEFTDOWN, 0, None)
input_up = INPUT(); input_up.type = INPUT_MOUSE
input_up.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_LEFTUP, 0, None)
user32.SendInput(1, ctypes.byref(input_down), ctypes.sizeof(INPUT))
user32.SendInput(1, ctypes.byref(input_up), ctypes.sizeof(INPUT))
elif button == 'right':
input_down = INPUT(); input_down.type = INPUT_MOUSE
input_down.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTDOWN, 0, None)
input_up = INPUT(); input_up.type = INPUT_MOUSE
input_up.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTUP, 0, None)
user32.SendInput(1, ctypes.byref(input_down), ctypes.sizeof(INPUT))
user32.SendInput(1, ctypes.byref(input_up), ctypes.sizeof(INPUT))
def click_handler(button, cps):
global running, left_button_physically_pressed, right_button_physically_pressed
delay = 1.0 / cps
while running:
if ctypes.windll.user32.GetAsyncKeyState(EXIT_KEY) & 0x8000:
running = False
break
if button == 'left' and left_button_physically_pressed:
send_mouse_click('left')
time.sleep(delay)
elif button == 'right' and right_button_physically_pressed:
send_mouse_click('right')
time.sleep(delay)
else:
time.sleep(0.001)
def hook_thread():
global running, hook_id
callback = LowLevelMouseProc(low_level_mouse_callback)
hook_id = user32.SetWindowsHookExW(WH_MOUSE_LL, callback, None, 0)
if not hook_id:
return
while running:
if ctypes.windll.user32.GetAsyncKeyState(EXIT_KEY) & 0x8000:
running = False
break
msg = wintypes.MSG()
PM_REMOVE = 0x0001
while user32.PeekMessageW(ctypes.byref(msg), None, 0, 0, PM_REMOVE):
user32.TranslateMessage(ctypes.byref(msg))
user32.DispatchMessageW(ctypes.byref(msg))
time.sleep(0.001)
if hook_id:
user32.UnhookWindowsHookEx(hook_id)
def main():
global running
print("✅ Autoclicker started")
try:
hook_t = threading.Thread(target=hook_thread, daemon=True)
hook_t.start()
time.sleep(0.5)
left_thread = threading.Thread(target=click_handler, args=('left', LEFT_CPS), daemon=True)
right_thread = threading.Thread(target=click_handler, args=('right', RIGHT_CPS), daemon=True)
left_thread.start()
right_thread.start()
while running:
if ctypes.windll.user32.GetAsyncKeyState(EXIT_KEY) & 0x8000:
running = False
break
time.sleep(0.05)
finally:
running = False
time.sleep(0.5)
print("✅ Autoclicker stopped")
if __name__ == "__main__":
main()
Подробнее здесь:
https://stackoverflow.com/questions/798 ... ed-and-how
1770568181
Anonymous
[b]Что делает программа:[/b] Программа распознает реальные физические щелчки мышью и быстро имитирует дополнительные щелчки, пока кнопка удерживается, с разной частотой для левой и правой кнопок. Он использует низкоуровневый крючок мыши Windows и функцию SendInput() для генерации щелчков мышью в режиме реального времени и обеспечивает чистый выход с помощью клавиши ALT. [b]Проблема:[/b] Курсор мыши сильно запаздывает и очень медленно реагирует во время работы программы. Это происходит потому, что низкоуровневый перехватчик обрабатывает каждое событие мыши, а также отправляет быстрые имитированные щелчки, что перегружает систему. Высокие показатели CPS и потоковая модель программы создают задержки, вызывающие заметную задержку ввода. Как можно устранить эту задержку, сохранив при этом работоспособность автокликера? Код: [code]import ctypes import time import threading import win32con from ctypes import wintypes WH_MOUSE_LL = 14 WM_LBUTTONDOWN = 0x0201 WM_LBUTTONUP = 0x0202 WM_RBUTTONDOWN = 0x0204 WM_RBUTTONUP = 0x0205 LLMHF_INJECTED = 0x00000001 LEFT_CPS = 12 RIGHT_CPS = 8 EXIT_KEY = win32con.VK_MENU left_button_physically_pressed = False right_button_physically_pressed = False running = True hook_id = None class POINT(ctypes.Structure): _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)] class MSLLHOOKSTRUCT(ctypes.Structure): _fields_ = [ ("pt", POINT), ("mouseData", wintypes.DWORD), ("flags", wintypes.DWORD), ("time", wintypes.DWORD), ("dwExtraInfo", wintypes.WPARAM) ] user32 = ctypes.WinDLL('user32', use_last_error=True) kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) if ctypes.sizeof(ctypes.c_void_p) == 8: LRESULT = ctypes.c_int64 else: LRESULT = ctypes.c_long user32.CallNextHookEx.argtypes = [wintypes.HHOOK, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM] user32.CallNextHookEx.restype = LRESULT user32.SetWindowsHookExW.argtypes = [ctypes.c_int, wintypes.HANDLE, wintypes.HINSTANCE, wintypes.DWORD] user32.SetWindowsHookExW.restype = wintypes.HHOOK LowLevelMouseProc = ctypes.WINFUNCTYPE(LRESULT, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM) def low_level_mouse_callback(nCode, wParam, lParam): global left_button_physically_pressed, right_button_physically_pressed if nCode >= 0: try: mouse_event = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT)).contents is_injected = (mouse_event.flags & LLMHF_INJECTED) != 0 if not is_injected: if wParam == WM_LBUTTONDOWN: left_button_physically_pressed = True elif wParam == WM_LBUTTONUP: left_button_physically_pressed = False elif wParam == WM_RBUTTONDOWN: right_button_physically_pressed = True elif wParam == WM_RBUTTONUP: right_button_physically_pressed = False except Exception: pass return user32.CallNextHookEx(None, nCode, wParam, lParam) def send_mouse_click(button): class MOUSEINPUT(ctypes.Structure): _fields_ = [ ("dx", ctypes.c_long), ("dy", ctypes.c_long), ("mouseData", ctypes.c_ulong), ("dwFlags", ctypes.c_ulong), ("time", ctypes.c_ulong), ("dwExtraInfo", ctypes.POINTER(ctypes.c_ulong)) ] class INPUT(ctypes.Structure): class _INPUT(ctypes.Union): _fields_ = [("mi", MOUSEINPUT)] _anonymous_ = ("_input",) _fields_ = [("type", ctypes.c_ulong), ("_input", _INPUT)] INPUT_MOUSE = 0 MOUSEEVENTF_LEFTDOWN = 0x0002 MOUSEEVENTF_LEFTUP = 0x0004 MOUSEEVENTF_RIGHTDOWN = 0x0008 MOUSEEVENTF_RIGHTUP = 0x0010 if button == 'left': input_down = INPUT(); input_down.type = INPUT_MOUSE input_down.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_LEFTDOWN, 0, None) input_up = INPUT(); input_up.type = INPUT_MOUSE input_up.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_LEFTUP, 0, None) user32.SendInput(1, ctypes.byref(input_down), ctypes.sizeof(INPUT)) user32.SendInput(1, ctypes.byref(input_up), ctypes.sizeof(INPUT)) elif button == 'right': input_down = INPUT(); input_down.type = INPUT_MOUSE input_down.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTDOWN, 0, None) input_up = INPUT(); input_up.type = INPUT_MOUSE input_up.mi = MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTUP, 0, None) user32.SendInput(1, ctypes.byref(input_down), ctypes.sizeof(INPUT)) user32.SendInput(1, ctypes.byref(input_up), ctypes.sizeof(INPUT)) def click_handler(button, cps): global running, left_button_physically_pressed, right_button_physically_pressed delay = 1.0 / cps while running: if ctypes.windll.user32.GetAsyncKeyState(EXIT_KEY) & 0x8000: running = False break if button == 'left' and left_button_physically_pressed: send_mouse_click('left') time.sleep(delay) elif button == 'right' and right_button_physically_pressed: send_mouse_click('right') time.sleep(delay) else: time.sleep(0.001) def hook_thread(): global running, hook_id callback = LowLevelMouseProc(low_level_mouse_callback) hook_id = user32.SetWindowsHookExW(WH_MOUSE_LL, callback, None, 0) if not hook_id: return while running: if ctypes.windll.user32.GetAsyncKeyState(EXIT_KEY) & 0x8000: running = False break msg = wintypes.MSG() PM_REMOVE = 0x0001 while user32.PeekMessageW(ctypes.byref(msg), None, 0, 0, PM_REMOVE): user32.TranslateMessage(ctypes.byref(msg)) user32.DispatchMessageW(ctypes.byref(msg)) time.sleep(0.001) if hook_id: user32.UnhookWindowsHookEx(hook_id) def main(): global running print("✅ Autoclicker started") try: hook_t = threading.Thread(target=hook_thread, daemon=True) hook_t.start() time.sleep(0.5) left_thread = threading.Thread(target=click_handler, args=('left', LEFT_CPS), daemon=True) right_thread = threading.Thread(target=click_handler, args=('right', RIGHT_CPS), daemon=True) left_thread.start() right_thread.start() while running: if ctypes.windll.user32.GetAsyncKeyState(EXIT_KEY) & 0x8000: running = False break time.sleep(0.05) finally: running = False time.sleep(0.5) print("✅ Autoclicker stopped") if __name__ == "__main__": main() [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79885027/mouse-lag-with-hardware-level-autoclicker-why-is-the-cursor-so-delayed-and-how[/url]