views:

373

answers:

3

I've got an application that sits in the system tray, which when double clicked on opens a window, fairly standard; however, when you close the window I'd like the window that was focussed before mine was opened to be given back focus.

If I pop my window up by a keyboard shortcut, I'm able to restore the previous focus on close by using the GetForegroundWindow API call before my window shows, then the SetForegroundWindow method after my window closes (with the value of the first call) to restore focus. This doesn't work when you open then window through the system tray, because the user has essentially made the system tray focus.

I've tried using a combination of GetForegroundWindow, GetWindow, and GetTopMostWindow to try to navigate the z-order to find the second window after the system tray (going on the assumption that the system tray will have jumped to the top, so logically the next one down would be the original front). I haven't had any success though, the results of those functions are pretty useless as they don't seem to give me any logical structure.

Does anyone have any ideas on how I could achieve this?

I had thought about some kind of background watcher, which just sits and monitors which is the front window and stores a pointer to it, but that'll be flaky at best.

This is on Windows (I'm personally on x64 Server 2008) and with .Net 3.5.

+1  A: 

I took a look at all my system tray icons and they have the same behavior as your program. Messing with Windows focus management is hairy, you might want to think twice (or more) before trying to change the standard behavior.

jdigital
I appreciate the warning, but this behaviour is desired. The app acts as an overlay, which you use to insert text into the app that had focus. It works great if you get the window up by a shortcut key, but the system tray kills the passthrough.
James Gregory
Do apps similar to yours have the same problem?
jdigital
+2  A: 

Although this might be a nice usability feature, you probably know that with Windows 7 the tray will get a (much) less prominent place on the desktop.

The only way to actually do this, is to monitor for Windows messages and track which window had the focus before your application got focus. Besides that AFAIK, there's not much you can do.

Jeroen Landheer
That's what I do when launching through keyboard shortcuts, but when it comes to using the tray, the last application that had focus before mine is the tray!I was pretty sure that there wasn't going to be a nice solution to this, but it's not my primary usage mechanism anyway.
James Gregory
With "Monitor Windows Messages" I mean really doing just that. You can for example remember the last 4 windows that had focus and go back in the queue skipping the system tray to get the handle of the window that had focus before that. This ain't easy though and will require system API calls
Jeroen Landheer
I tried to do such a thing, but I couldn't seem to get the right combination of calls. I tried walking backwards and forwards using GetWindow working from GetTopWindow, but didn't have any luck. Do you have any tips?
James Gregory
You could give Spy++ a try to see which messages are passed, but beyond that I'm just as in te dark on this as you are.
Jeroen Landheer
Accepted because although I didn't get the answer I wanted, this was the answer I expected. Spy++ was a good call too. Thanks.
James Gregory
A: 

I did this to get back previous window

SendKeys.Send("%{TAB}");

I know it is not 'the solution', but serving the purpose to some extent.