WM_TIMER?

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,410
40
Albuquerque, NM
prospero.unm.edu
#6
I recall doing something similar in PopupFix: start a timer, check the console window's visible/hidden status every n milliseconds. If it has changed from visible to hidden or vice versa, the console may have been attached or detached to Take Command/Console2/ConEmu, so do further checks for all of those and update internal variables....
 
#7
I recall doing something similar in PopupFix: start a timer, check the console window's visible/hidden status every n milliseconds. If it has changed from visible to hidden or vice versa, the console may have been attached or detached to Take Command/Console2/ConEmu, so do further checks for all of those and update internal variables....
I don't know about Rex's needs, but for yours, Charles, what's below, meant only as a test, works pretty well to tell if TCC has been attached/detached. Below, bInTab() expands L"%_TCTAB" and returns TRUE/FALSE accordingly.
Code:
VOID CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject,
   LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
   if ( hwnd == global.hWndConsole )
     Printf(L"%s a tab!\r\n", bInTab() ? L"In" : L"Not in");
}
// In InitializePlugin
  HWINEVENTHOOK hWinEvent = SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE,
     global.hThisModule, WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
 
Likes: Charles Dye
#11
A P.S. on that. If you could figure out TCC's instance of conhost.exe, you could target that PID with the Win event hook rather than all processes (0). I tested that by watching a CMD be attached/detached using a Win event hook which targeted CMD's conhost. EVENT_OBJECT_SHOW and EVENT_OBJECT_HIDE are generated by the conhost process. I don't know how to get the PID of TCC's conhost ... Rex? ... Charles?
 
#12
This works nicely (in a plugin) to get the PID of TCC's conhost and then set a conhost-specific Win event hook to watch for the console being hidden or shown.
Code:
// 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);
   }
 
#13
P.S. ...

If you're not interested in getting conhost's PID, you can just set the show/hide WinEvent hook for all processes. That doesn't burden the system. I've been counting and in a couple hours of work, mine has gotten only a few hundred hits from other windows (when it returns immediately).
Code:
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");
   }
}

  if ( global.hWndConsole != NULL ) // not for detached instances
   {
     SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE, global.hThisModule,
                             ShowHideMonitorProc, 0, 0, WINEVENT_OUTOFCONTEXT);
   }