views:

6531

answers:

6

How can I bring my WPF application to the front of the desktop? So far I've tried:

SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);

SetWindowPos(new WindowInteropHelper(Application.Current.MainWindow).Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);

None of which are doing the job (Marshal.GetLastWin32Error() is saying these operations completed successfully, and the P/Invoke attributes for each definition do have SetLastError=true).

If I create a new blank WPF application, and call SwitchToThisWindow with a timer, it works exactly as expected, so I'm not sure why it's not working in my original case.

Edit: I'm doing this in conjunction with a global hotkey.

A: 

Well I figured out a work around. I'm making the call from a keyboard hook used to implement a hotkey. The call works as expected if I put it into a BackgroundWorker with a pause. It's a kludge, but I have no idea why it wasn't working originally.

void hotkey_execute()
{
    IntPtr handle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(delegate
        {
            Thread.Sleep(10);
            SwitchToThisWindow(handle, true);
        });
    bg.RunWorkerAsync();
}
Factor Mystic
Just interested: Did you try Window.Activate (as suggested by Morten) and the other suggestions? They seem less hacky than this admitted kludge.
Simpzon
This has been quite awhile ago, but yes, at the time I did try that
Factor Mystic
This does not work on my Windows XP. I recommend @Matthew Xavier 's answer.
Lex Li
+13  A: 
myWindow.Activate();

Attempts to bring the window to the foreground and activates it.

That should do the trick, unless I misunderstood and you want Always on Top behavior. In that case you want:

myWindow.TopMost = true;
Morten Christiansen
I was simply using myWindow.Show() and sometimes it wasn't on top. I placed a call to myWindow.Activate() immediately afterwards and it worked.
Bermo
This worked for me, thank you
Pz
Activate does not work on Windows XP sometimes. I recommend @Matthew Xavier 's answer.
Lex Li
+2  A: 

If the user is interacting with another application, it may not be possible to bring yours to the front. As a general rule, a process can only expect to set the foreground window if that process is already the foreground process. (Microsoft documents the restrictions in the SetForegroundWindow() MSDN entry.) This is because:

  1. The user "owns" the foreground. For example, it would be extremely annoying if another program stole the foreground while the user is typing, at the very least interrupting her workflow, and possibly causing unintended consequences as her keystrokes meant for one application are misinterpreted by the offender until she notices the change.
  2. Imagine that each of two programs checks to see if its window is the foreground and attempts to set it to the foreground if it is not. As soon as the second program is running, the computer is rendered useless as the foreground bounces between the two at every task switch.
Matthew Xavier
Good point. The purpose of the code was in conjunction with a global hotkey, though, and other applications do it somehow.
Factor Mystic
Have to use PInvoke in C# to emulate what is described in this article, http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo.aspx
Lex Li
then why do expression blends error popup dialogs stay visible when I switch to visual studio sometimes? :-/
Simon_Weaver
Simon, I suspect that the error popups you see are "topmost" windows (a design decision of which I disapprove). There is a difference between the foreground window (which receives user input) and a "topmost" window in the Z-order. Any window can make itself "topmost", which places it atop all non-topmost windows, but doesn't give the window keyboard focus, etc. the way becoming the foreground window does.
Matthew Xavier
A: 

The problem could be that the thread calling your code from the hook hasn't been initialized by the runtime so calling runtime methods don't work.

Perhaps you could try doing an Invoke to marshal your code on to the UI thread to call your code that brings the window to the foreground.

joshperry
+4  A: 

In case you need the window to be in front the first time it loads then you should use the following:

private void Window_ContentRendered(object sender, EventArgs e) { this.Topmost = false; }

private void Window_Initialized(object sender, EventArgs e) { this.Topmost = true; }

Amir
Best answer in this thread, in my opinion
Steav
If you develop something similar to Launchy (http://launchy.net) in C#, you should notice this answer is almost useless.
Lex Li
A: 

I have had a similar problem with a WPF application that gets invoked from an Access application via the Shell object.

My solution is below - works in XP and Win7 x64 with app compiled to x86 target.

I'd much rather do this than simulate an alt-tab.

void Window_Loaded(object sender, RoutedEventArgs e)
{
    // make sure the window is normal or maximised
    // this was the core of the problem for me;
    // even though the default was "Normal", starting it via shell minimised it
    this.WindowState = WindowState.Normal;

    // only required for some scenarios
    this.Activate();
}
Seth