Need to "un-iconize" a window without giving focus

Started by stevengraff, April 07, 2014, 09:37:32 AM

Previous topic - Next topic

stevengraff

I've learned never to bet against the cleverness of WinBatch and its experts, but this one seems really tough...

Is there any way to change a window's status from iconized (i.e. minimized to the Windows taskbar) to "normal" without giving it the focus?

I have multiple instances of my script running, one that I'm typing input into, the other three are minimized. If WinActivate is used, the focus instantly changes to the newly activated instance, as does my stream of typing. Which is obviously quite frustrating, and not the wished-for behavior.

Currently, the taskbar instances are activated by a separate script but, they do have the ability to activate autonomously, based on self-inspection.

Maybe the fallback position is to simply have them flash instead, when they need attention, then the user can just click when ready to use them. (I think I saw a script designed for that purpose here: http://forum.winbatch.com/index.php?topic=802.msg3017#msg3017)

stevengraff

Chiming in on my own question... could it be that WinShow does exactly what I'm asking for?

In prelim testing it sure looks that way!

Deana

WinShow is intended to change the window state. However it also seems to give the Window Focus....at least with my test:

Code (winbatch) Select
Run('notepad','')
title = "~Notepad"
bit = 1
While @true
    If bit
      WinIconize(title)
      bit = 0
    else
      WinShow(title)
      bit = 1
    Endif
    TimeDelay(2)
EndWHile

Exit


Off hand I cannot think of any way to change the window state without the window getting focus. Anyone else?
Deana F.
Technical Support
Wilson WindowWare Inc.

stevengraff

Here's a video demonstration: http://screencast.com/t/mGhhh3TLxvK

You'll see, at the start a taskbar item "--John Shadi..." which will be brought to life by winShow, with no interruption in my typing in the original "--Joe Schmo..." window.

td

When you target WinShow at the 'big daddy window', a.k.a. the WinBatch main window, WinShow is intentionally written to restore the window without activating.  With other windows, not so much.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stevengraff

Quote from: td on April 07, 2014, 01:11:12 PM
When you target WinShow at the 'big daddy window', a.k.a. the WinBatch main window, WinShow is intentionally written to restore the window without activating.  With other windows, not so much.

Not to strain the point too much, but... when you say "other windows" are you referring to non-WinBatch windows or WinBatch non-main (child) windows (if that's even a thing).

Deana

Tony is saying that WinShow will NOT activate/set focus to the Box windows also known as the Main WinBatch window. However on any other windows ( like Notepad in my code sample ) will activate.

For example:

Code (winbatch) Select
title = "Test"
BoxOpen(title,"")
bit = 1
While @true
    If bit
      WinIconize(title)
      bit = 0
    else
      WinShow(title)
      bit = 1
    Endif
    TimeDelay(2)
EndWHile
Exit
Deana F.
Technical Support
Wilson WindowWare Inc.

td

To get a dialog to it's restored state without activating it you could do something like the following from a dialog callback
Code (winbatch) Select
hWnd = hDialog ; DllhWnd("SomeWindowName")
SW_SHOWNOACTIVATE = 4
DllCall("user32.dll", long:"ShowWindow", long:hWnd, long:SW_SHOWNOACTIVATE);
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

snowsnowsnow

QuoteTo get a dialog to it's restored state without activating it you could do something like the following from a dialog callback

Is there any reason that wouldn't work with arbitrary windows (handle retrieved via DllHwnd() or similar) ?

Is there a reason you couched it in terms of a WinBatch dialog?

td

Quote from: stevengraff on April 07, 2014, 01:37:39 PM
Not to strain the point too much, but... when you say "other windows" are you referring to non-WinBatch windows or WinBatch non-main (child) windows (if that's even a thing).
After reflecting a bit (always dangerous), you do bring up an interesting point that may have some bearing on the behavior demonstrated by your video.

The WinShow function specifically checks for the WinBatch application window as the window being referenced by the input Window ID or title.  When the input is in fact the WinBatch application window, it restores the window specifying that it not be activated.  In all other cases, it restores the window without specifically indicating that it should or should not be made the active window. 

About the only time the WinBatch application window has visible child windows is when using the WinBatch Box functions.  However, it is frequently an owner window of owned windows.  Message boxes  and WIL dialogs are two common examples of windows owned by the WinBatch application window.  One of the interesting features of an owned window is that its display state is influenced by the state of its owner window.  The owned window's activation status can also be influenced when the owner is transitioning display state. So if you use the WinShow function on a WinBatch application window that owns a WIL dialog, it should cause the dialog to be restore but not activated.  However, if you use WinShow directly on the dialog, it should be both restored and possibly activated. 

At least, that is the theory.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stevengraff

Quote from: td on April 08, 2014, 08:45:30 AM
Quote from: stevengraff on April 07, 2014, 01:37:39 PM
Not to strain the point too much, but... when you say "other windows" are you referring to non-WinBatch windows or WinBatch non-main (child) windows (if that's even a thing).
Message boxes  and WIL dialogs are two common examples of windows owned by the WinBatch application window.

I've been under the illusion that my dialog is, in fact, the "WinBatch application window." It's not? Or are you saying it's different if running in the Wil editor than under its own steam as a compiled exe?

Deana

The WinBatch "Main" window is actually the window/box you see when you click on the WinBatch taskbar icon of a running script. Any dialog generated by a script including the Dialog() is drawn based on the Main window. As Tony stated, Dialogs are "owned" by the main window/box.
Deana F.
Technical Support
Wilson WindowWare Inc.

stevengraff

Well, with my compiled script, the window I see when I click that taskbar icon is the dialog box. Or are you saying that the taskbar icon itself is the Main window? (Sorry for being so thick, but I'm starting to feel like I'm in an Abbot and Costello skit. :) )

Deana

Quote from: stevengraff on April 09, 2014, 04:36:36 AM
Well, with my compiled script, the window I see when I click that taskbar icon is the dialog box. Or are you saying that the taskbar icon itself is the Main window? (Sorry for being so thick, but I'm starting to feel like I'm in an Abbot and Costello skit. :) )

Basically yes the taskbar icon is the Main Window and any Dialogs  you call are based of the main ( taskbar icon ) window.
Deana F.
Technical Support
Wilson WindowWare Inc.

td

Quote from: stevengraff on April 09, 2014, 04:36:36 AM
Well, with my compiled script, the window I see when I click that taskbar icon is the dialog box. Or are you saying that the taskbar icon itself is the Main window? (Sorry for being so thick, but I'm starting to feel like I'm in an Abbot and Costello skit. :) )

WinBatch always has an application window that owns the WIL Dialog window.  Just because you can't see it doesn't mean that is not there.  A WIL Dialog window is never the WinBatch application window.  It is always owned by the WinBatch application window.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stevengraff

I am somewhat relieved to know that there are things there that I can't see. That explains a lot, in many facets of life.

td

Quote from: stevengraff on April 09, 2014, 08:16:30 AM
I am somewhat relieved to know that there are things there that I can't see. That explains a lot, in many facets of life.

We are the better for not being able to see everything that is there.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

DAG_P6

I still remember being flabbergasted the first time I enumerated the main windows on a machine. There were scores of windows for programs that I didn't even know were running. I spent the next hour or so identifying some of the ones that were less obvious.

The first time I asked the Visual Studio 6 AppWizard to generate a graphical "Hello World" application, it left no doubt that Microsoft means business when they say that everything is a window. For what it's worth, I have written at least a couple of complete programs that began life as "Hello World." However, if you run them, you never see the main window. I can think of at least one that does some stuff, then disappears without a trace.

In 2003, I even created a compiled WinBatch script that runs completely hidden in its default configuration. I use it when I need to send email on behalf of a production batch file.
David A. Gray
You are more important than any technology.

td

I have always thought it interesting that MSFT's COM Automation is implemented in part using hidden windows and thread message pumps.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

kdmoyers

I used to know the bass player for the Thread Message Pumps, back when they played the dive bars of Reno.  I've never seen a man look so good in stiletto heels.
The mind is everything; What you think, you become.

....IFICantBYTE

 ;D Somehow, I hear Maxwell Smart's voice (the original Don Adams) saying that Kirby.. I like your sense of humour.
Regards,
....IFICantBYTE

Nothing sucks more than that moment during an argument when you realize you're wrong. :)

td

Quote from: kdmoyers on April 11, 2014, 04:06:46 AM
I used to know the bass player for the Thread Message Pumps, back when they played the dive bars of Reno.  I've never seen a man look so good in stiletto heels.

A bunch of retired Microsofty's?
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

kdmoyers

Quote from: td on April 11, 2014, 07:07:22 AM
A bunch of retired Microsofty's?
Yeah, when that nerdy kid with the glasses offered them stock, they turned him down.  When their mistake became obvious, they turned to procedurally generated music back when no one knew what that meant, but were stoned enough not to care.

These days they just busk for tips and try to stay out of jail.
The mind is everything; What you think, you become.

hdsouza

I did not read through the whole thread so I apologize if this was already covered

When you say you have multiple instances of your script running, do you mean something like multithreading where you have a parent script calling child scripts. In that case you could employ "token passing" where in one child has access to do whatever it wants till it completes a spcific job.. in this case the child/script sending key strokes. You could simulate token passing by letting the parent have a file called token.txt to start with. it then checks if any child needs to use the token and gives the token to the child. prior to this the child would be in a wait state for the token. When the token is granted to the child and another child needs access to the token, the new child would just wait till the first child returned the token to the parent. This way you dont have two childs/scripts fighting with each other.  I had writen something along these lines a few years back. I guess that is what you are trying to achieve.

If you dont want to go this route you could also check that the window is active before sending the keystrokes out. although you could still run into the problem if another script has activated another window while the first script is sending keystrokes

td

Quote from: kdmoyers on April 11, 2014, 07:14:06 AM

Yeah, when that nerdy kid with the glasses offered them stock, they turned him down.  When their mistake became obvious, they turned to procedurally generated music back when no one knew what that meant, but were stoned enough not to care.

These days they just busk for tips and try to stay out of jail.

Marty always said we regretted saying no to the kid but that was before there was stock, let alone stock options.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stevengraff

Quote from: hdsouza on April 11, 2014, 08:35:25 AM
I did not read through the whole thread so I apologize if this was already covered

When you say you have multiple instances of your script running, do you mean something like multithreading where you have a parent script calling child scripts. In that case you could employ "token passing" where in one child has access to do whatever it wants till it completes a spcific job.. in this case the child/script sending key strokes. You could simulate token passing by letting the parent have a file called token.txt to start with. it then checks if any child needs to use the token and gives the token to the child. prior to this the child would be in a wait state for the token. When the token is granted to the child and another child needs access to the token, the new child would just wait till the first child returned the token to the parent. This way you dont have two childs/scripts fighting with each other.  I had writen something along these lines a few years back. I guess that is what you are trying to achieve.

If you dont want to go this route you could also check that the window is active before sending the keystrokes out. although you could still run into the problem if another script has activated another window while the first script is sending keystrokes

No, no multithreading... and no children. Just multiple instances of my main script. In each instance the user is having a Text conversation with a different person. At some point, the conversations go quiet, so the user minimizes them all so he can return to his "normal" work. When one of the conversants responds another script examines the response, and sends a WinShow ("conversant") command out to make visible (but not activate) that conversant's instance of the script. (see the video link?)