none
Как отслеживать положение курсора над webBrowser1? RRS feed

  • Вопрос

  • На форме есть контрол webBrowser1. У него не нашел события MouseMove. А мне нужно знать координаты курсора.

    Т.е. есть форма, на которой кнопки, лейблы и webBrowser1.

    Для формы создал событие:

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
       label1.Text = "X = " + e.X.ToString() + ", " + e.Y.ToString();
    }

    Но, оно работает только на кусках формы, которые не заняты какими-то контролами.

    1)  Что сделать, что бы получить координаты курсора над контролом webBrowser1?

    2)  Что сделать, что бы произошло событие «нажатия кнопки мыши» по заданным координатам над webBrowser1?

    • Изменено sg6336 2 мая 2012 г. 21:56

Ответы

  • Ночью, основываясь на идеях из
    http://www.geekpedia.com/code139_Simulate-Mouse-Click-On-WebBrowser-Control.html

    http://balakhonov-yuriy.ru/как-из-c-программно-нажать-html-кнопку-в-док/

    составил вот такую программу:

    public partial class Form1 : Form
        {
           
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                webBrowser1.Navigate(@"http://www.abc.ru/abc");
            }
    
            
            private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                timer1.Start();                
            }
    
            int step = 0;
            string[] MyArr = new string[4] { "name0", "name1", "name2", "name3"};
            int i = 0;
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (step == 0) timer1.Interval = 1000; //переходим на малый цикл
    
                if (step == 0) Cursor.Position = webBrowser1.PointToScreen(new Point(420, 120)); //нажимаем Мир
                if (step == 5) Cursor.Position = webBrowser1.PointToScreen(new Point(520, 450)); //разворачиваем Искать по имени
                if (step == 8) //вводим имя кормушки (добавить смену кормушек)
                {
                    Cursor.Position = webBrowser1.PointToScreen(new Point(520, 480));
                    SendKeys.Send(MyArr[i]); i++; if (i >= 4) i = 0;
                }
                if (step == 10) Cursor.Position = webBrowser1.PointToScreen(new Point(650, 480)); //нажимаем Искать
                if (step == 15) Cursor.Position = webBrowser1.PointToScreen(new Point(380, 620)); //нажимаем Атаковать
                if (step == 20) Cursor.Position = webBrowser1.PointToScreen(new Point(520, 660)); //выбираем Макс воинов
                if (step == 22) Cursor.Position = webBrowser1.PointToScreen(new Point(470, 720));
                
    
                if (step == 0 | step == 5 | step == 10 | step == 15 | step == 20 | step == 22)
                {
                    Point ScreenCoord = new Point(MousePosition.X, MousePosition.Y);
                    Point BrowserCoord = webBrowser1.PointToClient(ScreenCoord);
                    HtmlElement elem = webBrowser1.Document.GetElementFromPoint(BrowserCoord);
                    object obj = elem.DomElement;
                    System.Reflection.MethodInfo mi = obj.GetType().GetMethod("click");
                    mi.Invoke(obj, new object[0]);
                }
                step++;
                if (step > 25) { step = 0; timer1.Interval = 15 * 60 * 1000; } //запускаем длинный цикл (сюда же можно вставить смену кормушки)
            }
        }

    т.е. после загрузки страницы, включается таймер. В течение 25 секунд происходят перемещения курсора мыши и нажатие на элементы страницы, которые находятся под  курсором мыши (по заданным координатам). До конца не понимаю, как это происходит. Ну, программа сама определяет, что за элемент в заданных координатах и выполняет нужное действие (нажатие или ввод текста).
    Но, данная программа работает, если к компу не прикасаться. А форма данной программы является активной.

    Можно ли сделать такую программу, что бы она работала в фоновом режиме?

    Т.е. у меня стоит задача именно по координатам вызывать нужный элемент, на странице загруженной в webBrowser1.
    Т.к. предполагается, что название html компонентов будет периодически меняться. Т.е. привязаться к тегам ID или name не получится.
    А в дальней перспективе, хотелось бы, что бы эта программа работала и с флешь компонентами (пока еще не думал над этим).

    Подскажите, как сделать программу, которая эмулирует действия пользователя на сайте? Но, при этом, чтобы не было привязки к тегам html, а была привязка к указанным координатам в поле webBrowser1.

    • Помечено в качестве ответа sg6336 3 мая 2012 г. 7:58

Все ответы

  • 1) Если вам нужен глобальный перехватчик события движения мыши, то это можно сделать вот так.

    2) По второму вопросу, не очень понятно, какая у вас стоит задача. Можно чуть поподробнее, чего вы хотите добиться? Не как, а именно чего...

    Отвечающий
  • Ночью, основываясь на идеях из
    http://www.geekpedia.com/code139_Simulate-Mouse-Click-On-WebBrowser-Control.html

    http://balakhonov-yuriy.ru/как-из-c-программно-нажать-html-кнопку-в-док/

    составил вот такую программу:

    public partial class Form1 : Form
        {
           
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                webBrowser1.Navigate(@"http://www.abc.ru/abc");
            }
    
            
            private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                timer1.Start();                
            }
    
            int step = 0;
            string[] MyArr = new string[4] { "name0", "name1", "name2", "name3"};
            int i = 0;
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (step == 0) timer1.Interval = 1000; //переходим на малый цикл
    
                if (step == 0) Cursor.Position = webBrowser1.PointToScreen(new Point(420, 120)); //нажимаем Мир
                if (step == 5) Cursor.Position = webBrowser1.PointToScreen(new Point(520, 450)); //разворачиваем Искать по имени
                if (step == 8) //вводим имя кормушки (добавить смену кормушек)
                {
                    Cursor.Position = webBrowser1.PointToScreen(new Point(520, 480));
                    SendKeys.Send(MyArr[i]); i++; if (i >= 4) i = 0;
                }
                if (step == 10) Cursor.Position = webBrowser1.PointToScreen(new Point(650, 480)); //нажимаем Искать
                if (step == 15) Cursor.Position = webBrowser1.PointToScreen(new Point(380, 620)); //нажимаем Атаковать
                if (step == 20) Cursor.Position = webBrowser1.PointToScreen(new Point(520, 660)); //выбираем Макс воинов
                if (step == 22) Cursor.Position = webBrowser1.PointToScreen(new Point(470, 720));
                
    
                if (step == 0 | step == 5 | step == 10 | step == 15 | step == 20 | step == 22)
                {
                    Point ScreenCoord = new Point(MousePosition.X, MousePosition.Y);
                    Point BrowserCoord = webBrowser1.PointToClient(ScreenCoord);
                    HtmlElement elem = webBrowser1.Document.GetElementFromPoint(BrowserCoord);
                    object obj = elem.DomElement;
                    System.Reflection.MethodInfo mi = obj.GetType().GetMethod("click");
                    mi.Invoke(obj, new object[0]);
                }
                step++;
                if (step > 25) { step = 0; timer1.Interval = 15 * 60 * 1000; } //запускаем длинный цикл (сюда же можно вставить смену кормушки)
            }
        }

    т.е. после загрузки страницы, включается таймер. В течение 25 секунд происходят перемещения курсора мыши и нажатие на элементы страницы, которые находятся под  курсором мыши (по заданным координатам). До конца не понимаю, как это происходит. Ну, программа сама определяет, что за элемент в заданных координатах и выполняет нужное действие (нажатие или ввод текста).
    Но, данная программа работает, если к компу не прикасаться. А форма данной программы является активной.

    Можно ли сделать такую программу, что бы она работала в фоновом режиме?

    Т.е. у меня стоит задача именно по координатам вызывать нужный элемент, на странице загруженной в webBrowser1.
    Т.к. предполагается, что название html компонентов будет периодически меняться. Т.е. привязаться к тегам ID или name не получится.
    А в дальней перспективе, хотелось бы, что бы эта программа работала и с флешь компонентами (пока еще не думал над этим).

    Подскажите, как сделать программу, которая эмулирует действия пользователя на сайте? Но, при этом, чтобы не было привязки к тегам html, а была привязка к указанным координатам в поле webBrowser1.

    • Помечено в качестве ответа sg6336 3 мая 2012 г. 7:58
  • Передавать клики мышкой в свернутое приложение у вас не получиться. Если вы хотите написать бота, который действует по заданному алгоритму, который вы ему задали 1 раз, можете воспользоваться CodeUI тестами. Вроде они когда генерят код, он может выполняться и на свернутом окне.

    Про CodeUI на русском, с ход не нашел. Но вот можете посмотреть видео.



    Отвечающий
  • Пример, конечно, навороченный. Только как его переделать, что бы показывались координаты в пределах формы?

    Т.е. что бы выполнялось такое действие:

    private void Form1_MouseMove(object sender, MouseEventArgs e)
            {
                label1.Text = "X = " + e.X.ToString() + ", " + e.Y.ToString();
            }
    

    В этом случае координаты X и Y показаны относительно верхнего левого угла формы

    Т.е. предложенный Вами пример прекрасно работает над полем webBrowser1. Но, мне нужны координаты именно относительно верхнего левого угла webBrowser1.

    P.S. Можно, конечно форму поместить в верхний левый угол экрана и считывать, таким образом, все показатели координат.

  • А обновление до Visual Studio 2010 Beta2 бесплатно?

  • Дело в том, что beta2, это то, что было еще до релиза VS 2010. Т.е. вы можете "отктиться" до беты. Но не обновиться. Сейчас доступна Visual Studio 11 Beta. Можете поставить ее, а зарелизить ее обещают летом.
    Отвечающий
  • Вычитайте из координат которые получаете, координаты левого верхнего угла формы и координаты левого верхнего угла webbrauser. Будите получать координаты относительно webbrauser.
    Отвечающий
  • Про CodeUI на русском

    Практическое руководство. Создание закодированного теста пользовательского интерфейса

    Но, только что вчитался в свой код:

    ...
    if (step == 22) Cursor.Position = webBrowser1.PointToScreen(new Point(470, 720));
    
                if (step == 0 | step == 5 | step == 10 | step == 15 | step == 20 | step == 22)
                {
                    Point ScreenCoord = new Point(MousePosition.X, MousePosition.Y);
                    Point BrowserCoord = webBrowser1.PointToClient(ScreenCoord);
                    HtmlElement elem = webBrowser1.Document.GetElementFromPoint(BrowserCoord);
    ...

    Фактически, ведь уже известны координаты?
    Сегодня поробую переделать, текст программы, что бы в 

    HtmlElement elem = webBrowser1.Document.GetElementFromPoint(BrowserCoord);

    задаваллись координаты на прямую. Может, тогда в фоновом режиме запустится программа?


    • Изменено sg6336 3 мая 2012 г. 6:37
  • Продолжение вопросов по данной теме в Как сделать программу работающей в свернутом режиме (бот для webBrowser)?

    Где в топике уже есть работающий код, не привязанный к курсору мыши. А привязанный только к координатам в webBrowser1.

    • Помечено в качестве ответа sg6336 3 мая 2012 г. 8:00
    • Снята пометка об ответе Abolmasov Dmitry 4 мая 2012 г. 9:26
  • Почему вы ищите элементы визуально и задаете какие то абсолютные величины координат? Разве нельзя найти нужный элемент в разметке, пройтись по Dom дереву или получить элемент по Id, т.е. пользуясь методами HtmlDocument.GetElementsByTagName и HtmlDocument.GetElementById и уже для найденных элементов вызывать событие click, как это вы делаете.


    Для связи [mail]