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

#1
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
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:\"
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,586
46
Albuquerque, NM
prospero.unm.edu
#4
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?
 
#6
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)
 
#8
Ok, so it doesn't work perfectly. I have the following aliases defined:

@@[email protected] "%HOMEDRIVE%%HOMEPATH%"
@@[email protected] "%HOMEDRIVE%%HOMEPATH%\Documents"
@@[email protected] "%HOMEDRIVE%%HOMEPATH%\Downloads"
@@[email protected] "%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
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....
 
Last edited:
#10
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)
 
Last edited:
#12
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 [email protected][%_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.
 
Last edited: