Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing the creation of a WPF Window's native Win32 handle

I need to access the Win32 window handles of some of my WPF windows so I can handle Win32 activation messages. I know I can use PresentationSource.FromVisual or WindowInteropHelper to get the Win32 window handle, but I am running into problems if the WPF window has not been created yet.

If I use PresentationSource.FromVisual and the window has not been created, the returned PresentationSource is null. If I use WindowInteropHelper and the window has not been created, the Handle property is IntPtr.Zero (null).

I tried calling this.Show() and this.Hide() on the window before I tried to access the handle. I can then get the handle, but the window flashes momentarily on the screen (ugly!).

Does anyone know of a way to force a WPF window to be created? In Windows Forms this was as easy as accessing the Form.Handle property.

Edit: I ended up going with a variant on Chris Taylor's answer. Here it is, in case it helps someone else:

static void InitializeWindow(Window window)
{
    // Get the current values of the properties we are going to change
    double oldWidth = window.Width;
    double oldHeight = window.Height;
    WindowStyle oldWindowStyle = window.WindowStyle;
    bool oldShowInTaskbar = window.ShowInTaskbar;
    bool oldShowActivated = window.ShowActivated;

    // Change the properties to make the window invisible
    window.Width = 0;
    window.Height = 0;
    window.WindowStyle = WindowStyle.None;
    window.ShowInTaskbar = false;
    window.ShowActivated = false;

    // Make WPF create the window's handle
    window.Show();
    window.Hide();

    // Restore the old values
    window.Width = oldWidth;
    window.Height = oldHeight;
    window.WindowStyle = oldWindowStyle;
    window.ShowInTaskbar = oldShowInTaskbar;
    window.ShowActivated = oldShowActivated;
}

// Use it like this:
InitializeWindow(myWpfWindow);
like image 736
Zach Johnson Avatar asked Jul 10 '10 19:07

Zach Johnson


2 Answers

Use WindowInteropHelper.EnsureHandle, it does exactly what you need.

like image 186
Daniel Albuschat Avatar answered Oct 03 '22 21:10

Daniel Albuschat


One option is to set window state to minimized and not to show in the taskbar before Showing the window. Try something like this.

  IntPtr hWnd;
  WindowInteropHelper helper = new WindowInteropHelper(wnd);

  WindowState prevState = wnd.WindowState;
  bool prevShowInTaskBar = wnd.ShowInTaskbar;

  wnd.ShowInTaskbar = false;
  wnd.WindowState = WindowState.Minimized;
  wnd.Show();
  hWnd = helper.Handle;
  wnd.Hide();

  wnd.ShowInTaskbar = prevShowInTaskBar;
  wnd.WindowState = prevState;
like image 45
Chris Taylor Avatar answered Oct 03 '22 22:10

Chris Taylor