Необходимо проверить, перекрывается ли окно программы (чужой) другими окнами системы - C#
Формулировка задачи:
Необходимо проверить перекрывается ли окно программы(чужой), другими окнами системы.
План таков.
1. Перечислить все поверхностные окна системы
2. Получить hwnd перечисленных окон
3. Получить координаты используя GetWindowRect
4. Перевести координаты в переменные Rectagle
5. Использовать Rectagle.Contains для определения перекрытия.
Я не уверен что выбрал правильное решение. Оно мне кажется очень громоздким. Жду любой помощи, спасибо.
26 строка
Нашёл вот такое дело на делфи. может кто поможет на шарп переложить
// Это - главная функция. На входе - хэндл проверяемого окна, // на выходе - перекрыто оно другими (True), или нет (False). function IsWindowOverlapped(Wnd: HWND): boolean; var OldWnd: HWND; begin // Запомним хэндл окна OldWnd := Wnd; // И пройдемся по всем окнам верхнего уровня в системе, // передав адрес OldWnd, как параметр callback-функции EnumWindows(@EnumWindowProc, LParam(@OldWnd)); // Если OldWnd изменилось, то окно перекрыто Result := OldWnd <> Wnd end; type PWnd = ^HWND; // Это callback-функция для EnumWindows. Пока она не вернет // False, перебор окон продолжается. Wnd - хэндл очередного окна, TargetWnd - адрес переменной OldWnd (см. выше) function EnumWindowProc(Wnd: HWND; TargetWnd: PWnd): BOOL; stdcall; var Rct, TargetRct, OverRct: TRect; P: TPoint; begin // Берем прямоугольник окна Wnd и нашего окна GetWindowRect(Wnd, Rct); GetWindowRect(TargetWnd^, TargetRct); // Проверяем их пересечение Result := not IntersectRect(OverRct, Rct, TargetRct); // Если пересекаются, надо выяснить, какое окно сверху if not Result then begin // Берем центр области пересечения P.X := (OverRct.Left + OverRct.Right) div 2; P.Y := (OverRct.Top + OverRct.Bottom) div 2; // И получаем окно верхнего уровня в этой точке Wnd := GetTopParent(WindowFromPoint(P)); // Если это не наше окно, то надо остановить перебор и в // переменную OldWnd записать хэндл перекрывающего окна Result := Wnd <> TargetWnd^; // Кажется, здесь ошибка, надо = if not Result then TargetWnd^ := Wnd end end; // Это вспомогательная функция. Если Wnd - это хэндл дочернего // окна, то дает его родительское окно верхнего уровня, иначе // дает само это окно function GetTopParent(Wnd: HWND): HWND; begin repeat Result := GetParent(Wnd); if Result <> 0 then Wnd := Result until Result = 0; Result := Wnd end;
Первый пунк вроде готов.
public class WindowArray : ArrayList
{
private delegate bool EnumWindowsCB(int hwnd, IntPtr param);
[DllImport("user32")]
private static extern int EnumWindows(EnumWindowsCB cb, IntPtr param);
private static bool MyEnumWindowsCB(int hwnd, IntPtr param)
{
GCHandle gch = (GCHandle)param;
WindowArray itw = (WindowArray)gch.Target;
itw.Add(hwnd);
return true;
}
public WindowArray()
{
GCHandle gch = GCHandle.Alloc(this);
EnumWindowsCB ewcb = new EnumWindowsCB(MyEnumWindowsCB);
EnumWindows(ewcb, (IntPtr)gch);
gch.Free();
}
}
все же перечисляет он явно больше окон чем реально видимых.
Всё решено кроме непосредственно проверки перекрытия.
Я неправильно понял значение Rectagle.Contains. И она не годится для поставленной задачи.
Имеем координаты, нужно составить условия что бы сравнить два окна.
IntPtr hw0 = FindWindows.FindWindow("Progman", "Program Manager");
EnumWindow.EnumWindows((hWnd, lParam) =>
{
if (IsWindowVisibles.IsWindowVisible(hWnd) == true && proverkashowhide.IsIconic(hWnd) == false && hwnd != hWnd && hWnd != hw0)
{
FindWindowRect.RECT RectAllHwnd = new FindWindowRect.RECT();
FindWindowRect.GetWindowRect(hWnd, ref RectAllHwnd);
Rectangle RDC = new Rectangle(RectAllHwnd.Left, RectAllHwnd.Top, RectAllHwnd.Right - RectAllHwnd.Left, RectAllHwnd.Bottom - RectAllHwnd.Top);
Console.WriteLine(nos);
Console.WriteLine(RDC);
if (nos.Contains(RDC) == true)
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false");
}
}
return true;
}, IntPtr.Zero);
Вроде бы класс получился помогите правильно задать метод что бы возвращались значения true или false
// Класс для проверки на перекрытие
using System; // для IntPtr
using System.Drawing; // Для Rectangle
using System.Runtime.InteropServices; // Для импорта API функций
namespace ConsoleApplication3
{
class IsWindowsIntersect
{
// Функция для проверки видимое ли окно
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindowVisible(IntPtr hWnd);
// Функция для проверки не свёрнуто ли окно
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd);
// Функция для поиска дискриптора по классу и имени окна
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
// Проверка на перекрытие
public static bool intersect(IntPtr hwnd)
{
//Перечисляем все окна системы
EnumWindow.EnumWindows((HWND, lParam) =>
{
// Выполняем если окна видимые
if (IsWindowVisible(HWND) == true)
{
// Выполняем если окно не свёрнуто
if (IsIconic(HWND) == false)
{
// Выполняем если не наше окно для проверки
if (hwnd != HWND)
{
// Выполняем если не окно рабочего стола
if (HWND != FindWindow("Progman", "Program Manager"))
{
FindWindowRect.RECT Recthwnd = new FindWindowRect.RECT();
FindWindowRect.GetWindowRect(hwnd, ref Recthwnd);
FindWindowRect.RECT RectHWND = new FindWindowRect.RECT();
FindWindowRect.GetWindowRect(HWND, ref RectHWND);
Rectangle rectangle1 = new Rectangle(Recthwnd.Left, Recthwnd.Top, Recthwnd.Right - Recthwnd.Left, Recthwnd.Bottom - Recthwnd.Top);
Rectangle rectangle2 = new Rectangle(RectHWND.Left, RectHWND.Top, RectHWND.Right - RectHWND.Left, RectHWND.Bottom - RectHWND.Top);
Rectangle rectangle3 = new Rectangle();
if (rectangle1.IntersectsWith(rectangle2))
{
rectangle3 = Rectangle.Intersect(rectangle1, rectangle2);
if (!rectangle3.IsEmpty)
{
Console.WriteLine("Окно перекрыто");
return true;
}
}
}
}
}
}
return true;
}
, IntPtr.Zero);
Console.WriteLine("Окно не перекрыто");
return false;
}
}
}
public static bool intersect(IntPtr hwnd)
Решение задачи: «Необходимо проверить, перекрывается ли окно программы (чужой) другими окнами системы»
textual
Листинг программы
int ff = 0;
IsWindowsIntersect.Enum(hwnd, ref ff);
if (ff == 1)
{
Console.WriteLine("Окно перекрыто");
}
else
{
Console.WriteLine("Окно не перекрыто");
}