Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как программно вызвать щелчёк мышью в TWebBrowser  (Прочитано 19109 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Megabotan
Участник

ru
Offline Offline

« : 23-12-2006 20:44 » 

Пытаюсь функцией sendmessage (mouse_event мне не подходит) вызвать клик мышью в WebBrowser на форме.
Вот такой код:
Код:
procedure TForm1.Button4Click(Sender: TObject);
var Pt: TPoint;
begin
  Pt.x := WebBrowser1.Left + (WebBrowser1.Width div 2)-300;
  Pt.y := WebBrowser1.Top + (WebBrowser1.Height div 2);
  Pt := ClientToScreen(Pt);
 
  Pt.x := Round(Pt.x * (65535 / Screen.Width));
  Pt.y := Round(Pt.y * (65535 / Screen.Height));
 
 //Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pt.x, Pt.y, 0, 0);
 
  SendMessage(Form1.WebBrowser1.Handle, WM_LBUTTONDOWN, 0, MakeLParam(Pt.x,Pt.y));
  SendMessage(Form1.WebBrowser1.Handle, WM_LBUTTONUP, 0, MakeLParam(Pt.x,Pt.y));
   //PostMessage(WebBrowser1.Handle,WM_LBUTTONDOWN, MK_LBUTTON, makelong(Pt.x,Pt.Y));
   //PostMessage(WebBrowser1.Handle,WM_LBUTTONUP, 0, makelong(Pt.x,Pt.Y));
end;
Если вместо Form1.WebBrowser1.Handle поставить Form1.Button3.Handle, то кнопка Button3 будет нормально нажиматься, а  WebBrowser никак не реагирует (закомментированный вариант тоже не подходит).
Координаты я пробовал нулевые задавать - ничего не меняется.
Может в Interner Explorer защита от подобных действий стоит? Я уже сталкивался с тем, что в этом компоненте запрещён доступ к телу фрейма, если домен фрейма не совпадает с  доменом родительского документа.
Может кто меня научит как с такими нюансами справляться?
Записан
Megabotan
Участник

ru
Offline Offline

« Ответ #1 : 24-12-2006 09:50 » new

Ребят, подскажите, пожалуйста. Очень нужно.
Наверняка ведь можно с помощью Win API симулировать клик мышкой, не двигая при этом настоящий курсор.
Это мне нужно для того, чтобы для дистанционной системы обучения брать научный контент у сторонних сайтов, для генерации которого используются события JavaScript (OnMouseOver, OnMouseClick).
Вызвать JavaScript-функции событий непосредственно можно, но будет гораздо сложнее.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 24-12-2006 11:22 » 

Megabotan, логичнее будет добавить (если это возможно) в отображаемую страницу код, который вызовет JS-метод click() на нужном элементе формы. Код, как ты понимаешь, должен быть на JS.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Megabotan
Участник

ru
Offline Offline

« Ответ #3 : 24-12-2006 13:31 » 

Метод click можно вызвать прямо из Delphi. Для события Onmouseover тоже можно было бы извращение какое-нибудь придумать, но дело в том, что ссылки находятся в iframe, доступ к телу которого заботливо запрещён программистами Microsoft  RTFM
У меня два выхода:
Либо брать из кэша и сохранять код родительского документа и фрейма в одном локальном каталоге, тогда доступ к телу фрейма откроется (не хочется этого делать, мне все равно потом придётся возится с интерфейсом IHtmlDocument2, чтобы вызывать JavaScript ф-ции из Delphi).
Либо через Win Api ф-ции, чтобы они имитировали движении и нажатие кпопок мыши в окне TWebBrowser.
Мне нужна именно подсказка как это сделать. Мой код работает для чего угодно, только не для TWebBrower.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 24-12-2006 17:24 » 

Хм. Я с этими штуками не знаком - не могу сказать, где рыть.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 24-12-2006 18:24 » 

Я пробовал как-то, не получилось. Текст у кнопок и окна менялся, а вот клик не эмулировался. Но ...
Есть тут одна фича, про которую я позже узнал, но опробовать не успел. Я тебе ее посоветую, а ты уж сам смотри. Если опробуешь, то напиши о результатах, глядишь RXL в ФАК засунет, если посчитает нужным.
Итак, вот она
Цитата
mouse_event Function

--------------------------------------------------------------------------------

The mouse_event function synthesizes mouse motion and button clicks.

Windows NT/2000/XP: This function has been superseded. Use SendInput instead.


Syntax

VOID mouse_event(          DWORD dwFlags,
    DWORD dx,
    DWORD dy,
    DWORD dwData,
    ULONG_PTR dwExtraInfo
);
Parameters

dwFlags
[in] Specifies various aspects of mouse motion and button clicking. This parameter can be certain combinations of the following values.
The values that specify mouse button status are set to indicate changes in status, not ongoing conditions. For example, if the left mouse button is pressed and held down, MOUSEEVENTF_LEFTDOWN is set when the left button is first pressed, but not for subsequent motions. Similarly, MOUSEEVENTF_LEFTUP is set only when the button is first released.

You cannot specify both MOUSEEVENTF_WHEEL and either MOUSEEVENTF_XDOWN or MOUSEEVENTF_XUP simultaneously in the dwFlags parameter, because they both require use of the dwData field.

MOUSEEVENTF_ABSOLUTE
Specifies that the dx and dy parameters contain normalized absolute coordinates. If not set, those parameters contain relative data: the change in position since the last reported position. This flag can be set, or not set, regardless of what kind of mouse or mouse-like device, if any, is connected to the system. For further information about relative mouse motion, see the following Remarks section.
MOUSEEVENTF_MOVE
Specifies that movement occurred.
MOUSEEVENTF_LEFTDOWN
Specifies that the left button is down.
MOUSEEVENTF_LEFTUP
Specifies that the left button is up.
MOUSEEVENTF_RIGHTDOWN
Specifies that the right button is down.
MOUSEEVENTF_RIGHTUP
Specifies that the right button is up.
MOUSEEVENTF_MIDDLEDOWN
Specifies that the middle button is down.
MOUSEEVENTF_MIDDLEUP
Specifies that the middle button is up.
MOUSEEVENTF_WHEEL
Windows NT/2000/XP: Specifies that the wheel has been moved, if the mouse has a wheel. The amount of movement is specified in dwData
MOUSEEVENTF_XDOWN
Windows 2000/XP: Specifies that an X button was pressed.
MOUSEEVENTF_XUP
Windows 2000/XP: Specifies that an X button was released.
dx
[in] Specifies the mouse's absolute position along the x-axis or its amount of motion since the last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is specified as the mouse's actual x-coordinate; relative data is specified as the number of mickeys moved. A mickey is the amount that a mouse has to move for it to report that it has moved.
dy
[in] Specifies the mouse's absolute position along the y-axis or its amount of motion since the last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is specified as the mouse's actual y-coordinate; relative data is specified as the number of mickeys moved.
dwData
[in] If dwFlags contains MOUSEEVENTF_WHEEL, then dwData specifies the amount of wheel movement. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.
Windows 2000/XP: If dwFlags contains MOUSEEVENTF_XDOWN or MOUSEEVENTF_XUP, then dwData specifies which X buttons were pressed or released. This value may be any combination of the following flags.

If dwFlags is not MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, or MOUSEEVENTF_XUP, then dwData should be zero.

XBUTTON1
Set if the first X button was pressed or released.
XBUTTON2
Set if the second X button was pressed or released.
dwExtraInfo
[in] Specifies an additional value associated with the mouse event. An application calls GetMessageExtraInfo to obtain this extra information.
Return Value

This function has no return value.




Remarks

If the mouse has moved, indicated by MOUSEEVENTF_MOVE being set, dx and dy hold information about that motion. The information is specified as absolute or relative integer values.

If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface, (65535,65535) maps onto the lower-right corner.

If the MOUSEEVENTF_ABSOLUTE value is not specified, dx and dy specify relative motions from when the last mouse event was generated (the last reported position). Positive values mean the mouse moved right (or down); negative values mean the mouse moved left (or up).

Relative mouse motion is subject to the settings for mouse speed and acceleration level. An end user sets these values using the Mouse application in Control Panel. An application obtains and sets these values with the SystemParametersInfo function.

The system applies two tests to the specified relative mouse motion when applying acceleration. If the specified distance along either the x or y axis is greater than the first mouse threshold value, and the mouse acceleration level is not zero, the operating system doubles the distance. If the specified distance along either the x- or y-axis is greater than the second mouse threshold value, and the mouse acceleration level is equal to two, the operating system doubles the distance that resulted from applying the first threshold test. It is thus possible for the operating system to multiply relatively-specified mouse motion along the x- or y-axis by up to four times.

Once acceleration has been applied, the system scales the resultant value by the desired mouse speed. Mouse speed can range from 1 (slowest) to 20 (fastest) and represents how much the pointer moves based on the distance the mouse moves. The default value is 10, which results in no additional modification to the mouse motion.

The mouse_event function is used to synthesize mouse events by applications that need to do so. It is also used by applications that need to obtain more information from the mouse than its position and button state. For example, if a tablet manufacturer wants to pass pen-based information to its own applications, it can write a dynamic-link library (DLL) that communicates directly to the tablet hardware, obtains the extra information, and saves it in a queue. The DLL then calls mouse_event with the standard button and x/y position data, along with, in the dwExtraInfo parameter, some pointer or index to the queued extra information. When the application needs the extra information, it calls the DLL with the pointer or index stored in dwExtraInfo, and the DLL returns the extra information.

Function Information

Minimum DLL Version user32.dll
Header Declared in Winuser.h, include Windows.h
Import library User32.lib
Minimum operating systems Windows 95, Windows NT 3.1
Unicode Implemented as Unicode version.


УДачи!!!
« Последнее редактирование: 16-12-2007 16:18 от Алексей1153++ » Записан

ещё один вопрос ...
Megabotan
Участник

ru
Offline Offline

« Ответ #6 : 24-12-2006 18:41 » 

Спасибо, попробуем.
Только ведь ф-ция mouse_event будет по настоящему курсор двигать, т. е. я, когда такое приложение запущено, ничего за компом другого делать не смогу. Если только не породить второй курсор  Улыбаюсь, что вероятно невозможно...
Кстати, никак нельзя просмотреть код фрейма в TWebBrowser, если его домен не совпадает с родительским документо? Я когда пытаюсь обратиться к свойству document фрейма у меня вылетает ошибка "Отказано в доступе", т. е. это Microsoft нарочно придумало. Мож какой обходной путь есть? Я б так просто событие click вызывал бы...
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 24-12-2006 18:47 » 

Ты посмотри, не факт, что если ты вызывешь ее для нажатия, то она и курсор передвинет. Попробуй Улыбаюсь. И написать не знабудь. Ага
Записан

ещё один вопрос ...
zubr
Гость
« Ответ #8 : 27-12-2006 18:05 » 

Вопрос в общем то решается через объектную модель TWebBrowser, что то типа:
WebBrowser1.OleObject.Document.forms.item(0).elements.item(0).click;
Записан
Megabotan
Участник

ru
Offline Offline

« Ответ #9 : 27-12-2006 18:08 » 

В моём случае не решается, я уже выше говорил почему...
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 28-12-2006 06:20 » 

Какие результаты?
Записан

ещё один вопрос ...
Megabotan
Участник

ru
Offline Offline

« Ответ #11 : 28-12-2006 15:20 » 

Вот код, который щёлкает компанент TWebBrowser в точке, удалённой влево на 300 пикселей от центра TWebBrowser:
Код:
procedure TForm1.Button4Click(Sender: TObject);
var Pt, Pos: TPoint;
begin
  Pt.x := WebBrowser1.Left + (WebBrowser1.Width div 2)-300;
  Pt.y := WebBrowser1.Top + (WebBrowser1.Height div 2);
  Pt := ClientToScreen(Pt);
  Pt.x := Round(Pt.x * (65535 / Screen.Width));
  Pt.y := Round(Pt.y * (65535 / Screen.Height));

  GetCursorPos(Pos);
  Pos.x := Round(Pos.x * (65535 / Screen.Width));
  Pos.y := Round(Pos.y * (65535 / Screen.Height));
   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);
   Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pos.x, Pos.y, 0, 0);
end;
Просто вызвать клик не удаётся - нужно обязательно двигать курсор в точку клика.
Мне бы хотелось всё таки sendmessage использовать, единственное что: мне до конца не остался ясен четвёртый параметр dwExtraInfo.
Если окно будет чем-нибудь перекрыто то щёлкаться будет передний план.
« Последнее редактирование: 28-12-2006 16:27 от Megabotan » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines