So you want to spawn a new WPF window but you don't want it to be activated?  This is doable in Win32, but with WPF, it presents some problems ... until now.  This issue recently came up and some folks (read: not me) on the WPF team discovered a a pretty clever workaround.  Basically, the workaround is to use an obscure windows hooks that exists for Computer Based Training (CBT), which allows or a training program to choose to ignore or allow messages to get through to the window.

So, the solution is to set the hook before calling the Show() method on the window. The call back receives the HCBT_ACTIVATE notification, returns 1 to ignore/prevent the operation, then unhooks the hook. The window is shown, but does not take focus. There is no flicker or visible degradation.

If you'd like to see this working in action, check out the sample application that I've deployed via ClickOnce.  You'll notice that the main window will spawn three windows yet you will continue to be able to type in the textbox of the main window. I've posted the source code and here's the crux of the code if you are interested:

 

using System; 
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace ShowWindowWithoutActivating
{ /// <summary> /// Interaction logic for Window1.xaml
/// </summary>

public partial class Window1 : System.Windows.Window
{
delegate int HookProc(int code, IntPtr wParam, IntPtr lParam); private HookProc myCallbackDelegate; IntPtr hook;

    <span style="color: rgb(43,145,175)">DispatcherTimer</span> dt = <span style="color: rgb(0,0,255)">new</span> <span style="color: rgb(43,145,175)">DispatcherTimer</span>();

    <span style="color: rgb(0,0,255)">int</span> counter = 0;

    <span style="color: rgb(0,0,255)">public</span> Window1()
    {
        InitializeComponent();
        textBox1.Focus();
        dt.Interval = <span style="color: rgb(0,0,255)">new</span> System.<span style="color: rgb(43,145,175)">TimeSpan</span>(0, 0, 3);
        dt.Tick += <span style="color: rgb(0,0,255)">new</span> <span style="color: rgb(43,145,175)">EventHandler</span>(TimerTick);
        dt.Start();

        <span style="color: rgb(0,128,0)">// initialize our delegate

this.myCallbackDelegate = new HookProc(this.MyCallbackFunction);

    }
    <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span> TimerTick(<span style="color: rgb(0,0,255)">object</span> sender, <span style="color: rgb(43,145,175)">EventArgs</span> e)
    {
        <span style="color: rgb(0,0,255)">if</span> (counter == 2) dt.Stop();
        counter++;

        <span style="color: rgb(43,145,175)">Window</span> w = <span style="color: rgb(0,0,255)">new</span> <span style="color: rgb(43,145,175)">Window</span>();
        w.Title = <span style="color: rgb(163,21,21)">"TestWindow"</span>;
        w.Width = 400;
        w.Height = 300;
        w.Top = 400;
        w.Left = 400;

        <span style="color: rgb(0,128,0)">// setup a cbt hook

hook = SetWindowsHookEx(5 /* wh_cbt */, this.myCallbackDelegate, IntPtr.Zero, AppDomain.GetCurrentThreadId());
w.Show(); }

    <span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(0,0,255)">int</span> MyCallbackFunction(<span style="color: rgb(0,0,255)">int</span> code, <span style="color: rgb(43,145,175)">IntPtr</span> wParam, <span style="color: rgb(43,145,175)">IntPtr</span> lParam)
    {
        <span style="color: rgb(0,0,255)">switch</span> (code)
        {
            <span style="color: rgb(0,0,255)">case</span> 5: <span style="color: rgb(0,128,0)">/* HCBT_ACTVIATE */

UnhookWindowsHookEx(hook);
return 1; /* prevent windows from handling activate */ }
//return the value returned by CallNextHookEx return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}

    [<span style="color: rgb(43,145,175)">DllImport</span>(<span style="color: rgb(163,21,21)">"user32.dll"</span>)]
    <span style="color: rgb(0,0,255)">static</span> <span style="color: rgb(0,0,255)">extern</span> <span style="color: rgb(0,0,255)">bool</span> UnhookWindowsHookEx(<span style="color: rgb(43,145,175)">IntPtr</span> hhk);

    [<span style="color: rgb(43,145,175)">DllImport</span>(<span style="color: rgb(163,21,21)">"user32.dll"</span>)]
    <span style="color: rgb(0,0,255)">static</span> <span style="color: rgb(0,0,255)">extern</span> <span style="color: rgb(43,145,175)">IntPtr</span> SetWindowsHookEx(<span style="color: rgb(0,0,255)">int</span> code, <span style="color: rgb(43,145,175)">HookProc</span> func, <span style="color: rgb(43,145,175)">IntPtr</span> hInstance, <span style="color: rgb(0,0,255)">int</span> threadID);

    [<span style="color: rgb(43,145,175)">DllImport</span>(<span style="color: rgb(163,21,21)">"user32.dll"</span>)]
    <span style="color: rgb(0,0,255)">static</span> <span style="color: rgb(0,0,255)">extern</span> <span style="color: rgb(0,0,255)">int</span> CallNextHookEx(<span style="color: rgb(43,145,175)">IntPtr</span> hhk, <span style="color: rgb(0,0,255)">int</span> nCode, <span style="color: rgb(43,145,175)">IntPtr</span> wParam, <span style="color: rgb(43,145,175)">IntPtr</span> lParam);

}

}