Проверка, закрыто ли другое окно c

#c #winapi

#c #winapi

Вопрос:

Я разрабатываю приложение, которое проверяет открытые окна на компьютере пользователя в Windows (точно так же, как диспетчер задач)

Я использовал EnumWindows для перечисления всех активных окон, и это работает, теперь я хочу создать функцию, которая записывает сообщение на консоль, когда окно закрыто. Возможно ли, или я должен проверить массив WindowHandler в отдельном потоке и как мне проверить их статус?

Спасибо за помощь.

Комментарии:

1. Если у вас есть права доступа, один из способов — использовать глобальную процедуру перехвата CBT. Дальнейшее чтение msdn.microsoft.com/en-us/library/windows/desktop /… см. HCBT_DESTROYWND

2. итак, когда пользователь нажимает X в Windows, моя программа может «прослушивать» через этот CBT-хук?

3. Начните здесь: msdn.microsoft.com/en-us/library/windows/desktop /… и убедитесь, что вы прочитали о том, в каком потоке вызывается ваш обратный вызов.

4. Вам необходимо зарегистрироваться для WinEvents и обработать EVENT_OBJECT_DESTROY событие. Вам необходимо зарегистрироваться перед запуском EnumWindows цикла. В противном случае вы можете пропустить разрушение окна.

Ответ №1:

Самое простое решение — использовать WinEvents, зарегистрировавшись для EVENT_OBJECT_DESTROY событий. Код довольно прост:

 #include <windows.h>

namespace {
    HWINEVENTHOOK g_WindowDestructionHook = NULL;
}

inline void CALLBACK WinEventProc( HWINEVENTHOOK hWinEventHook,
                                   DWORD         event,
                                   HWND          hwnd,
                                   LONG          idObject,
                                   LONG          idChild,
                                   DWORD         dwEventThread,
                                   DWORD         dwmsEventTime ) {
    // Filter interesting events only:
    if ( idObject == OBJID_WINDOW amp;amp; idChild == CHILDID_SELF ) {
        wprintf( L"Window destroyed: HWND = Xn", hwnd );
    }
}

inline void RegisterWindowDestructionHook() {
    g_WindowDestructionHook = ::SetWinEventHook( EVENT_OBJECT_DESTROY,
                                                 EVENT_OBJECT_DESTROY,
                                                 NULL,
                                                 WinEventProc,
                                                 0, 0,
                                                 WINEVENT_OUTOFCONTEXT );
}

inline void UnregisterHook() {
    ::UnhookWinEvent( g_WindowDestructionHook );
}
  

Использовать это одинаково просто:

 ::CoInitialize( NULL );
RegisterWindowDestructionHook();

MSG msg = {};
while ( ::GetMessageW( amp;msg, nullptr, 0, 0 ) > 0 ) {
    ::TranslateMessage( amp;msg );
    ::DispatchMessageW( amp;msg );
}

UnregisterHook();
::CoUninitialize();