Jump to content

Prevent a window from being activated


Recommended Posts

I have a app which periodically creates a window and activates it.

I need it to be running completely in background without disturbing user from what he is doing.

For now what I'm doing is basically this:

WinWait($window)

SetWinState($window,SW_MINIMIZED)

what gives me almost instant return to the user program, but still not enough fast to completely avoid stealing the focus.

My question is if there are any ways to check the window right before is ready to be activated and suppress the activation?

Thank you.

Link to comment
Share on other sites

I don't know why you're doing this exactly.. but using a

WinSetState($window,@SW_HIDE)

Will render the user almost completely useless.

The reason to avoid activation of a window generated by a program is to avoid user being interrupted.

I guess that should be a common problem for tasks where you need to suppress activation of window created by an app supposed to run silently in backround but instead stealing the focus from the program in use.

@SW_HIDE has the same issue as @SW_MINIMIZE because the window first gets activated and only after that is hidden or minimized. @SW_HIDE is actually worse because it doesn't return the focus to the current app.

@SW_HIDE Hides the window and activates another window.

@SW_MINIMIZE Minimizes the specified window and activates the next top-level window in the Z order.

I started to look if there is something to prevent a window to activate and found some sort of mecanism of win32 hooks by which a filter function intercepts events before they reach an application.

Windows calls the WH_CBT hook with HCBT_ACTIVATE when any window is about to be activated.

The hook I need for my purposes is called WH_CBT using the HCBT_ACTIVATE hook code.

If the filter function return TRUE, the window is not activated.

As far as I know this sort of things requires to write your own dll to be able to catch the activation.

I don't know anything about so if somebody could help me or point to an easie way it would be much appreciated. Thanks to everyone trying to help people on this forum.

Link to comment
Share on other sites

...For now what I'm doing is basically this:

WinWait($window)

SetWinState($window,SW_MINIMIZED)

what gives me almost instant return to the user program, but still not enough fast to completely avoid stealing the focus....

Have you looked into setting WinWaitDelay to 1 or 0 milliseconds.

(until you get your other solution going...)

Opt("WinWaitDelay", 0)

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

Have you looked into setting WinWaitDelay to 1 or 0 milliseconds.

(until you get your other solution going...)

Opt("WinWaitDelay", 0)
Thanks for the advice. I already set WinWaitDelay to 0 to minimize the impact of the switching from background app to the user current program. You still get that annoying screen flicking for that short moment of changing focus to another window. So I guess a real working solution would be something like WinWaitNotActivate to wait for a window and open it background using Microsoft concept of windows hooks. So the only one question is if there is anyone knowledgeable enough and having time and desire to implement it :-) In my opinion such a feature would be a useful addition to AutoIt as a tool for automation of existing application. I consider the ability to run a program in full background is one of automation criteria. I assume that WinWaitNotActivate does not exist yet in AutoIt because is not an easy task :-( I'm still looking for a solution to my problem so I am opened to any ideas. Thank you very much.
Link to comment
Share on other sites

...WinWaitNotActivate does not exist yet in AutoIt...

That is what WinWait does. The problem is that you do not want WinWait... as you do not want to wait.

You would initially need to set it in the Run() function to do the no activate or before the call if possible with an API call. Programs that do minimize or hide immediately like those that run from the Run key in registry are internally coded to do that. The state flag in Run() does work for Notepad and such and is the point of execution or before when the state needs to be set.

Link to comment
Share on other sites

Is this a new window each time or the same window that is simply being hidden?

The program is a time clock polling app. It pings the hardware every minute or so and create a window to show the progress. Then window is closed and my script continue to do its own job. During the clock poll if there are data in the timeclock another window is created to process downloaded data. And so on.

So my troubles are only related to these two windows. And what I can do for now is WinWait and WinSetState(@SW_MINIMIZE) as the only one way to return back to user program. And even with the minimal delay set with Opt is still a problem. I need it to be completely working in background.

Link to comment
Share on other sites

Tresa, I wasn't speaking to you. If you would have looked at the content of the question or the amount of posts I have in comparison to you, you would have realised that.

scuzzy...

Excuse me I realize that's not what I mean

It a french spelling near 'Excuse me'

Edited by tresa
Link to comment
Share on other sites

I see. The only way I am familiar with to keep this window from appearing is to subclass the target application to disgard the request to open the window. The problem is that AutoIt is not easily able to do this.

@tresa, forgive me for being a little harsh last time I posted. I see now that I was mistaken in the manner of my address to you. Thank goodness you did't take it in a manner it was not intended.

Who else would I be?
Link to comment
Share on other sites

@tresa, forgive me for being a little harsh last time I posted. I see now that I was mistaken in the manner of my address to you. Thank goodness you did't take it in a manner it was not intended.

No problem !

The fact is that when I read the first question I understood that AutoIt was stealing priority with a window, hence my suggestion of the traytip

It no sense in the reality as it's another app that show a window

For this subject I have no solution and I'll only be a viewer

Link to comment
Share on other sites

I see. The only way I am familiar with to keep this window from appearing is to subclass the target application to disgard the request to open the window. The problem is that AutoIt is not easily able to do this.

Or may be have those window hooks implemented as a dll call with the required window handle passed as an argument. I need those windows just not being activated. They still have to be created by the program in order to be able to acomplish its job. Making a wrapper like WinWaitNotActivate($window) would be a great feature. Thank you and hopefully some more ideas and may be working solutions will come up in time.

Link to comment
Share on other sites

Unforunately I have no experience in this type of situation. However, there is a registry tweak that will change whether or not ANY application is able to steal focus. Find it here.

I played with the registry settings preventing applications to steal focus and also did the same thing using MS TweakUI. Unfortunately it didn't work. At least not in the way I expected. It seems that it has different behaviour on WinXP and Win98 but it does steal the focus for a moment anyway. When the program is not minimized then the window is created and popups. If I minimize the program the window steals the focus without appearing on screen. Also the tweaked value goes back on Win98 after while. May be there are other apps changing it back or something. Then I tried also to hide the window having the registry tweak applied. is much better in sense that the window I hide does not steal the focus at all. But the problem is in order to be able to click a button (close the window) I need to unhide it. To do that I'm using @SHOWMINNOACTIVE macro and then apply one of WinClose, ControlClick or ControlSend. Either way it requires the window to be unhidden and that brings me back to the problem of being shown for a short moment. @SHOWMINNOACTIVE+WinClose takes the focus away for less time then WinWait+@SW_MINIMIZE so I would stick for a while to that method If I wouldn't have another problem: combination @SW_HIDE + tweak is not consistent. Once in a while that window gets activated and popups or just steal the focus. This happens mostly if I need to switch often between different applications. Otherwise it would be almost perfect. But because of that I have to go for WinWait+@SW_MINIMIZE with more annoying screen flicking. So you can see how appearently a small problem turns to be a real pain in ass in my case :lmao:
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...