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

WM_TIMER?

Discussion in 'Support' started by vefatica, Jan 2, 2016.

  1. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    Unlike previous versions of TCC, the v19 "TCC.EXE" class window gets a WM_TIMER message every 500 milliseconds. What's that all about?
     
  2. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    To monitor whether the console window has been attached to or detached from a TCMD tab window.

    Why do you care?
     
  3. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    I don't really care. I was just surprised to see it, and curious.
     
  4. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    Still curious ... what does TCC do with that information?
     
  5. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    Required for interprocess communication with TCMD.
     
  6. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,312
    Likes Received:
    39
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    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);
    
     
    Charles Dye likes this.
  8. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    Older TCCs and other apps fare pretty well in TCMD v19 tabs. What will fail without the polling?
     
  9. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    Several internal variables and window handles were not being reset properly pre-V19 when they were detached and/or attached.
     
  10. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,312
    Likes Received:
    39
    Thanks for that.
     
  11. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    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);
       }
    
     

Share This Page