none
When the Window handle is available in WPF

    السؤال

  • In my application, after initializing an instance of Window and before showing it, I need to access its handle to do some tasks. Following code will return Zero:

    Window window = new Window();
    IntPtr windowHandle1 = new WindowInteropHelper(window).Handle;
    IntPtr windowHandle2 = (PresentationSource.FromVisual(window) as HwndSource).Handle;
    

    However, it works perfectly if I place these code in SourceInitialized or Loaded events:

    void Window_SourceInitialized(object sender, EventArgs e)
    {
      Window window = sender as Window;
      if (window != null)
      {
        IntPtr windowHandle1 = new WindowInteropHelper(window).Handle;
        IntPtr windowHandle2 = (PresentationSource.FromVisual(window) as HwndSource).Handle;
      }
    }
    
    

    Could someone give me a solution to make the Window handle available but not shows it.

     

    Thanks,

    Victory


    Thanks, Victory
    09/صفر/1432 08:43 ص

الإجابات

  • Starting from .NetFX 4.0 there is no need to wait for SourceInitialized event.

    You can get window handle just like this:

     

    var window = new Window();
    var handle = new WindowInteropHelper(window).EnsureHandle();
    

     

    14/صفر/1432 10:06 ص
  • I thought you would not get HWND on a window until Show()... right?


    Javaman

    Right - if you use NetFX 3.5 and earlier.

    But NetFX 4.0 gives you "WindowInteropHelper.EnsureHandle()" method.

    14/صفر/1432 07:09 م
  • Here is EnsureHandle method for NetFX 3.5 WindowInteropHelper class - implemented as an extension.

    It`s behavior is exactly the same as NetFX 4.0 EnsureHandle method.

     

    using System.Reflection;
    
    namespace System.Windows.Interop
    {
     /// <summary>
     /// Provides NetFX 4.0 EnsureHandle method for
     /// NetFX 3.5 WindowInteropHelper class.
     /// </summary>
     public static class WindowInteropHelperExtensions
     {
      /// <summary>
      /// Creates the HWND of the window if the HWND has not been created yet.
      /// </summary>
      /// <param name="helper">An instance of WindowInteropHelper class.</param>
      /// <returns>An IntPtr that represents the HWND.</returns>
      /// <remarks>Use the EnsureHandle method when you want to separate
      /// window handle (HWND) creation from the
      /// actual showing of the managed Window.</remarks>
      public static IntPtr EnsureHandle(this WindowInteropHelper helper)
      {
       if (helper == null)
        throw new ArgumentNullException("helper");
    
       if (helper.Handle == IntPtr.Zero)
       {
        var window = (Window)typeof(WindowInteropHelper).InvokeMember("_window",
          BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic,
    null, helper, null); typeof(Window).InvokeMember("SafeCreateWindow", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
    null, window, null); } return helper.Handle; } } }

     

    And here is usage example:

     

    var window = new Window();
    var handle = new WindowInteropHelper(window).EnsureHandle();
    

     

    This example works both in NetFX 4.0 (without any extensions) and NetFX 3.5 (requires an extension provided above).

    23/صفر/1432 03:05 م
  • Hi Victory,

    It seems the handle is available when Window.SourceInitialized event fires, and the Window is not rendered at that point. So I think you can place your code in SourceInitialized to accomplish this.

    If you still have any doubts or concerns about this issue, please feel free to let me know.


    Best regards,
    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    14/صفر/1432 09:17 ص

جميع الردود

  • Hi there,

    the handle will be available after the window has finished loading and is ready for interaction, which is the case when the loaded-event has fired (see FrameworkElement.Loaded Event ).


    Cheers,
    Olaf
    http://blogs.intuidev.com
    09/صفر/1432 12:10 م
  • Hi Victory,

    It seems the handle is available when Window.SourceInitialized event fires, and the Window is not rendered at that point. So I think you can place your code in SourceInitialized to accomplish this.

    If you still have any doubts or concerns about this issue, please feel free to let me know.


    Best regards,
    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    14/صفر/1432 09:17 ص
  • Starting from .NetFX 4.0 there is no need to wait for SourceInitialized event.

    You can get window handle just like this:

     

    var window = new Window();
    var handle = new WindowInteropHelper(window).EnsureHandle();
    

     

    14/صفر/1432 10:06 ص
  • The other answers on this thread are excellent, but I did have a question.

    I thought you would not get HWND on a window until Show()... right?


    Javaman
    14/صفر/1432 10:28 ص
  • I thought you would not get HWND on a window until Show()... right?


    Javaman

    Right - if you use NetFX 3.5 and earlier.

    But NetFX 4.0 gives you "WindowInteropHelper.EnsureHandle()" method.

    14/صفر/1432 07:09 م
  • Hi Victory,

    Just checking in to see if the information was helpful. Please let us know if you would like further assistance.

    Have a nice day!


    Best regards,
    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    17/صفر/1432 01:48 ص
  • Unfortunately, our projects base on .NET 3.5 and WindowInteropHelper doesn't support manual way to force OnSourceInitialized started. Does .NET 3.5 provide a similar method?
    Thanks, Victory
    22/صفر/1432 06:45 ص
  • I double check "EnsureHandle" in .NET 4.0 and it triggers Window.SourceInitialized event. I wonder whether there is an equivalent method in .NET 3.5?

    Actually, I can live with the approach that I obtain the window handle in SourceInitialized event. Just find a way to make my life easier.


    Thanks, Victory
    22/صفر/1432 06:49 ص
  • Glad to know this new feature!

    I bet there isn't such method in 3.5, that's why they added it in 4.0.

    23/صفر/1432 09:14 ص
  • Here is EnsureHandle method for NetFX 3.5 WindowInteropHelper class - implemented as an extension.

    It`s behavior is exactly the same as NetFX 4.0 EnsureHandle method.

     

    using System.Reflection;
    
    namespace System.Windows.Interop
    {
     /// <summary>
     /// Provides NetFX 4.0 EnsureHandle method for
     /// NetFX 3.5 WindowInteropHelper class.
     /// </summary>
     public static class WindowInteropHelperExtensions
     {
      /// <summary>
      /// Creates the HWND of the window if the HWND has not been created yet.
      /// </summary>
      /// <param name="helper">An instance of WindowInteropHelper class.</param>
      /// <returns>An IntPtr that represents the HWND.</returns>
      /// <remarks>Use the EnsureHandle method when you want to separate
      /// window handle (HWND) creation from the
      /// actual showing of the managed Window.</remarks>
      public static IntPtr EnsureHandle(this WindowInteropHelper helper)
      {
       if (helper == null)
        throw new ArgumentNullException("helper");
    
       if (helper.Handle == IntPtr.Zero)
       {
        var window = (Window)typeof(WindowInteropHelper).InvokeMember("_window",
          BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic,
    null, helper, null); typeof(Window).InvokeMember("SafeCreateWindow", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
    null, window, null); } return helper.Handle; } } }

     

    And here is usage example:

     

    var window = new Window();
    var handle = new WindowInteropHelper(window).EnsureHandle();
    

     

    This example works both in NetFX 4.0 (without any extensions) and NetFX 3.5 (requires an extension provided above).

    23/صفر/1432 03:05 م