С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
8 / 8 / 4
Регистрация: 23.07.2012
Сообщений: 261

Необходимо проверить, перекрывается ли окно программы (чужой) другими окнами системы

09.02.2015, 17:01. Показов 2362. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Необходимо проверить перекрывается ли окно программы(чужой), другими окнами системы.

План таков.

1. Перечислить все поверхностные окна системы
2. Получить hwnd перечисленных окон
3. Получить координаты используя GetWindowRect
4. Перевести координаты в переменные Rectagle
5. Использовать Rectagle.Contains для определения перекрытия.

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

Добавлено через 46 минут
Нашёл вот такое дело на делфи. может кто поможет на шарп переложить

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Это - главная функция. На входе - хэндл проверяемого окна,
// на выходе - перекрыто оно другими (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;
Добавлено через 44 минуты
Первый пунк вроде готов.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        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();
            }
        }
Добавлено через 33 минуты
все же перечисляет он явно больше окон чем реально видимых.

Добавлено через 4 часа 33 минуты
Всё решено кроме непосредственно проверки перекрытия.

Я неправильно понял значение Rectagle.Contains. И она не годится для поставленной задачи.

Имеем координаты, нужно составить условия что бы сравнить два окна.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
Добавлено через 7 часов 9 минут
Вроде бы класс получился помогите правильно задать метод что бы возвращались значения true или false

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Класс для проверки на перекрытие
 
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;
        }
    }
}
Добавлено через 32 секунды
Цитата Сообщение от riotel Посмотреть сообщение
public static bool intersect(IntPtr hwnd)
26 строка
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.02.2015, 17:01
Ответы с готовыми решениями:

Почему форма fsSystemStayOnTop иногда перекрывается другими окнами?
Окно программы, которое должно быть поверх всех окон, иногда все же прячется за другими приложениями. Можно ли что-нибудь сделать, чтобы...

Как сделать всплывающее окно над всеми другими окнами
написал простенькую программу - таймер: Private Sub start_Click() Dim j As Integer, h As Byte, m As Byte, s As Byte ...

Окна программы перекрываются другими окнами
Добрый день всем! У меня возникла проблема - в моем проекте несколько форм, многие из них вызываются методом ShowDialog() из...

3
8 / 8 / 4
Регистрация: 23.07.2012
Сообщений: 261
11.02.2015, 14:45  [ТС]
После многочисленных извращений полуилось вот что

Добавлено через 1 минуту
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Класс для проверки на перекрытие
 
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 delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool EnumWindows(EnumWindowsProc callback, IntPtr extraData);
 
        public static void Enum(IntPtr hwndmain, ref int perecritie)
        {
            int per = 0;
            EnumWindows((hwndenum, lParam) =>
            {
                if (intersect(hwndmain, hwndenum) == false)
                {
                    per = 1;
                    return false;
                }
                else
                {
                    return true;
                }
            }
            , IntPtr.Zero);
 
            if (per == 1)
            {
                perecritie = 1;
            }
            else
            {
                perecritie = 0;
            }
        }
 
        // Проверка на перекрытие
        public static bool intersect(IntPtr hwndmain, IntPtr hwndenum)
        {
            // Выполняем если окно видимое
            if (IsWindowVisible(hwndenum) == true)
            {
                // Выполняем если окно не свёрнуто
                if (IsIconic(hwndenum) == false)
                {
                    // Выполняем если не наше окно для проверки
                    if (hwndmain != hwndenum)
                    {
                        // Выполняем если не окно рабочего стола
                        if (hwndenum != FindWindow("Progman", "Program Manager"))
                        {
                            FindWindowRect.RECT Recthwnd = new FindWindowRect.RECT();
                            FindWindowRect.GetWindowRect(hwndmain, ref Recthwnd);
 
                            FindWindowRect.RECT RectHWND = new FindWindowRect.RECT();
                            FindWindowRect.GetWindowRect(hwndenum, 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)
                                {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
                    int ff = 0;
                    IsWindowsIntersect.Enum(hwnd, ref ff);
                    if (ff == 1)
                    {
                        Console.WriteLine("Окно перекрыто");
                    }
                    else
                    {
                        Console.WriteLine("Окно не перекрыто");
                    }
Всё работает. Но вопрос по совершенствованию кода открыт.
0
 Аватар для Sanya_sa
912 / 816 / 333
Регистрация: 03.02.2015
Сообщений: 5,276
Записей в блоге: 9
11.02.2015, 17:19
Если форма "перекрыта" другими формами значит она не активна. Не проще проверить ActiveForm?

Добавлено через 2 минуты
Стоп скорее даже Focused проверить.
1
8 / 8 / 4
Регистрация: 23.07.2012
Сообщений: 261
11.02.2015, 18:07  [ТС]
Дело в том что она может быть и не активна , но не перекрыта

Добавлено через 21 минуту
Что выполняет фокус?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.02.2015, 18:07
Помогаю со студенческими работами здесь

Встроить свое окно в окно чужой программы
Что то я не могу допереть как такое можно организовать,Хочу свое окно в чужую программу встроить,пример такой программы spy++ там основные...

Выпадающее меню перекрывается другими слоями
Доброго времени, уважаемые! У меня такая проблема: есть выпадающее меню в шапке сайта, когда наводишь курсор на него часть скрывается...

Выпадающее меню перекрывается другими слоями
Добрый день,уважаемые программисты) У меня такая проблема: на сайте uslugi34.ru есть выпадающее меню в шапке сайта но когда они...

Как сделать, чтоб моя программы стояла рядышком с другими (чужими) окнами, как на рисунке
Есть форма. Она простая. На нём указала поверх всех окон StayOnTop. Но мне надо, чтоб моя форма и чужие программы когда они открыты на весь...

Как сделать окно чужой программы невидимым?
Как сделать окно чужой программы невидимым?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru