PDA

View Full Version : XP focus problem workaround



Selyb
November 22nd, 2003, 12:05 AM
its kind of ugly but it works

Command 1
Send Message
Command or 273
wParam = 3
lParam = 0

*** Target ***
ClassName = GirderHidden
Executable = Girder.exe

Match Invisible Tasks
Only send to first Match = 1
Command 2
Girder
Minimize Girder
Command 3
Window
Set Focus

*** Target ***
your window
Command 4
Window
Close

*** Target ***
Name = Girder 3.2
Executable = Girder.exe

Send only to first match = 1

Selyb
January 30th, 2004, 12:28 AM
or use this small app (www.selyb.com/sendfocus.zip) i wrote
Mirror (http://mason.gmu.edu/~tfemino/Files/SendFocus.rar) Thanx to Thracx
usage:
sendfocus.exe [/s] Window Title|Window Class
e.g. sendfocus.exe "Microsoft Internet Explorer"
sendfocus.exe ConsoleWindowClass
sendfocus.exe /s Drempels

/s does not warn you if the window was not found

Promixis
January 30th, 2004, 06:47 AM
Selby,

How does this work differently then the Girder command Window/Set Focus? Am I missiing something :)

Selyb
January 30th, 2004, 10:31 AM
in xp a window cannot send focus if it is not the foreground window
if you create a hotkey to have girder send focus to another window it works as long as you are working on it or the girder window is open
when girder is in the background it doesnt send focus properly
there have been several threads about this over the last year

Selyb
January 30th, 2004, 10:34 AM
Found Here (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Windows/WindowReference/WindowFunctions/AllowSetForegroundWindow.asp)
Remarks

Starting with Microsoft Windows 98 and Windows 2000, the system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
Windows 2000/XP: No menus are active.

A process that can set the foreground window can enable another process to set the foreground window by calling AllowSetForegroundWindow. The process specified by dwProcessId loses the ability to set the foreground window the next time the user generates input, unless the input is directed at that process, or the next time a process calls AllowSetForegroundWindow, unless that process is specified.

Promixis
January 30th, 2004, 10:41 AM
Ah, cool - I haven't had that problem. Maybe you could PM Ron with how you did it so we can fix it!

Selyb
January 30th, 2004, 04:37 PM
i did, thats how i got the thread in the tips and tricks forum
problem is that an existing window cannot send focus if it doesnt have focus
but when you create a window (or start an application) it automatically receives focus
in the pm i told that i believe if you create a window that will never be seen (1 pixel by 1 pixel, or somewhere where the current resolution cant see it), send the focus, then destroy the window it should work fine

Ron
February 1st, 2004, 12:11 AM
Actually I'd have to spawn a new program, not just a window. I'll think about it.

Sancc
February 8th, 2004, 05:52 AM
Can someone please repost the prog ?
It's no longer available from selybs page.

Fredrick Freekowtski
March 8th, 2004, 07:52 AM
thanks for sendfocus.exe, selyb!
this works great...

Selyb
March 9th, 2004, 10:53 AM
i host this from my home computer and sometimes the server is down
here is the code i used so anyone with VB installed can compile it
just paste this in a module
Dim sWindow As Long, sText As String, bEcho As Boolean
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Sub Main()
bEcho = True
If LenB(Command()) Then sText = Command() Else sText = InputBox("Please enter window title or class name", "SendFocus")
If LeftB(sText, 6) = "/s " Then bEcho = False: sText = MidB(sText, 7)
If RightB(sText, 6) = " /s" Then bEcho = False: sText = LeftB(sText, LenB(sText) - 6)
If sText = "?" Or sText = "/?" Or LCase(sText) = "/help" Then MsgBox "Usage:" & vbNewLine & "SendFocus.exe [/s] [Window Title|Window ClassName]" & vbNewLine & vbNewLine & "/s Silent", vbCritical, "SendFocus": Exit Sub
If LeftB(sText, 2) = ChrW(34) And RightB(sText, 2) = ChrW(34) Then sText = MidB(sText, 3, LenB(sText) - 4)
sWindow = FindWindow(vbNullString, sText)
If sWindow = 0 Then sWindow = FindWindow(sText, vbNullString)
If bEcho Then If sWindow = 0 Then MsgBox "Window Not Found - """ & sText & ChrW(34), vbCritical, "SendFocus" Else SetForegroundWindow sWindow
End Sub

Fredrick Freekowtski
March 9th, 2004, 11:34 AM
would it be hard to include something like "only send to first match"?

Selyb
March 9th, 2004, 06:50 PM
Actually I'd have to spawn a new program, not just a window. I'll think about it.i had the idea you could just create a new window because i can have girder restore from the tray icon and it gets focus
i dont really understand why it gets focus since this seems to break the rules i posted above

Eddie
March 26th, 2004, 02:51 PM
I decided to give sendfocus.exe a try after finding out that "Set Focus" function in Girder wasn't reliable (it actually is quite misleading when you find it works when you "Test Command" it (and Girder is in focus), but doesn't work when you actually try and execute it from a hotkey :)

Anyway.. I'm afraid to report that there seems to be a few problems with this little app :(
SendFocus doesn't always close itself properly, and when I come to shutdown my machine, it refuses to quit, holding my system up. I have to manually go into Task Manager and "End Process" the (usually many) sendfocus.exe instances, each taking up about 4Mb :|

I've seemed to find a (crude?) workaround this problem: by setting ForegroundLockTimeout to 0 in the registry: meaning that this "prevent apps from stealing focus" XP feature is disabled.

So far, I haven't had any adverse side-effects from this, so I'll keep the value at 0.

My other plan, should the above one fail, is to get Grider to silently "import" the registry key (using some sort of switch to supress the "Are you sure?" box, I believe) to set it the value at 0, (succesfully) set focus to another application, then change the value back.

Not the most efficient way, but it's "silent" :)

(Or is there another way of setting registry values from within Girder?
And has Ron considered calling the API before and after each and every SetFocus? (not the most elegant solution I know, but it is one way), sort of like:
- Store value from GetForegroundLockTimeout()
- Call SetForegroundLockTimeout() with a value of 0
- Set Focus to target
- Call SetForegroundLockTimeout() with previous value)

Would that work?

Eddie

EDIT: Hrm.. not as reliable as SendFocus is... :(
Sometimes it works. Sometimes in doesn't. And when I test it again a second time - it usually works - just not when you want, or need, it to :P

Selyb
March 27th, 2004, 01:11 AM
Eddie: I'm truthfully sorry but I have no idea how the app could be not exiting properly, ive used it over and over again and the only problem i have ever come across is if I click on a window between executing the trigger in girder and the app sending the focus
BTW, i have changed that registry setting and i have found no difference at all
i tried to allow programs to steal focus and i could not get it to work

Fred: it should not work on more than one window
all the app does is ask windows for the handle of the window named with the parameter then ask windows to send focus to that window handle

Eddie
March 28th, 2004, 12:35 PM
I've read through your code, Selby, and although I'm more C++ than VB, I can't see what you're doing differently to make it succesfully set focus to another window when Girder can't do it?
(In particular the SetForegroundWindow call at the very end?)

I think I might have a idea as to why it doesn't work: your app isn't truly "silent", e.g. if it doesn't find the window, it pops a message box informing the user, and requiring user input. I think I might have set Girder to run sendfocus.exe with the "Hidden" startup option, meaning I never get to see the prompt, or close it (nor do I want to).

Could you possibly re-compile the application to remove user input elements?

Also.. one last problem :)
Your app doesn't seem to like unicode either :| (or Girder doesn't pass the variable correctly)
My apps often have chinese in their title, and after capturing the title using "Get Caption" in Girder, I pass the variable to sendfocus and it often cries that it cannot find a window named "???" :)

Cheers,

Eddie

Selyb
March 29th, 2004, 11:56 AM
my app doesnt do anything different from girder
it works because it is a separate exe
what would be a more desirable action to perform if the given window is not found?
i want to be notified in some way when something goes awry and a msgbox was the easiest thing i could do
i could easily pop up the msgbox for only 1 or 2 seconds

Eddie
March 29th, 2004, 05:40 PM
my app doesnt do anything different from girder
it works because it is a separate exe
what would be a more desirable action to perform if the given window is not found?
i want to be notified in some way when something goes awry and a msgbox was the easiest thing i could do
i could easily pop up the msgbox for only 1 or 2 seconds

Could you have a silent switch then?

e.g. sendfocus -silent [window class]

I would love to modify to my tastes.. but I don't have a VB compiler :(

In that case, what I don't understand is why does XP allow your program to set focus? Although it's a new process, the window it's setting focus to is not a child, nor does it comply with any of the rules you posted?

Care to enlighten me?

Cheers Selyb!

Eddie

EDIT: Regarding the chinese unicode issue I posted about above, I don't think (as I've just tried it) the "Get Caption" action correctly captures the text of the active application with chinese in it's title.. :(, so it might not be your app after all. Maybe a girder dev would like to give us a comment?

Selyb
March 29th, 2004, 07:04 PM
Could you have a silent switch then?

e.g. sendfocus -silent [window class]

I would love to modify to my tastes.. but I don't have a VB compiler :(exe updated
Usage: SendFocus.exe [/?|/help|?]|[/s] Window Title|Window Class
E.G.
SendFocus.exe /?
SendFocus.exe /s Internet Exlporer
SendFocus.exe Girder
SendFocus.exe ConsoleWindowClass /s
In that case, what I don't understand is why does XP allow your program to set focus? Although it's a new process, the window it's setting focus to is not a child, nor does it comply with any of the rules you posted?

Care to enlighten me?none of the rules i quoted above mention 'starting a new process'

Eddie
March 30th, 2004, 11:09 AM
Could you have a silent switch then?

e.g. sendfocus -silent [window class]

I would love to modify to my tastes.. but I don't have a VB compiler :(exe updated
Usage: SendFocus.exe [/?|/help|?]|[/s] Window Title|Window Class
E.G.
SendFocus.exe /?
SendFocus.exe /s Internet Exlporer
SendFocus.exe Girder
SendFocus.exe ConsoleWindowClass /s
In that case, what I don't understand is why does XP allow your program to set focus? Although it's a new process, the window it's setting focus to is not a child, nor does it comply with any of the rules you posted?

Care to enlighten me?none of the rules i quoted above mention 'starting a new process'

Thanks Selyb!

Just grabbed the new exe file from your website, but the /s bit doesn't seem to work though :|
I've tried /? which confirms that I have got the new exe, and I've tried it without the /s switch, and it works perfectly then. Tried it before and after the executable, in Girder, and in the Start Menu -> Run and had no luck..

What I tried to say above was that if you start a new process, you automatically get focus.. right? And with that focus, you can give it other applications, namely any "child" windows you create?
If this is not the case, why does this (simple) program bypass the anti-steal-focus "protection", what does it do (I assumed that it was a new process) that Girder can't, if you see what I mean?

I'm confused :)

Eddie

EDIT: This doesnt work:

E:\Girder\sendfocus.exe /s My Computer
E:\Girder\sendfocus.exe My Computer /s

Yet:

E:\Girder\sendfocus.exe My Computer

Works perfectly.

Funnily enough, the first two commands, with the "/s" in, don't return a error message of any sort, as it would do if it was trying to find a window named "/s My Computer" or "My Computer /s" - which mean the silent switch (might?) be working.. but you've probably exited the function without actually executing the "set focus" code? Just a guess...

thracx
April 1st, 2004, 06:49 PM
I am still having problems with Girder Sending Focus. Selyb's SendFocus link is broken, and the registry modification didn't seem to help me (well, it seemed to help sometimes and then not other times..).

Hopefully Selyb's link will work again shortly (Selyb, I can offer a small mirror on my webspace if you want). In the meantime, I'd like to hear some success stories..

Selyb
April 1st, 2004, 07:30 PM
This doesnt work:

E:\Girder\sendfocus.exe /s My Computer
E:\Girder\sendfocus.exe My Computer /s

Yet:

E:\Girder\sendfocus.exe My Computer

lol
yeah, i didnt test on a window that was actually open, only tested the switch :-/
gimme just a minute

Selyb
April 1st, 2004, 07:38 PM
done, will update the source posted in just a sec

ok, ive run into a deal here; when i wrote this app i didnt have child windows in mind
i suppose if the child window has a caption it should work but i heard about a case where the window's class didnt find the window and the caption was blank (invisible window)
a workaround for this is to have sendfocus.exe send focus to girder
while this is running have girder loop until it has focus and when it does then send focus to the child window


BTW: anyone who wants to mirror this has my complete permission
if so just give me a way to contact you about any updates (though i dont see myself updating anything about it any time soon :P )

thracx
April 1st, 2004, 09:39 PM
I had Girder setup to give the focus to a Aston plugin, but it wouldn't work whenever a full-screen window had the focus. That was until I started fiddling with this SendFocus app.

SendFocus is currently unable to send to windows such as this one (it's a child, apparently without a window name - Girder could find it, but SendFocus needed the Title [the ClassName didn't work for some reason..] ).

I have a workaround similar to what Selyb suggested, in case any of you run into my problem:
1. Create a MultiGroup
2. Learn your Eventstring
3. Create 3 commands
4. Have the first command use SendFocus to give Girder the focus (O.S. -> Execute -> [SendFocus-Location]
5. Have the second command wait (Window -> Wait -> 16ms [16 works fine for me] )
6. Have the third command send the normal 'Set Focus' command to your window of choice! (Window -> Set Focus [make sure you acquire target properly!] )

Eddie
April 4th, 2004, 07:41 PM
Selyb: This seems to work perfectly. Thanks once again!

Eddie

RacerChris
May 8th, 2004, 08:14 PM
Ok guys. I'm a newbie with Girder, but am having problems with "dependable" Set Focusing. I D/L Selyb's app, but not sure know to incorporate it into my Girder Subroutines. Can anyone LMK

Promixis
May 8th, 2004, 10:16 PM
You can also download the Lua Windows Function plugin which has 2 functinos for setting the foreground window which should work.

RacerChris
May 11th, 2004, 07:23 PM
You can also download the Lua Windows Function plugin which has 2 functinos for setting the foreground window which should work.

Ok. I tried this too, but it is not allowing me to focus on the Dialog Box. Is there something I am missing here? I'm a newbie and may be doing something fundamentally wrong...

This is what I am trying to do:

Using Hot Key to execute a series of commands to change monitor setups using ATI Schemes. The specific problem is using Girder to accept the resolution changes. For what its worth, I pasted the specific command from Girder below: <clip>

Promixis
May 11th, 2004, 07:44 PM
If you want to target a dialog box, then you shouldn't need the lwinfunc. I have found the ATI stuff to be tricky to target correctly.

RacerChris
May 11th, 2004, 08:45 PM
If you want to target a dialog box, then you shouldn't need the lwinfunc. I have found the ATI stuff to be tricky to target correctly.

Yeah, me too. Any suggestions?

Promixis
May 12th, 2004, 09:52 AM
When you bring up the targeting box, you will have to try several different combinations of classname, windowname etc.

If this doesn't work, you can use LWinFunc to do more sophisticated window searching as you can match substrings etc. LWinFunc also has a sendmessage command so you can do it all from lua script. This is definitely more difficult...

korsairr
March 22nd, 2005, 05:56 AM
can someone repost this set focus program? unless there is a better way to bring applications to the front and in focus.

Thanks.

Selyb
July 16th, 2005, 11:11 PM
I put it back on my server

Click Here (http://www.selyb.com/sendfocus.zip)

john-m
September 20th, 2005, 08:58 PM
That link seems to be down :roll: Could someone link to that file for me?! I'm just a newbie but it seems to me that there are certain apps in XP which don't come to the foreground when you re-execute them (eg. BS Player) , and certain others which open multiple instances. In both cases you're completely stumped without the sendfocus file described in this topic.

Promixis
September 20th, 2005, 09:24 PM
use hte lua windows function plugin...

ForceForegroundWindow ()

Sany
November 5th, 2005, 07:14 AM
I'm using Girder 3.3.50 with the world famous :D IgorPlug-3 plugin.
However i could not make my WIN XP Prof (HUN) to shutdown by a single code from my remote control. The syntax is very simple. New Toplevel Group- New Command (edit: OS- Shutdown- apply)- Add eventsring (edit: learn, antirepeat 500ms)

What could the problem be?
...:(

Thanks a lot