john1990_1 Ответов: 1

Как проверить, открыто ли окно и отображается ли оно на экране, например, нет ли задержки?


Я хочу убедиться, что окно открыто и отображается на экране (с поддержкой более чем одного монитора, конечно), потому что я приказываю Windows подделать щелчок мыши на форме, чтобы Google Translate textbox в браузере был выбран (я много пробовал выбрать его, но он не работает, так как не всегда он выбирается), поэтому я не хочу, чтобы щелчок мыши нажимал на что-то другое, я сделал квадрат цветов 3x3, и я хочу проверить на экране, действительно ли эти 9 цветов находятся на экране, а затем быстро заказать поддельный щелчок мыши, я не получаю правильные цвета, когда я тестирую с этим кодом:

Что я уже пробовал:

private void FormMain_Paint(object sender, PaintEventArgs e)
 {
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50, 1, Color.Gray);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 1,1, Color.DarkGray);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 2, 1, Color.Brown);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50, 2, Color.RosyBrown);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 1, 2, Color.DarkSlateGray);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 2, 2, Color.DarkGray);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50, 3, Color.SlateGray);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 1, 3, Color.LightSlateGray);
     ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 2, 3, Color.LightGray);
 }


if (formMain.WindowState != FormWindowState.Minimized)
                {
                    if ((GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50, 1))) == Color.Gray) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 1, 1))) == Color.DarkGray) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 2, 1))) == Color.Brown) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50, 2))) == Color.RosyBrown) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 1,2))) == Color.DarkSlateGray) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 2, 2))) == Color.DarkGray) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50, 3))) == Color.SlateGray) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 1, 3))) == Color.LightSlateGray) &&
                     (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 2, 3))) == Color.LightGray))
                    {
                        Program.DoMouseClick(formMain.Location.X + formMain.pictureBoxSettings.Right + 1, formMain.Location.Y + formMain.pictureBoxSettings.Top + 100);
                    }
                }


static public void SetPixel(Control control, int x, int y, Color color)
        {
            if (control != null)
            {
                IntPtr hDC = GetDC(control.Handle);
                int argb = color.ToArgb();
                int colorRef =
                    (int)((argb & 0x00FF0000) >> 16) |
                    (int)(argb & 0x0000FF00) |
                    (int)((argb & 0x000000FF) << 16);
                SetPixel(hDC, x, y, colorRef);
                ReleaseDC(control.Handle, hDC);
            }
        }


static Color GetPixel(Point p)
{
    using (var bitmap = new Bitmap(1, 1))
    {
        using (var graphics = Graphics.FromImage(bitmap))
        {

            graphics.CopyFromScreen(p, new Point(0, 0), new Size(1, 1));
        }
        return bitmap.GetPixel(0, 0);
    }
}

Richard MacCutchan

Какие цвета вы получаете? Вы уверены, что ваши пиксельные адреса верны?

john1990_1

Я сделал цвет c=GetColor(); первого адреса, и он вернул случайный и неназванный цвет (так как "именованный цвет" был ложным), однако когда я делаю щелчок мыши на первом местоположении, он правильно нажимает на местоположение нарисованных пикселей... может быть, это из-за размытия панели формы (окна), и мне следует немного уменьшить пиксели, чтобы убежать от размытия.

john1990_1

Поместить пиксели в положение Y=20,21,22 не получилось.

Richard MacCutchan

Одна из проблем с этим может заключаться в том, что Windows управляет физическим экраном, и часто цвета будут объединены, так что то, что вы рисуете в форме, фактически изменяется, когда оно отображается на экране.

john1990_1

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

Richard MacCutchan

Вам нужно использовать отладчик, чтобы точно проверить, какие пиксельные адреса возвращаются из PointToScreen назовите, и какие значения цвета в каждой точке.

john1990_1

Когда я вызываю движение мыши к местоположению PointToScreen, оно идет к середине моего квадрата 3x3. Хотите увидеть полный исходный код vs? как я могу поделиться этим?

Richard MacCutchan

Извините, но я не хочу видеть полный исходный код, так как у меня нет времени изучать весь ваш код.

john1990_1

Никаких проблем, никаких догадок, почему это не работает?

Richard MacCutchan

По моему опыту, догадки никогда не срабатывают. Единственный способ узнать это-использовать отладчик, чтобы увидеть, что происходит внутри кода.

john1990_1

Я думаю, что проблема заключается в том, что у меня есть 4 экрана, как сказать GetPixel искать точку в координатах 4 экранов. (например, 3 на столе и один выше)

john1990_1

Что делать, если windows находится на 2 или более мониторах одновременно?

Richard MacCutchan

Затем вам придется попробовать несколько вещей и проверить документацию MSDN.

john1990_1

Я добавил свой метод "GetPixel", проверьте его PLZ.

Richard MacCutchan

Извините, но я не совсем понимаю, о чем вы спрашиваете. Как я уже говорил ранее, вам нужно потратить время с отладчиком, чтобы точно проверить, что происходит в вашем коде. Это не то, что кто-то другой может сделать для вас.

john1990_1

Я долго отлаживал и зашел в тупик, а что, если речь идет о масштабировании экранов Windows?

john1990_1

Речь идет о том, что масштабирование экранов рабочего стола Windows составляет 150%, это сработало, когда я сделал масштабирование 100%, как это исправить (заставить программу учитывать масштабирование)?

Richard MacCutchan

Вы, вероятно, достигли точки, когда ваши исходные цвета были "отрегулированы" Windows для отображения увеличенных изображений. Но я понятия не имею, что вы можете сделать в таком случае. Вероятно, вам придется переосмыслить то, чего вы пытаетесь достичь.

john1990_1

Цвета точно такие же, просто я не могу добраться до их истинного местоположения, так как один способ дает мне местоположение при 100% - ном увеличении и один при 150% - ном увеличении, я проверил его и увидел, что он получает изображение не в нужном месте, но когда я сделал масштабирование на 100% на всех экранах, я получил истинное изображение формы (когда я отправил координаты формы и размер в новом размере(200,200)).

john1990_1

Я хочу установить фокус ввода на исходном текстовом поле в элементе управления веб-браузером в форме, когда форма открывается или нажимается F1, я пытался очень долго, но ни один способ не работал безупречно, кроме вызова щелчка мыши на пустом пикселе в форме.

Richard MacCutchan

Это не то, что я сделал, но могут быть классы .NET, которые могут найти элементы управления в другой форме.

1 Ответов

Рейтинг:
2

#realJSOP

Visual Studio поставляется с инструментом под названием "Spy++". Используйте его, чтобы найти элементы управления в данном окне. Чтобы управлять элементом управления в окне внешнего приложения, вам потребуется использовать System.Runtime.InteropServices.

Вам нужно будет найти этот инструмент, потому что VS больше не помещает ярлык для него в меню Пуск windows. Я нашел его и добавил пользовательский пункт в меню Tools в VS.


john1990_1

Делает ли это способ убедиться, что окно не находится в лаге и на самом деле отображается на экране с цветами? Я имею в виду, это то же самое, как если бы один из них назывался GetPixel на дисплее, он обнаруживает цвета, показанные на окне, и он не открывается или запаздывает?

#realJSOP

Не имеет ничего общего с цветами - просто позволяет найти окна и элементы управления, которые в данный момент активны в windows.Z однако, как только вы найдете нужное окно управления, вы можете обнаружить любые свойства окна, которые вам могут понадобиться. Это потребует некоторого гугления с вашей стороны. Вы можете использовать Spy++ для проверки данного окна, чтобы увидеть, если вы можете получить наводку на то, что искать. Предостережение: нет никакого "быстрого способа" узнать, что делать, если только вы случайно не наткнетесь на довольно полную сборку, содержащую все необходимые вызовы InteropServices.

john1990_1

Я хочу вызвать щелчок мыши по пустой точке на форме, чтобы выбрать ввод в исходное текстовое поле Google Translate, я хочу убедиться, что форма отображается, я хочу проверить цвета на дисплее, которые находятся в форме, так что щелчок не идет по душе посту на FB или что-то еще, как я могу убедиться, что окно не находится в лаге и его цвета действительно находятся на дисплее? делает ли метод, который вы предлагаете, убедитесь, что щелчок не переходит в другое окно, если моя программа находится в лаге для отображения на дисплее?

#realJSOP

Вы можете использовать InteropServices для отправки окну события. Я не знаю (или мне все равно), что вы хотите сделать, но это можно (и, вероятно, требуется) сделать с помощью interopservices, поскольку это включает в себя другое окно во внешнем приложении. Как я уже упоминал, google-ваш друг.

Кстати, хорошая "пустая точка" - это верхний/левый пиксель клиентской области окна. Там почти никогда нет контроля. Цвет пикселя в этой точке не имеет значения.

john1990_1

You don't understand, I have a Windows Forms program, in this program there's a web browser control, in this web browser control Google Translate is sometimes navigated to, I want to focus on the "source" textbox in the web browser control, I tried many way and I didn't find a way that always does select the input on the source textbox, I fake a mouse click from my program on my program, on an empty place in my program (not on the browser control), I want this click from my program to my program, I want to make sure that my program is shown on the display and isn't lagging to open, because if my program thinks my program is shown on the display and it does a click thinking my program is there to catch the click, the click my be clicked on "Like" on FB if my window of my program wasn't shown on the display!

#realJSOP

0) для протокола, ваши описания проблем отстой.

1) вам не нужно "имитировать щелчок мыши". Просто вызовите метод Focus() элемента управления.

2) Узнайте, что такое идентификатор текстового поля. Вы можете сделать это, перейдя на страницу google translate во внешнем браузере и просмотрев исходный код.

3) в своем коде используйте HTMLAgilityPack (установите его в свой проект с помощью NuGet), чтобы проанализировать страницу и найти элемент управления, когда он просматривается в вашем приложении. Оттуда это просто вопрос манипулирования DOM, чтобы сделать то, что вы хотите сделать.

john1990_1

Я делал это миллион раз, я называю wb.Focus(); и wb.Document.GetElementByID("источник").InvokeMember("фокус"); и многие другие подобные вещи. Он выбирается только иногда, и я понял, что это не может быть сделано таким образом, если вы можете исправить это так, то потрясающе! в противном случае, пожалуйста, помогите мне убедиться, что фальшивый щелчок мыши не переходит к чему-то другому в этой точке дисплея.

#realJSOP

Я просто хватаюсь за соломинку здесь, но попробуйте InvokeMember("щелчок") или InvokeMember("mouseup").

Кроме того, сделайте это таким образом:

HTMLNode ctrl = wb.Document.GetElementByID("source"); 
if (ctrl != null)
{
    ctrl.InvokeMember("click");
}

Таким образом, вы можете поставить точку останова и посмотреть, что происходит.

john1990_1

Я попытаюсь опубликовать программу на своем жестком диске для тестирования, не могли бы вы сообщить мне все имена методов в "InvokeMember" или то, что я могу попросить свою программу сделать в веб-браузере, чтобы было выбрано исходное текстовое поле? Например, может быть, "InvokeScript" лучше работает для выбора исходного текстового поля?

#realJSOP

Черт возьми, погугли это, чувак. Подсказка - это события javascript.

Richard MacCutchan

Не сдерживайся, Джон, скажи, что ты чувствуешь. :) :)

john1990_1

Это все, что я смог придумать.:
Объект HTMLElement textArea1 = formMain.webBrowserGoogleTranslate.Документ.GetElementById("источник");
if (textArea1 != null)
{
formMain.webBrowserGoogleTranslate.Документ.InvokeScript("'click'", new object[] { textArea1 });
}

#realJSOP

Этот парень не может быть из США (как указано в его профиле). Нас, программистов, не как правило, это F*скин беспомощным...

john1990_1

Я знаю только C# из школы, и я любитель, я изучаю биологию, не могли бы вы помочь мне исправить риск в моей программе, чтобы убедиться, что никто из моих друзей, которые используют мою программу, и я в конечном итоге с случайным щелчком мыши в Facebook?