Практическое применение mouse_event
Все когда-то хоть один раз, да требуется. Так и у меня. О функции имитирующей нажатие кнопок мыши (клики) я собственно и не задумывался , пока какой-то один веселый парень не нафлудил на моем сайте бесплатных программ. В итоге нужно было удалить более 400 новостей различного вареза. Конечно если бы он выкладывал новости там где они должны быть, то я бы заметил. Но вот ведь хитрец! Он заливал их в каталог статей, а туда я захожу очень редко. Нет конечно этот варез был не активирован и вроде бы наплевать, но размер сайта все-таки ограничен... Судя по всему он это делал специально для таких нужд приспособленной программой для заливки новостей. Когда я начал чистить вручную , то понял что это будет довольно гиморно. Приходилось в админке кликать по удалению новости и потом потверждать. После 10-15 удалений новостей, я начал задумываться об автоматизации этой задачи. Поискал что-то готовое , но все какое-то навороченное, кучу времени надо на изучение. Решил сделать свою. В уме сразу ожила функция keybd_event для имитации нажатия клавиш. Раз есть для клавиш, значит должна быть и для мыши. Залез в интернет и тут же натолкнулся на функцию Mouse_Event. То что нужно!
Ее определение:
mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo )
- dwFlags - Флаг(и), могут быть:
- MOUSEEVENTF_ABSOLUTE - устанавливает, что параметры dx и dy содержат абсолютные координаты. Если флажок не установлен, то параметры dx и dy содержит относительные координаты.
- MOUSEEVENTF_MOVE - устанавливает, что произошло перемещение.
- MOUSEEVENTF_LEFTDOWN - устанавливает, что нажата левая кнопка.
- MOUSEEVENTF_LEFTUP - устанавливает, что отпущена левая кнопка.
- MOUSEEVENTF_RIGHTDOWN - устанавливает, что нажата правая кнопка.
- MOUSEEVENTF_RIGHTUP - устанавливает, что отпущена правая кнопка.
- MOUSEEVENTF_MIDDLEDOWN - устанавливает, что нажата средняя кнопка.
- MOUSEEVENTF_MIDDLEUP - устанавливает, что отпущена средняя кнопка.
- MOUSEEVENTF_WHEEL - Windows NT/2000/XP: устанавливает, что переместилось колесико, если мышь имеет колесико. Величина перемещения определяется в параметре dwData.
- MOUSEEVENTF_XDOWN - Windows 2000/XP: устанавливает, что была нажата X-кнопка.
- MOUSEEVENTF_XUP - Windows 2000/XP: устанавливает, что была отпущена X-кнопка.
- dx,dy - кординаты мыши
- dwData - величина перемещения колесика, один щелчок колесика содержит величину - 120.
- dwExtraInfo - дополнительное значение, связанное с событием мыши, для получения следует вызвать функцию GetMessageExtraInfo.
Данная функция способна кликать и двигать мышью. Но если первое делается очень просто, то для определения координат для параметров функции, нужно заниматься преобразованием их в другую систему координат, что для моих задач было просто не нужно. Есть способы гораздо проще: функция SetCursorPos вполне сгодится для перемещения мыши. В итоге получалась такая схема в цикле:
- перемещаемся на нужную кнопку
- создаем имитацию нажатия на левую кнопку мыши
- ждем 200 мс
- создаем имитацию отпускания левой кнопки мыши
- перемещаемся на место где покажется окно с кнопкой потверждения
- ждем 2000 мс (все-таки появляется не сразу)
- повторяем пукнты 2,3,4
Для того, чтобы это смотрелось очевидным я написал похожий код:
#INCLUDE "windows.bi" Dim msg As MSG Dim As WNDCLASSEX wc Dim As String NameClass="MyClass" Dim As HINSTANCE Hinst=GetModuleHandle(0) Sub cur(I As Any Ptr) For i As Integer = 1 To 5 SetCursorPos(565,423) ' помещаем курсор на кнопку mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0) 'нажимаем Sleep(200) ' пауза между нажатиями mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0)' отпускаем SetCursorPos(660,555)' помещаем курсор на другую кнопку Sleep(2000) ' ждем пока появится окно потверждения mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0) 'нажимаем Sleep(200)' пауза между нажатиями mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0)' отпускаем Sleep(1000) Next End Sub Function wndproc(hwnd As HWND, msg As Uinteger,_ wparam As WPARAM, lparam As LPARAM) As Integer Select Case msg Case WM_CREATE CreateWindowEx(0,"Button","OK",_ WS_VISIBLE Or WS_CHILD,10,10,100,30,_ hwnd,Cast(HMENU,1),0,0) Case WM_COMMAND If Loword(wParam) = 1 Then MessageBox(0,"","",0) Endif Case WM_DESTROY PostQuitMessage(0) End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function With wc .cbSize=SizeOf(WNDCLASSEX) .style=CS_HREDRAW Or CS_VREDRAW .lpfnWndProc=@wndproc .hInstance=Hinst .hIcon=LoadIcon(0,IDI_WINLOGO) .hCursor=LoadCursor(0,IDC_ARROW) .hbrBackground=Cast(HBRUSH,COLOR_WINDOWFRAME) .lpszClassName=StrPtr(NameClass) .hIconSm=.hIcon End With If RegisterClassEx(@wc)=0 Then Print "Register error, press any key" Sleep End Endif CreateWindowEx(0,NameClass,"",_ WS_VISIBLE Or WS_OVERLAPPEDWINDOW,_ GetSystemMetrics(SM_CXSCREEN)\2-150,_ GetSystemMetrics(SM_CYSCREEN)\2-150,_ 300,300,0,0,Hinst,0) Threadcreate(@cur) While GetMessage(@msg,0,0,0) TranslateMessage(@msg) DispatchMessage(@msg) Wend
Вот таким простым способом я легко удалил весь флуд с сайта, а заодно познакомился еще с одной великолепной API функцией.