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

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

05.12.2012, 13:24. Показов 12867. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Программный отбор элементов справочника Номенклатура по группе 1С
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор под наименованию группы (на. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
Программный отбор элементов справочника Сотрудники по перечислениям 1С
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит предопределенное значение перечислений. Процедура. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru