Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/65: Рейтинг темы: голосов - 65, средняя оценка - 4.77
3 / 3 / 1
Регистрация: 30.05.2011
Сообщений: 8

FindWindow на несколько форм, где класс и название окна абсолютно одинаковы

05.12.2012, 13:24. Показов 12872. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго дня.
Вот такая проблема: запущено 3 окна одного и того же приложения, то есть класс и название окна абсолютно одинаковы. Нужно с помощью функции FindWindow найти эти 3 окна и запомнить их.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
 
namespace test
{
    class Program
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        
        static void Main(string[] args)
        {
              IntPtr proc = FindWindow("{класс окна}", "{имя окна}");
              Console.WriteLine(Convert.ToString(proc));
        }
    }
}
Проблема в том, что данная функции всегда ищет первое попавшееся окно и с помощью цикла найти остальные не получается.

Добавлено через 5 минут
P.S. если быть более точным, необходимо сделать так: запускается окно, тыкаем кнопку, запоминаем это окно; запускаем второе окно, тыкаем кнопку, запоминаем это окно; и тоже самое с третьим.

Добавлено через 1 час 45 минут
Промежуточный вариант реализации таков: забываем про FindWindow и используем функции GetTopWindow, GetWindow, GetClassName:
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
 
namespace test
{
    class Program
    {
        //Ищем хэндл первого окна в Z-последовательности - начальная точка поиска
        [DllImport("user32.dll")]
        static extern IntPtr GetTopWindow(IntPtr hWnd);
 
        //Функция для поиска хэндла следующего окна в Z-последовательности
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
        enum GetWindow_Cmd : uint
        {
            GW_HWNDFIRST = 0,
            GW_HWNDLAST = 1,
            GW_HWNDNEXT = 2,
            GW_HWNDPREV = 3,
            GW_OWNER = 4,
            GW_CHILD = 5,
            GW_ENABLEDPOPUP = 6
        }
 
        //Функция получения класса окна
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
 
        static void Main(string[] args)
        {
            IntPtr proc = new IntPtr();
            IntPtr proc2 = new IntPtr();
            IntPtr proc3 = new IntPtr();
            IntPtr Localproc = new IntPtr();
            int c = 0;
            int z;
            int count = 31;//количество символов в названии класса окна + 1 символ
            StringBuilder strB = new StringBuilder();
 
            Localproc = GetTopWindow((IntPtr)null);//ищем первое окно
            while (c != 3)//смотрим окна, пока 3 раза не найдем нужный класс
            {
                z = GetClassName(Localproc, strB, count);// в strB записываем класс окна
                if (strB.ToString() == "{класс окна}")
                {
                    if (c == 0)
                        proc = Localproc;
                    if (c == 1)
                        proc2 = Localproc;
                    if (c == 2)
                        proc3 = Localproc;
                    c++;
                }
                z = 0;
                strB = strB.Clear();
                Localproc = GetWindow(Localproc, 2);//получаем хэндл следующего окна
            }
            Console.WriteLine(Convert.ToString(proc));
            Console.WriteLine(Convert.ToString(proc2));
            Console.WriteLine(Convert.ToString(proc3));
        }
    }
}
Иногда случается косяк и
C#
1
 Localproc = GetTopWindow((IntPtr)null);
получает не то, что нужно, из-за чего программа закрывается с ошибкой (не помогает даже try{} catch{}).

Добавлено через 2 часа 17 минут
Иногда программа вылетает после выполнения этой строки:
C#
1
z = GetClassName(Localproc, strB, count);
Точнее закрывается с ошибкой vshost32.exe, ну и соответственно данная программа. С чем это может быть связано?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.12.2012, 13:24
Ответы с готовыми решениями:

Как задать имя окна браузера Амиго для поиска дескриптора окна FindWindow
var h: HWND; begin h := FindWindow(nil, 'Amigo'); if h > 0 then По Amigo результат h нулевой, я так понял, не...

FindWindow и одинаковые окна
Запущено два калькулятора, нужно получить Handle обоих, как это сделать?

FindWindow для русского заголовка окна
Добрый день! Пытаюсь использоваьт функцию FindWindow для получения Handle окна с русским заголовком. Функция всегда возвращает нулевое...

5
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
08.12.2012, 20:34
Здравствуйте!
Вам нужна функция FindWindowByCaption(IntPtr, string):

C#
1
2
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
Работаете с ней, как с обычной FindWindow, но передаете в качестве параметра и надпись в заголовке окна, при этом желательно передавать этой функции в качестве дескриптора окна - (0) IntPtr.Zero, например:

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
public static void ShowWindow(string windowName, IntPtr handleMain)
            {
                IntPtr handle = FindWindowByCaption(handleMain, windowName);
                if (handle != IntPtr.Zero)
                    ShowWindow(handle);
            }
            public static void ShowWindow(IntPtr handleWindow)
            {
                ShowWindow(handleWindow, ShowWindowCommand.Restore);
                SetForegroundWindow(handleWindow);
            }
 
[DllImport("user32.dll", SetLastError = true)]
            private static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow);
 
[DllImport("user32.dll", SetLastError = true)]
            private static extern bool SetForegroundWindow(IntPtr hWnd);
 
private enum ShowWindowCommand
            {
                /// <summary>
                /// Hides the window and activates another window.
                /// </summary>
                Hide = 0,
                /// <summary>
                /// Activates and displays a window. If the window is minimized or 
                /// maximized, the system restores it to its original size and position.
                /// An application should specify this flag when displaying the window 
                /// for the first time.
                /// </summary>
                Normal = 1,
                /// <summary>
                /// Activates the window and displays it as a minimized window.
                /// </summary>
                ShowMinimized = 2,
                /// <summary>
                /// Maximizes the specified window.
                /// </summary>
                Maximize = 3, // is this the right value?
                /// <summary>
                /// Activates the window and displays it as a maximized window.
                /// </summary>       
                ShowMaximized = 3,
                /// <summary>
                /// Displays a window in its most recent size and position. This value 
                /// is similar to <see cref="Win32.ShowWindowCommand.Normal"></see>
                ///   , except 
                /// the window is not actived.
                /// </summary>
                ShowNoActivate = 4,
                /// <summary>
                /// Activates the window and displays it in its current size and position. 
                /// </summary>
                Show = 5,
                /// <summary>
                /// Minimizes the specified window and activates the next top-level 
                /// window in the Z order.
                /// </summary>
                Minimize = 6,
                /// <summary>
                /// Displays the window as a minimized window. This value is similar to
                /// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the 
                /// window is not activated.
                /// </summary>
                ShowMinNoActive = 7,
                /// <summary>
                /// Displays the window in its current size and position. This value is 
                /// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the 
                /// window is not activated.
                /// </summary>
                ShowNA = 8,
                /// <summary>
                /// Activates and displays the window. If the window is minimized or 
                /// maximized, the system restores it to its original size and position. 
                /// An application should specify this flag when restoring a minimized window.
                /// </summary>
                Restore = 9,
                /// <summary>
                /// Sets the show state based on the SW_* value specified in the 
                /// STARTUPINFO structure passed to the CreateProcess function by the 
                /// program that started the application.
                /// </summary>
                ShowDefault = 10,
                /// <summary>
                ///  <b>Windows 2000/XP:</b> Minimizes a window, even if the thread 
                /// that owns the window is not responding. This flag should only be 
                /// used when minimizing windows from a different thread.
                /// </summary>
                ForceMinimize = 11
            }
В показанном примере при вызове ShowWindow(IntrPtr.Zero, "My new window"); окно с заголовком My new window отобразится на экране так, что все остальные окна будут помещены позади нашего окна, которое в свою очередь станет активным и получит фокус ввода.
0
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
10.12.2012, 11:47
Ах да, прошу прощения за то, что забыл указать импорт из DLL самой функции FindWindowByCaption:

C#
1
2
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
10.12.2012, 16:09

Не по теме:

SkydraTM, это и есть FindWindow

Цитата Сообщение от SkydraTM Посмотреть сообщение
EntryPoint = "FindWindow"
FindWindowByCaption как API в Windows, в природе не существует.



Добавлено через 7 минут
Цитата Сообщение от Kelord Посмотреть сообщение
Иногда программа вылетает после выполнения этой строки:
Скорее всего буфер маленький, попробуйте
Цитата Сообщение от Kelord Посмотреть сообщение
StringBuilder strB = new StringBuilder(256);
И еще, лучше использовать EnumWindows, с GetWindow можно поймать бесконечный цикл.
0
3 / 3 / 1
Регистрация: 30.05.2011
Сообщений: 8
10.12.2012, 20:34  [ТС]
Спасибо за совет, но для себя нашел решение попроще.
сначало отлавливаю все процессы данного приложения:
C#
1
2
3
4
5
6
7
8
9
for (int i = 0; i < 3; i++)
{
    try
    {
        All3Proc[i] = Process.GetProcessesByName("{имя процесса без .exe}")[i];
        ProcCount++;
    }
    catch { All3Proc[i] = null; }
}
Далее сортирую эти процессы по времени запуска, и уже в отсортированном массиве беру хэндл основного окна:
C#
1
All3Proc[i].MainWindowHandle
Такой код более стабилен и плюс можно работать с другими параметрами процессов.
0
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
11.12.2012, 08:21
Не уверен, что сортировка по времени может дать дивиденты во всех случаях, но иногда такой способ наиболее прост, соглашусь.
Предыдущему оратору хотелось бы заметить - что он он совершео прав, существует FindWindow и FindWindowEx, bycaption дишь суффикс для нашего именования, хорошо что отметили сей факт, иначе нехорошо врать)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.12.2012, 08:21
Помогаю со студенческими работами здесь

FindWindow на Windows x64 не находит окна
Почему то на x64 винде не находит окна. На х32 винде работает: int main() { HWND hwnd = FindWindow(L&quot;dwm&quot;,...

FindWindow не нашел окна, а ShellExecute возвращает ERROR_PATH_NOT_FOUND
Функция ShellExecute возвращает ERROR_PATH_NOT_FOUND(числовое значение - 2), хотя путь указан верный в переданных ей пораметрах. ...

FindWindow не видит диалоговые окна других приложений
Здравствуйте, я с вопросом на счет хука. У меня есть программа, и на определенном этапе, в ней появляется диалоговое окно, которое и нужно...

Найти handle своего окна без FindWindow
Как узнать handle своего (а не активного) окна в mvs c++ ? может в какой-нибудь переменной хранится? :scare:

Вывести на экран количество слов где первая и последняя буквы одинаковы (не понимаю где ошибка)
задан текст нужно вывести на экран количество слов где первая и последняя буквы одинаковы #include &lt;iostream&gt; #include...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в КА2. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа в КА2. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru