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

How to? How can TCC tell if its own window is the active one?

Discussion in 'T&T - Functions' started by mfarah, Apr 1, 2014.

  1. mfarah

    Joined:
    Nov 2, 2009
    Messages:
    227
    Likes Received:
    5
    I usually run processes in TCC windows that take quite some time to complete (pdir /S/(m) in large directories, moving large amounts of files from one drive to another, etcetera). Instead of staying still and watching them run, I usually change focus to another window to do something else while those processes run. This leads to time wasted, as it usually takes me some time to realize "hey, it should be done already" and checking on it. That, or checking too early and seeing the job is still running...

    I've tried running these commands with an appended & beepbeep.btm, or running them as an argument to a batchfile (beepmewhendone.btm pdir ...), but it's cumbersome and I tend to forget to do it.

    I was thinking perhaps a better way to do this would be to add a small alias to the prompt variable (like the cbatt alias in the help page for the prompt command), BUT it would be supremely annoying if it beeped all the time. Ideally, the beep should sound ONLY if the TCC window isn't active at the moment.

    So, how can TCC tell, through a function or variable, wether its own window is the active one at the moment?
     
  2. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,054
    Likes Received:
    30
    My SYSUTILS plugin has
    Code:
    v:\> help @fgwin
    @FGWIN[TCPMXYWH] = word list of spec'd foreground window properties
    Options: Title, Class, Pid, Module, X(pos), Y(pos), Width, Height
    
    v:\> echo %@fgwin[mt]
    "G:\TC16\tcc.exe" "16.01  [3540]  v:\"
    
     
  3. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,054
    Likes Received:
    30
    The special aliases POST_EXEC and PRE_INPUT could help you implement a test.
     
  4. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,351
    Likes Received:
    39
    This is a deep question. TCC's window might be the console window, or it might be the Take Command window, or it might be something else altogether (Console2, ConEmu....) Even if you know that Take Command has focus, how do you know which is the active tab?
     
  5. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    I recommend that you follow the long duration action with the command MSGBOX using option /O. This will pop up the message on the topmost window.
     
  6. MaartenG

    Joined:
    Aug 3, 2016
    Messages:
    355
    Likes Received:
    8
    This seemed like a good puzzle, so I gave it a try ...

    Code:
    %@IF["%_TCTABACTIVE%___%@wintitle[%[_%@instr[%@eval[!%_TCTABACTIVE],ppid]]]%" == "%_TCTAB%___%_winfgwindow%",rem,beep]
    
    You can test it with something like: delay 5 & %@IF[...] and use those 5 seconds to switch to another Tab or application.

    If it works correctly, you can use it as a POST_EXEC alias or integrate it in your PROMPT with %@EXECSTR[...]

    @WINTITLE was introduced in TCMD 16, so this command will fail on older versions.

    ( Some explanation will follow soon; there are two parts that are not completely straightforward)
     
  7. mfarah

    Joined:
    Nov 2, 2009
    Messages:
    227
    Likes Received:
    5
    I've been testing it. It's great! :-)
     
  8. mfarah

    Joined:
    Nov 2, 2009
    Messages:
    227
    Likes Received:
    5
    Ok, so it doesn't work perfectly. I have the following aliases defined:

    @@Alt-7=@cdd "%HOMEDRIVE%%HOMEPATH%"
    @@Alt-8=@cdd "%HOMEDRIVE%%HOMEPATH%\Documents"
    @@Alt-9=@cdd "%HOMEDRIVE%%HOMEPATH%\Downloads"
    @@Alt-0=@cdd "%HOMEDRIVE%%HOMEPATH%\Dropbox"

    This way I can change to my most-used directories with a quick keystroke. On a TCC window WITHIN TCMD, but not on a detached TCC window, with the %@IF added to the POST_EXEC alias, whenever I use those, I get this error syntax:

    TCC: Syntax error "%@IF["1___TC 21 - 2 - cdd "C:\Users\Mi.." == "1___TC 21 - 2 - cdd "C:\Users\Mi.."]"

    This occurrs because the quotes haven't been escaped. I'm trying to user %@replace to replace the inner occurrences of " with \" or something like that (let's see if I can pull that off).
     
  9. MaartenG

    Joined:
    Aug 3, 2016
    Messages:
    355
    Likes Received:
    8
    Thanks for your feedback! Glad you (almost ;-) like it.

    I would stay away from escaping quotes etc. It usually leads to escaping the escape quotes to the Nth degree ...


    You could try comparing the two with something like @MD5[s,string], like:
    Code:
    %@IF[%@MD5[s,%_TCTABACTIVE%___%@wintitle[%[_%@instr[%@eval[!%_TCTABACTIVE],ppid]]]%] == %@MD5[s,%_TCTAB%___%_winfgwindow%],rem,beep]
    
    (Just penned this down; not tested at all)

    (Or something like: if %@LEN[%@replace[left side,,right side]] == 0 , but that will probably have quote-issues or ","-issues by itself .. )


    After re-reading all this: did you have to take extra precautions to prevent your POST_EXEC alias from looping?
    I mean: Window not in foreground means the beep command, which triggers a new prompt, which triggers POST_EXEC to beep, etcetera....
     
    #9 MaartenG, Feb 2, 2017
    Last edited: Feb 2, 2017
  10. MaartenG

    Joined:
    Aug 3, 2016
    Messages:
    355
    Likes Received:
    8
    Did you find a working solution? I just tested my quick suggestions and they were bad ...

    I was curious if the @MD5 function would work. It does not. It's also allergic to odd number of double quotes (which seems strange, as it is "just a string").

    The @REPLACE function did semi-work:
    Code:
    [TEST]echo %@replace[123"456,x,123"456]
    TCC: (Sys) The parameter is incorrect.
     "%@replace[123"456,x,123"456]"
    
    [TEST]echo %@replace["123"456",x,"123"456"]
    x
    
    [TEST]
    

    Another strange thing I noticed is the behaviour of @STRIP:
    It behaves different when parsing a string or when parsing a variable with it's value set to the same string:
    Code:
    [TEST]set DUMMY=123"456
    
    [TEST]echo %@STRIP[x,%DUMMY]
    123"456
    
    [TEST]echo %@STRIP[x,123"456]
    TCC: Syntax error "@STRIP[x,123"456]"
    
    [TEST]
    
    How is that even possible?


    To be continued ....
    (sorry for all the confusion)
     
    #10 MaartenG, Feb 3, 2017
    Last edited: Feb 3, 2017
  11. MaartenG

    Joined:
    Aug 3, 2016
    Messages:
    355
    Likes Received:
    8
    BTW: There is a workaround for these specific cases:

    replace "%HOMEDRIVE%%HOMEPATH%" with "~" like:
    @@Alt-9=@cdd "~\Downloads"

    That will make the title short enough to be displayed in full.
    Things will go wrong though in other cases where the title too long
     
  12. MaartenG

    Joined:
    Aug 3, 2016
    Messages:
    355
    Likes Received:
    8
    While still not (completely) working, here is some background info.

    When describing the inner workings of this command, it turned out that it can be further simplified (which was my original intention, but forgot to implement (in the original function ...@eval[%_TCTAB... would be more appropriate than ...%@eval[%_TCTABACTIVE... , but I digress ..))

    Probably won't help much with the odd number of quotes issues ... (this is a problem in every @function I tried. Real messy. Someone should report that as a bug).

    version 2:
    Code:
    %@IF["%@wintitle[%[_%@instr[%@eval[!%_TCTABACTIVE],ppid]]]%" == "%_winfgwindow%",rem,beep]
    

    Core is the %_winfgwindow variable. That's the (only?) way to detect the foreground window. In "plain" TCC.exe it matches TCC's title. In TCMD.exe it matches the title of TCMD (not that of the TCC tab).

    That title has to be compared to the title of the window that your (long) command is running in.
    To get that title (of TCC resp TCMD), @WINTITLE[%_pid] resp. @WINTITLE[%_ppid] is used.

    To avoid an extra @IF statement to differentiate between these two, I used _TCTABACTIVE This gives a boolean ("0" or "1") depending if it it the active tab in TCMD ("1") or not ("0"). In plain TCC _TCTABACTIVE = 0.

    After inversion (NOT _TCTABACTIVE) it is used for @INSTR : it reads from position 0 *or* 1 the rest of the string "PPID". That way it gives you PPID resp. PID
    Now there are a few scenarios:
    • TCC running in foreground TCMD and TCC is the foreground tab:
      _TCTABACTIVE = 1 gives _PPID, gives TCMD's title = a match with _WINFGWINDOW
    • TCC running in foreground TCMD and TCC is a background tab:
      _TCTABACTIVE = 0 gives _PID, gives TCC's title = no match with _WINFGWINDOW (which is TCMD's title)
    • TCC running in background TCMD:
      no match with _WINFGWINDOW
    • Plain TCC running in foreground:
      _TCTABACTIVE = 0 gives _PID, gives TCC's title = a match with _WINFGWINDOW
    • Plain TCC running in background:
      _TCTABACTIVE = 0 gives _PID, gives TCC's title = no match with _WINFGWINDOW

    So, there is only a match (= do not beep) when:
    • TCC is running in foreground TCMD ànd TCC is the foreground tab
    • Plain TCC is running in foreground
    Which seems about right.
     
    #12 MaartenG, Feb 4, 2017
    Last edited: Feb 4, 2017
  13. MaartenG

    Joined:
    Aug 3, 2016
    Messages:
    355
    Likes Received:
    8
    @mfarah : have you found a solution or workaround for the single " issue?

    I'm now working on a script where this is also problematic.
    All of the string-functions I tried gave a syntax error, even @unquote ....
     

Share This Page