Необходимо проверить, перекрывается ли окно программы (чужой) другими окнами системы - 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("Окно не перекрыто"); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д