Как надежно найти активное окно, когда оно не фокусируется

Так, я думал, что это будет просто, и, ну, в общем, я был неправ. Вот упрощенное описание проблемы:

Я пишу небольшое приложение для наших производственных людей, которые захватят снимок экрана всего рабочего стола, а также активного окна, когда они нажмут значок приложения в системном лотке. В настоящее время я использую метод Win32 "GetforegroundWindow" в Событии mouseMove NotifyIcon, чтобы сохранить дескриптор активного окна и сделать снимок экрана в событии Click.

Это действительно иногда работает, но если я нажимаю значок очень быстро, я на самом деле получаю панель задач вместо активного окна. Я не уверен, почему это происходит (я действительно понимаю, что панель задач является окном, я не понимаю, почему иногда это, кажется, фокусируется в MouseMove, прежде чем я нажал), и у меня было мало удачи с помощью метода EnumWindows также, вероятно, потому что я не полностью понимаю, как это работает.

Казалось бы, что, если бы я смог получить z положение каждого окна с помощью только дескриптор окна, это было бы легкой проблемой для решения использования EnumWindows. Я не нашел, что метод делает это как бы то ни было.

Так, я спрашиваю Вас парни; как Вы записали бы метод для определения местоположения активного окна надежно, учитывая, что оно не может сфокусироваться в то время? Или мой google-fu приводит к сбою меня или информацию об этом, редко.Заранее спасибо.

6
задан Ed S. 26 February 2010 в 18:36
поделиться

2 ответа

Единственный способ предотвратить расширение клеток - использовать это...

table { table-layout: fixed; width: 500px; }
table td { overflow:hidden; }

Хотя интересной попыткой было бы сделать div относительно позиционированным, а затем установить вход как абсолютный...

td div { position: relative; }
td div input { position: absolute; }

Абсолютно позиционированные элементы не вызывают расширения, и их исходное положение основано на первом относительно позиционированном родительском элементе.

-121--5085920-

Возможно, используется ограничивающая окружность. В основном, при создании объекта Collidable трека его центральную точку и вычислите радиус/диаметр, содержащий весь объект. Вы можете сделать первый проход устранение, используя что-то вроде;

int r = C1.BoundingRadius + C2.BoundingRadius;

if( Math.Abs(C1.X - C2.X) > r && Math.Abs(C1.Y - C2.Y) > r )
/// Skip further checks...

Это сбрасывает сравнения до двух для большинства объектов, но насколько это получит вас я не уверен... профиль!

-121--2579263-

Панель задач является максимально допустимым окном переднего плана. При нажатии на него оно временно будет окном переднего плана. Если нажать, например, кнопку Пуск (Start) и нажать клавишу Escape (Escape), то это будет окно переднего плана, пока вы не нажмете на него.

Можно использовать GetWindow с HWND_NEXT, передаваемыми в дескрипторе окна панели задач.

Nevermind, поскольку панель задач является самым верхним окном, GetWindow (или GetNextWindow и т.д.) будет работать по-другому. Я бы предложил вернуться к решению EnumWindows , которое, вероятно, является вашей лучшей ставкой.

1
ответ дан 17 December 2019 в 22:12
поделиться

Если форма, снимок которой вы хотите получить, такая же, как и форма, связанная с панелью задач, вам действительно не нужно использовать GetforegroundWindow. Просто используйте Form.hWnd и передайте его в функцию, получающую снимок. Вам может понадобиться сделать его верхним окном, вызвав

[DllImport( "user32.dll" )]
public static extern IntPtr SetForegroundWindow( IntPtr hWnd );

или

[DllImport( "user32.dll" )]
public static extern bool BringWindowToTop( HandleRef hWnd );

Если вы хотите получить весь рабочий стол, то, вероятно, вам просто нужно вставить Thread.Sleep, чтобы убедиться, что окно переднего плана успело подняться на верхний план до получения снимка рабочего стола.

помещаю src из моего комментария сюда для лучшей печати

[DllImport( "user32.dll" )]
public static extern IntPtr GetForegroundWindow();

[DllImport( "user32.dll" )] 
public static extern IntPtr GetActiveWindow(); 

// this or the next line not both
IntPtr curWindow = GetActiveWindow(); 
IntPtr curWindow = GetForegroundWindow(); 

BringWindowToTop( window ); 
System.Threading.Thread.Sleep( 500 ); 

Где поток spleep дает окну достаточно времени, чтобы прийти к вершине в порядке Z.

0
ответ дан 17 December 2019 в 22:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: