![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() На форме WebBrowser. В нём - флеш игра. Нужно кликнуть по заданым координатам. Всё отлично работает через Mouse_event.
Код:
{Переместим курсор мыши} Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pt.x, Pt.y, 0, 0); {Имитируем нажатие левой кнопки мыши} Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, Pt.x, Pt.y, 0, 0); {Имитируем отпускание левой кнопки мыши} Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, Pt.x, Pt.y, 0, 0) Главная проблема - в том, что окно с ботом должно быть открыто. При свёрнутом в трей курсор бегает где угодно, но не там где нужно. Намутил решение через postmessage, но отчего-то работать не хочет. В чём проблема? Код:
procedure TfrmMain.Button3Click(Sender: TObject); var Pt: TPoint; left, top:integer; begin left:=strtoint(Edit31.Text); top:=strtoint(Edit32.Text); {Позволим кнопке перерисоваться} Application.ProcessMessages; {Найдем координаты центра button 1} Pt.x := WebBrowser1.Left + left; Pt.y := WebBrowser1.Top + top + 25; //костыль в 25 от верхней границы {Преобразуем Pt к координатам экрана} Pt := ClientToScreen(Pt); {Преобразуем Pt к "mickeys" (аболютным координатам курсора мышки} Pt.x := Round(Pt.x * (65535 / Screen.Width)); Pt.y := Round(Pt.y * (65535 / Screen.Height)); postmessage(frmMain.WebBrowser1.Handle,WM_MOVE,0,(Pt. x shl 16)+ Pt.y); postmessage(frmMain.WebBrowser1.Handle,WM_LBUTTONDOWN,0,(Pt. x shl 16)+ Pt.y); postmessage(frmMain.WebBrowser1.Handle,WM_LBUTTONUP,0,(Pt.x shl 16)+ Pt.y); |
#2
|
|||
|
|||
![]() Решал я эту задачу, и много форумов обшарил, отправить клик мышки в неактивное окно мне кажется нереальным, единственное что мне удалось, отправить клик мышки в неактивное окно, но и тут есть проблема, окно так и норовит стать активным. Задачу решил следующим способом, перед тем как кликнуть в флешке, я делал окно активным (в моем случае было пять окон), дальше отправлял нужно кол-во кликов, и переходил к следующему окну. А для того что бы это работало на заднем плане, поставил виртуальную машину с XPшкой, там это все и запустил.
Вот ссылка на мои творения в этом направлении. |
#3
|
|||
|
|||
![]() Вот топик нашёл:
http://www.programmersforum.ru/showthread.php?t=77918 Вроде как рабочий вариант для Notepad. Код:
postmessage(FindWindowEx(FindWindow('notepad', nil), 0, 'Edit', nil),WM_LBUTTONDOWN,0,(x shl 16)+ y); postmessage(FindWindowEx(FindWindow('notepad', nil), 0, 'Edit', nil),WM_LBUTTONUP,0, (x shl 16)+ y); |
#4
|
|||
|
|||
![]() Перекопал кучу русскоязычных форумов - отправился за материалом в буржунет. Решение существует. Дело в том, что нужно передавать хэндл дочернего окна. А проблема - получается такая "матрёшка" что до нужного хэндла нужно докопаться.
Вот приблизительный код: Цитата:
Меня смущает TPageContol - там вкладки две. Как на нужную вывести? Кто сможет объяснить как добраться до нужного хэндла? Вот вывод Spy++: ![]() |
#5
|
|||
|
|||
![]() Вот таким вот образом я добирался до флешки, только через WinSight32 дочернее окно называется GeckoPlugin.
Код:
procedure TForm1.GetSubChild(wd: HWnD); Var Cw:HWnd; Begin If WD=0 then Exit; Cw := FindWindowEx(Wd, 0, nil, nil); while (Cw <> 0) do begin FRes:=cw; GetSubChild(Cw); Cw := FindWindowEx(Wd, Cw, nil, nil); End; end; Код:
postmessage(Wnd,WM_MOVE,0,(Pt. x shl 16)+ Pt.y); postmessage(Wnd,WM_LBUTTONDOWN,0,(Pt. x shl 16)+ Pt.y); postmessage(Wnd,WM_LBUTTONUP,0,(Pt.x shl 16)+ Pt.y); Последний раз редактировалось Asinkrit, 20.10.2010 в 09:35. |
#6
|
|||
|
|||
![]() Цитата:
Ну вот продедура, которая отправляет в свёрнутое окно блокнота Код:
procedure TForm1.Button1Click(Sender: TObject); var wnd: HWND; i: Integer; s: string; begin wnd:=FindWindow('notepad', nil); if wnd<>0 then begin wnd:=FindWindowEx(wnd, 0, 'Edit', nil); s:='Hello'; for i:=1 to Length(s) do SendMessage(wnd, WM_CHAR, Word(s[i]), 0); // Simulate Return Key. PostMessage(wnd, WM_KEYDOWN, VK_RETURN, 0); // Simulate Space. PostMessage(wnd, WM_KEYDOWN, VK_SPACE, 0); end; end; Только что проверил - работает. И активным стать не пытается. |
#7
|
|||
|
|||
![]() Да но это не клик мышки, ты попробуй именно клик мышки сделать (с клавиатурными сообщениями все немного проще), или к примеру в блокноте добавь кучу текста и попробуй выделить его, то есть MouseDown, MouseMove, MouseUp.
|
#8
|
|||
|
|||
![]() Значит создал файл в блокноте. Забил его единичками. Нижеприведённый код выставляет курсор в указанное мной место. В данном примере x=200 y=200 Проверил и на других числах - работает.
Код:
procedure TForm1.Button1Click(Sender: TObject); var wnd: HWND; i: Integer; s: string; begin wnd:=FindWindow('notepad', nil); if wnd<>0 then begin wnd:=FindWindowEx(wnd, 0, 'Edit', nil); s:='PIZDEC'; for i:=1 to Length(s) do //SendMessage(wnd, WM_CHAR, Word(s[i]), 0); // Simulate Return Key. //PostMessage(wnd, WM_KEYDOWN, VK_RETURN, 0); // Simulate Space. //PostMessage(wnd, WM_KEYDOWN, VK_SPACE, 0); postmessage(Wnd,WM_MOVE,0,(200 shl 16)+ 200); postmessage(Wnd,WM_LBUTTONDOWN,0,(200 shl 16)+ 200); postmessage(Wnd,WM_LBUTTONUP,0,(200 shl 16)+ 200) end; end; Значит можно-таки движение мыши передать. |
#9
|
|||
|
|||
![]() Ок, а теперь попробуй в флешку тоже самое отправить..) хендл флешки можешь получить используя процедуру что я выше давал, в нее надо передать хендл окна броузера, в FRes получишь хендл флешки.
|
#10
|
|||
|
|||
![]() Торможу с процедурой с утра. Так нужно использовать?
Код:
var wnd,xxx: HWND; begin ... xxx:=frmMain.Webbrowser1.Handle; wnd:=GetSubChild(xxx); Где wnd искомый? |
#11
|
|||
|
|||
![]() Я же сказал, в FRes, вот переделал, что бы возвращала хендл.
Код:
function GetSubChild(wd: HWnd):HWnd; Var Cw:HWnd; Begin Result:=0; If WD=0 then Exit; Cw := FindWindowEx(Wd, 0, nil, nil); while (Cw <> 0) do begin Result:=cw; GetSubChild(Cw); Cw := FindWindowEx(Wd, Cw, nil, nil); End; end; |
#12
|
|||
|
|||
![]() Попробовал. Не тот хэндл отдаёт.
+++Shell DocObject View (этот получил) ++++++Internet Explorer_Server +++++++++MacromediaFlashPlayerActiveX (этот нужен) Хотя пиши эти строки и понимаю, что нужно попробовать несколько раз твою функцию использовать ![]() UPD: Ура! О да! Кажется я это сделал! Сейчас домой убегать нужно, рабочий день заканчивается - дома нужно будет потестить. Потом отпишусь. Последний раз редактировалось MrDiG, 20.10.2010 в 16:58. |
#13
|
|||
|
|||
![]() Функция и так рекурсивная, сама себя вызывает несколько раз, пока до нижнего уровня не дойдет.
Давай, пиши о результатах, очень интересно, если все таки получится невозможное) |
#14
|
|||
|
|||
![]() Получилось! Только спускать нужно было не до флешки, а до браузера. Навёл WinSpy++ на окно. Показало, что это браузер и уточнил его хэндл. Используя твою функцию и выводя промежуточные хэндлы "спустился" до нужного окна.
Код выглядит приблизительно так: Код:
procedure TfrmMain.ClickToPage(const left: integer; const top: integer); var Pt: TPoint; var wnd: HWND; begin Application.ProcessMessages; Pt.x := WebBrowser1.Left + left; Pt.y := WebBrowser1.Top + top; Pt := ClientToScreen(Pt); //{Преобразуем Pt к "mickeys" (аболютным координатам курсора мышки} //Pt.x := Round(Pt.x * (65535 / Screen.Width)); // Pt.y := Round(Pt.y * (65535 / Screen.Height)); wnd:=frmMain.WebBrowser1.Handle; wnd:=frmMain.GetSubChild(wnd); wnd:=frmMain.GetSubChild(wnd); //ShowMessage(inttostr(wnd)); // выдаст в десятичной то что WinSpy видит в HEX postmessage(wnd,WM_MOVE,0,(Pt.x shl 16)+ Pt.y); postmessage(wnd,WM_LBUTTONDOWN,0,(Pt.x shl 16)+ Pt.y); postmessage(wnd,WM_LBUTTONUP,0,(Pt.x shl 16)+ Pt.y); Application.ProcessMessages; Окно свёрнуто. Активным стать не пытается. Иногда правда что-то не попадаеть, но я думаю это из-за моего остального кода. У меня случайные координаты для клика в случайное место кнопки. Я его ещё не поправил. Последний раз редактировалось MrDiG, 21.10.2010 в 09:10. |
#15
|
|||
|
|||
![]() Если это работает, то это великолепно, однако есть другая проблема, получить изображение флешки в свернутом окне, вот она точно не решается.
|