Проверка HWND с помощью API Win32
Из собственного API Win32 с использованием С++ существует ли способ определить, действительно ли окно, связанное с HWND?
Ответы
Ответ 1
Вы можете использовать API Win32 IsWindow.
Не рекомендуется использовать его по двум причинам:
- Ручки Windows могут быть повторно использованы после того, как окно будет уничтожено, поэтому вы не знаете, есть ли у вас дескриптор в совершенно другом окне или нет.
- Состояние может измениться сразу после этого вызова, и вы считаете его действительным, но оно может быть действительно недействительным.
Из MSDN (такая же ссылка, как указано выше):
Нить не должна использовать IsWindow для окно, которое оно не создало, потому что окно может быть уничтожено после эта функция была вызвана. В дальнейшем, потому что обработчики окон переработаны ручка может даже указывать на другое окно.
Что можно сделать?
Возможно, ваша проблема может быть повторно решена, так что вам не нужно проверять действительный дескриптор. Возможно, например, вы можете установить канал от клиента к серверу.
Вы также можете создать крючок Windows, чтобы обнаруживать, когда возникают определенные сообщения, но это, вероятно, слишком велико для большинства потребностей.
Ответ 2
Вы можете использовать IsWindow(), а также попытаться отправить окно сообщение WM_NULL с SendMessage (hWnd, WM_NULL) и посмотрите, успешно ли он.
Кроме того, это правда, что окно может быть уничтожено в любое время, если оно не находится под вашим контролем. Как утверждали другие, ручка потенциально может принадлежать другому окну, поскольку ручки повторно используются. На самом деле я не знаю, насколько это возможно.
Единственное решение, которое я знаю о создании системного hook, который ищет сообщения, указывающие, что окно уничтожено (WM_CLOSE, WM_DESTROY), Затем вы сравните дескриптор окна сообщения с теми, которые вы держите, чтобы увидеть, затронуто ли какое-либо из окон, о которых вы заботитесь. Смотрите здесь, чтобы узнать больше об аппаратных крючках.
Ответ 3
Этот вопрос старый, но мне эта функция нужна сама, и я немного разочаровался после прочтения оговорок. Однако, сделав немного больше копания, кажется, что все в порядке. Если вы не имеете дело с 16-битными программами, IsWindow, похоже, подходит. Проблема, связанная с повторным использованием дескриптора, по-видимому, была решена в соответствии с этим:
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
Итак, из-за верхнего 16-битного счетчика повторного использования маловероятно, что вы столкнетесь с проблемой повторного использования окна.
Ответ 4
IsWindow
Ответ 5
Если оконная процедура для рассматриваемого окна находится под вашим контролем (или если вы можете подклассифицировать ее), я бы предложил зарегистрировать настраиваемое сообщение, на которое окно отвечает с ненулевым результатом. Отправка этого сообщения в другое окно (или недопустимый HWND) приведет к 0.
Конечно, это говорит только о том, относится ли HWND к одному из окон, которые вы контролируете, но, возможно, дает другие ответы выше, которые могут быть даже полезными.
Используйте RegisterWindowMessage для регистрации сообщения с использованием достаточно уникального имени.
Ответ 6
if(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
// do stuff
}
проверит, существует ли окно и имеет соответствующее имя
Ответ 7
Возможно, комбинация 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
}
}