Проверьте HWND с помощью Win32 API - PullRequest
16 голосов
/ 26 февраля 2010

Из собственного Win32 API, использующего C ++, есть ли способ определить, является ли окно, связанное с HWND, все еще действительным?

Ответы [ 7 ]

30 голосов
/ 26 февраля 2010

Вы можете использовать Win32 API IsWindow .

Не рекомендуется использовать его по двум причинам:

  1. Дескрипторы Windows можно использовать повторно после разрушения окна, поэтому вы не знаете, есть ли у вас дескриптор совершенно другого окна или нет.
  2. Состояние может измениться сразу после этого вызова, и вы подумаете, что оно допустимо, но оно может действительно быть недействительным.

Из MSDN (та же ссылка, что и выше):

Поток не должен использовать IsWindow для окно, которое он не создал, потому что окно может быть разрушено после эта функция была вызвана. В дальнейшем, потому что оконные ручки переработаны ручка может даже указывать на другое окно.

Что можно сделать?

Возможно, ваша проблема может быть перестроена так, чтобы вам не нужно было проверять действительный дескриптор. Может быть, например, вы можете установить канал от клиента к серверу.

Вы также можете создать хук Windows, чтобы определять, когда появляются определенные сообщения, но это, вероятно, излишне для большинства нужд.

11 голосов
/ 08 июня 2012

Этот вопрос старый, но я сам нуждался в этой функциональности и был немного разочарован после прочтения предостережений. Тем не менее, после нескольких копаний кажется, что все хорошо. Если вы не имеете дело с 16-битными программами, IsWindow, похоже, является подходящим вариантом. Проблема повторного использования ручки, по-видимому, была достаточно решена в соответствии с этим:

http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx

Итак, из-за верхнего 16-битного счетчика повторного использования весьма маловероятно, что вы столкнетесь с проблемой повторного использования окна.

8 голосов
/ 26 февраля 2010

Вы можете использовать IsWindow () или также попытаться отправить окну сообщение WM_NULL с помощью SendMessage (hWnd, WM_NULL) и посмотреть, успешно ли оно.

Кроме того, верно, что окно может быть разрушено в любое время, если оно не находится под вашим контролем. Как уже говорили другие, дескриптор может потенциально принадлежать другому окну, так как дескрипторы используются повторно. На самом деле я не знаю, насколько это вероятно.

Единственное известное мне решение для создания системной ловушки , которая ищет сообщения, указывающие, что окно разрушено (WM_CLOSE, WM_DESTROY). Затем вы сравнили бы дескриптор окна сообщения с тем, который вы держите, чтобы увидеть, не затронуты ли какие-либо из окон, которые вас интересуют. См. Здесь для получения дополнительной информации о системных крючках.

1 голос
/ 26 июля 2017

Возможно, комбинация IsWindow, FindWindow и GetWindowThreadProcessId будет более точной

HWND windowHandle = FindWindow(NULL, TEXT("window_title"));
LPDWORD oldpid = 0;
GetWindowThreadProcessId(windowHandle, &oldpid);
//after some time
if (IsWindow(windowHandle))
{
    LPDWORD newpid = 0;
    GetWindowThreadProcessId(windowHandle, &newpid);
    if (newpid == oldpid)
    {
        //the window is still running
    }else
    {
        //the window exists but has changed
    }
}
1 голос
/ 22 июля 2013

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

Конечно, это говорит только о том, что HWND ссылается на одно из окон, которыми вы управляете, - но, возможно, с учетом других приведенных выше ответов, которые могут даже оказаться полезными.

Используйте RegisterWindowMessage для регистрации сообщения, используя достаточно уникальное имя.

1 голос
/ 26 февраля 2010
0 голосов
/ 06 октября 2016
if(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
     // do stuff
 }

проверит, существует ли окно и имеет ли оно соответствующее имя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...