#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();