// This hook targets CONHOST and only receives SHOW/HIDE (0x8002, 0x8003) events.
VOID CALLBACK ShowHideMonitorProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if ( hwnd == global.hWndConsole )
{
// just to see it work
Printf(L"%s\r\n", (event == EVENT_OBJECT_HIDE) ? L"HIDE" : L"SHOW");
}
}
// After getting CONHOST's PID, this hook unhooks itself and sets
// a more appropriate one to watch for console hide or show.
VOID CALLBACK ConHostDiscoveryProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if ( hwnd == global.hWndConsole && global.dwConHostPid == 0 )
{
HANDLE hEventThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, dwEventThread);
global.dwConHostPid = GetProcessIdOfThread(hEventThread);
CloseHandle(hEventThread);
UnhookWinEvent(hWinEventHook);
SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE, global.hThisModule,
ShowHideMonitorProc, global.dwConHostPid, 0, WINEVENT_OUTOFCONTEXT);
}
}
// in InitializePlugin()
if ( global.hWndConsole != NULL ) // not for detached instances
{
// After getting the PID of CONHOST.EXE, this hook unhooks itself and sets another hook targeting
// only CONHOST, the console window, and the events EVENT_OBJECT_SHOW and EVENT_OBJECT_HIDE.
// Do this only in a thread that pumps messages. Doing it here, in InitializePlugin(), works.
SetWinEventHook(EVENT_MIN, EVENT_MAX, global.hThisModule, ConHostDiscoveryProc, 0, 0, WINEVENT_OUTOFCONTEXT);
}