Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

Другие советы

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

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

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

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

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

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

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

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

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

Возможно, сочетание 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
    }
}
if(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
     // do stuff
 }

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top