15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Как получить дескриптор консольного окна (HWND)

Иногда необходимо производить какие-нибудь действия с окном, связанным с консольным приложением. Win32 API не предоставлят прямых методов получения дескриптора окна, связанного с консольным приложением. Однако, дескритор (handle) окна можно получить вызвав FindWindow(). Эта функция отыскивает дескриптор окна, основанный на имени класса либо имени окна.

Чтобы определить текущий заголовок консоли, вызывается GetConsoleTitle(). Затем этот заголовок указывается в функции FindWindow().

Так как несколько окошек могут иметь одинаковый заголовок, то Вам прийдётся изменить заголовок текущего консольного окна на уникальный. Это поможет защититься от получения неправильного дескриптора окна. Для изменения заголовка текущего консольного окна используется SetConsoleTitle(). Вот как это делается:

  1. Вызываем GetConsoleTitle() чтобы сохранить заголовок текущего консольного окна.

  2. Вызываем SetConsoleTitle() чтобы изменить заголовок на уникальный (неповторимы).

  3. Вызываем Sleep(40) чтобы дать время заголовку измениться.

  4. Вызываем FindWindow(NULL, uniquetitle), для получения HWND. Этот запрос возвратит HWND либо NULL в случае неудачи.

  5. Вызываем SetConsoleTitle() со значением, полученным в шаге 1, для восстановления изначального заголовка окна.

Необходимо проверить полученный HWND. Например, можно проверить, соответствует ли полученный HWND текущего процесса, вызвав для него GetWindowText() с этим HWND и сравнив его с результатом, полученным при помощи GetConsoleTitle().

Нет гарантии, что полученный HWND подойдёт для всех возможных операций с дескриптором окна.

Пример кода

Следующая функция возвращает дескриптор текущего окна консольного приложения (HWND). Если функция выполнена удачно, то возвращённое значение будет являться дескриптором консольного окна, иначе, вслучае ошибки будет возвращён NULL. Для краткости, некоторые проверки возможных ошибок убраны.

   HWND GetConsoleHwnd(void)
   {
       #define MY_BUFSIZE 1024 // Размер буфера для заголовка консольного окна.
       HWND hwndFound;         // Это то, что будет возвращено.
       char pszNewWindowTitle[MY_BUFSIZE]; // Уникальный заголовок окна.
       char pszOldWindowTitle[MY_BUFSIZE]; // Изначальный заголовок окна.

       // Выбираем текущий заголовок окна.

       GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);

       // Формируем "уникальный" NewWindowTitle.

       wsprintf(pszNewWindowTitle,"%d/%d",
                   GetTickCount(),
                   GetCurrentProcessId());

       // Изменяем текущий заголовок окна.

       SetConsoleTitle(pszNewWindowTitle);

       // даём время заголовку, чтобы измениться.

       Sleep(40);

       // Ищем NewWindowTitle.

       hwndFound=FindWindow(NULL, pszNewWindowTitle);

       // Восстанавливаем изначальный заголовок окна.

       SetConsoleTitle(pszOldWindowTitle);

       return(hwndFound);
   }