Fog Creek Software
Discussion Board




Moving an application to the foreground

I am looking for ways to move an application to the foreground.
Right now I use "SetForegroundWindow", but on XP this does not move it to the foreground, but blinks the icon in the taskbar.

Are there other ways to force an application to become the active and focused application (preferably in VB or else Win32)?

Practical Geezer
Wednesday, May 14, 2003

Have a look at http://www.mvps.org/vbnet/ and/or http://www.mvps.org/vb/

These are two of my favourite sites for 'how to' snippets.

Justin
Wednesday, May 14, 2003

I believe that it's now considered rude for an application to force itself to the foreground and demand attention like a petulant child, hence the flashing Taskbar button.

John Topley
Wednesday, May 14, 2003

John,

I would agree, but this application is a personal security application. Although security guards are not supposed to be doing something else, and there is audio feedback that there is an alarm, some organisations, and possibly even some official regulations might require the application to be forced to the foreground.
I don't think it is a good idea, because if a security guard is using another application, we have to assume that that is important too, and that she is well equiped to decide which is more important. But still ...

Practical Geezer
Wednesday, May 14, 2003

The trouble with forcing yourself to the foreground is that if you do it while the user is typing, their keystrokes are all of a sudden diverted to another application where they have a different meaning. For example, your rude security application pops up saying "blah blah blah [Yes][No]" and the user happens to be typing "banana" into an email message, so the "n" gets interpreted as "No" which has disasterous affects and the user doesn't even SEE your rude dialog or know what it just did or how to recover.

So the Windows UI people started cracking down on applications bringing themselves to the front.

Joel Spolsky
Wednesday, May 14, 2003

Can't you still use http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Windows/WindowReference/WindowFunctions/SetWindowPos.asp to briefly set your app to HWND_TOPMOST ?

Just me (Sir to you)
Wednesday, May 14, 2003

Joel,

Couldn't agree more. I don't like it either, but I can't seem to convince the people asking. I can sympathise because of the nature of the problem -- which is needing immediate attention for an urgent security violation -- but I think this is not the proper solution to an otherwise valid problem. Still...

Just Me,
Will look into it, thanks.

Practical Geezer
Wednesday, May 14, 2003

VB example:

Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_SHOWWINDOW = &H40
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2
Private Const Flags = SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE

Private Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Private Function SetTopMostWindow(Window As Form, Topmost As Boolean) As Long

    If Topmost = True Then
        SetTopMostWindow = SetWindowPos(Window.hwnd, HWND_TOPMOST, 0, 0, 0, 0, Flags)
    Else
        SetTopMostWindow = SetWindowPos(Window.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, Flags)
    End If

End Function

Private Sub Form_Load()

    'Exemples d'utilisations de la fonction :
    SetTopMostWindow Me, True 'Active l'affichage au premier plan
    SetTopMostWindow Me, False 'Désactive l'affichage au premier plan

End Sub


from: http://faq.vb.free.fr/index.php?question=50

Just me (Sir to you)
Wednesday, May 14, 2003

You might interrupt the guards' game of FreeCell :-)

I think that XP's single greatest achievement is the flash in taskbar instead of popping the window to the top. I'm still stuck on NT 4.0 at work, and I throw things several times a day when an app steals the focus.

Rob Warner
Wednesday, May 14, 2003

Just me, thanks.

I will be trying this immediately. Just in my defense, I am only posing as a programmer to help someone out, which is why I am asking these silly questions that real programmers know how to do of course :-)

Practical Geezer
Wednesday, May 14, 2003

There is one exception to the obvious problem(s) of bringing another application to the front.

I think we all agree that having a application pop to the front is nasty. I would not even try to unleash such a thing on my users.

However, there is a good exception here!

That exception is when you actually DO NEED the application to come to the front!

Windows does the following:

If you activate a application, and is it WAS minimized, then it will flash in the task bar. However, if that application was NOT minimized, and you activate the application, then it will come to the front.

So, this different behavior actually creates a problem for me.

I have a ms-access form to edit some data with a word merge button. The user clicks on that button, I launch word, and execute a single record mail merge. So far, this is great. The user edits, or perhaps just prints the word doc. They can now close the doc and they are done (they have NOT closed word yet).

At this point, they can now switch back to my access application via the task bar. They move to another record, or even perhaps enter a new one. They now want do word template merge again. If they whack the word button, then of course I don’t re-launch another running copy of word, but I grab the  existing running copy of word that is loaded in memory.  (no need to launch another running copy of word).

At this point once again if I use appActiivate, then the user is now looking at the word doc.

Lets assume this time that the user prints the word doc, closes the doc, and then MINIMIZES WORD!

At this point, I am now in big trouble. If the user minimizes word to switch back to ms-access, then my application behaviors will change. Further, watching people use my application, a LARGE PORTION of them minimize word when done . I am in big trouble now.

The next time I use the launch word template button, I get a flashing box on the task bar!. This is not expected behavior. The user does want word to come to the front, and is expecting this!

So, the solution I used to solve this problem is both to activate the application, and MAXIMIZE that application also. This gets around this nasty problem explained above. None of my users have complained about the fact that word is maximized when it launched (some people do not like maximized applications, but this problem is minor to that of dealing with a flashing box in the task bar.

So, in summary, if the application is minimized, and you activate it, you get the flashing box. So, add in a maximize, and you are ok.

To thus get word to the front, I had to use:

AppActivate "Microsoft Word"
WordApp.WindowState = 1  'wdWindowStateMaximize

I don’t know the api’s to do the above, but I guessing that would also work.

By the way, if anyone wants to word enable a ms-access form, then feel free to grab my word merge code example. It allows you to instantly word enable any ms-access form you have with a simple line of code.

You can download my code at:

http://www.attcanada.net/~kallal.msn/msaccess/msaccess.html

Albert D. Kallal
Edmonton, Alberta Canada
kallal@msn.com
http://www.attcanada.net/~kallal.msn

Albert D. Kallal
Wednesday, May 14, 2003

"I think that XP's single greatest achievement is the flash in taskbar instead of popping the window to the top."

I agree, apart from the fact that this feature actually debuted in Windows 2000! ;-)

John Topley
Wednesday, May 14, 2003

As "Just Me" shows, you should use the "SetWindowsPos" method to bring the window to the top of the Z-order, instead of the "SetForegroundWindow". SetForegroundWindow also sets the focus to (activates) the window that is moved to the foreground and this can cause unintended results as described in previous entries. This is why its behavior was changed in Windows XP (and 2000 and Me, I believe) to flash the taskbar icon instead of setting the window as foreground and activating it.

SetWindowsPos will also activate the window unless you pass the "SWP_NOACTIVATE" flag, which is why the code sample shown above includes this flag, along with the "SWP_NOMOVE" and "SWP_NOSIZE" flags (which preserve the window's current size and position) and the "SWP_SHOWWINDOW" flag (to display, not hide, the window).

If the window is minimized, you may also need to call the "ShowWindow" method with the parameter "SW_SHOWNOACTIVATE" (as mentioned by Albert) - I don't remember if the "SWP_SHOWWINDOW" flag is sufficient to restore a minimized window. [Albert, in your code, have you tried ".WindowState = 0" which should restore the window to its normal, not maximized, state?]

Philip Dickerson
Wednesday, May 14, 2003

Gee, Phillip. Good suggestion here.

I just tried your suggestion, and it works.

I mean obviously, I just have to un-mnimzine the window, and I am home free.

I just tested this on a ME notebook, but I betting that it will work on win2k also.

So, the “flashing” task bar is due to the application being minimized, but I can do a restore, and not actually have to max the window. This makes a lot of sense.

So, regardless, the solution is to un-minmize the window, but you don’t have to max it!

Great stuff!

Now I am off going to change that code to “restore” the window..and not max it!

Hey, you now fixed my issue of having to max the window! ….I did not ever have to do that!


Albert D. Kallal
Edmonton, Alberta Canada
kallal@msn.com
http://www.attcanada.net/~kallal.msn

Albert D. Kallal
Wednesday, May 14, 2003

Regarding apps bringing themselves to the front, it bothers me to no end.  I use TweakUI to make my mouse behave with focus-follows-pointer (or sloppy focus to some).  *Extremely* helpful for when you have a full screened app and you want to type into it using data from a small editor window on top of it, without switching back and forth.

The problem is when some applications (TOAD, and Visio come to mind) bring themselves to the front as soon as the mouse pointer enters them.  Very irritating.  Since it's only those two applications that I use that do that, I can generally work around it by putting them on the second monitor, but it still bites me at least once a day.

So please, for all you people coding window focus stuff, don't forget about the people with sloppy focus! :)

Andrew Hurst
Wednesday, May 14, 2003

The Win32 calls have direct equivalents in VB. It's as easy as:

    Me.WindowState = vbNormal
    Me.SetFocus

Tested on Windows 2000.

echidna
Wednesday, May 14, 2003

Sounds like a system admin issue to me.  If indeed the sec officer slacked off and didn't see a message that the safe is broken into or whatever because he is playing freecell; then its the admins job to set up a policy on that machine only allowing necessary apps to run.

Maybe he needs a dual monitor set up and always have the necessary app in it own monitor...

apw
Wednesday, May 14, 2003

Interestingly I was dealing with this issue yesterday. I wanted a second instance of an application to re-activate the first, and was having problems ensuring consistent behaviour on all Win32 platforms.

Under Windows 95 and NT4, if an inactive application calls SetActiveWindow() or SetForegroundWindow() using the HWND of one of its windows, this makes the application active. The same applies if it calls SetWindowPos() with HWND_TOP and SWP_SHOWWINDOW (no need for HWND_TOPMOST windows). These 3 APIs are basically equivalent.

Under ME and XP, this does not happen. Instead the inactive application has its button highlighted on the windows taskbar but is not made active. Also if the inactive application calls SetForegroundWindow(), the same
thing happens.

If SetForegroundWindow() is called from an active application (an app with the active window), and is passed the HWND of a window in an inactive application, it *can* properly activate the other application and the other window. But if an inactive application calls SetForegroundWindow(), it can't make itself active. This applies under all 32 bit versions of Windows.

Therefore the only reliable system of inter-application activations that works under all versions of Windows is for the currently active application to call SetForegroundWindow() using the HWND of a window
in the other application.

PS: As everyone (including our illustrious leader :) ) has pointed out, I realize apps should not force themselves to the foreground. This thread is about 'how', not 'should I'.

Mr Foreground
Wednesday, May 14, 2003

If you use HWND_TOPMOST (not HWND_TOP) with SetWindowsPos, this will bring a window (whether or not it is the active window) to the front, even on Windows 2000, Me, and XP. If you don't want to leave it as forced to being the top window, then you can wait a short period of time (long enough for the window to have become visible as the topmost window) and call SetWindowsPos again with HWND_NOTOPMOST - it will then still remain as the topmost window until you click in a different window ar otherwise change the active window.

Philip Dickerson
Wednesday, May 14, 2003

Setting WindowState = vbNormal and calling SetFocus will also bring a minimised, non-focussed application to the foreground, even in Windows 2000 and XP.

The problem with SetForegroundWindow is that it's local to the process.
 

echidna
Wednesday, May 14, 2003

Consider using a tray icon with balloon tip or popup box like Windows Messenger.

pUnk
Wednesday, May 14, 2003

Phllip Dickerson's comments are extremely useful. However, the window which comes to the front still does not have the focus, and calling SetFocus() has no effect. Any more ideas?

Geoff Walsh
Wednesday, March 10, 2004

*  Recent Topics

*  Fog Creek Home