20

I'm writing a WPF app, and I'd like to make use of this library.

I can get an IntPtr for the window by using

new WindowInteropHelper(this).Handle

but that won't cast to System.Windows.Forms.IWin32Window, which I need to show this WinForms dialog.

How do I cast IntPtr to System.Windows.Forms.IWin32Window?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Arsen Zahray
  • 24,367
  • 48
  • 131
  • 224

1 Answers1

38

OPTION 1

IWin32Window only expects a Handle property, which is not too difficult to implement since you already have the IntPtr. Create a wrapper class that implements IWin32Window:

public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    public WindowWrapper(IntPtr handle)
    {
        _hwnd = handle;
    }

    public WindowWrapper(Window window)
    {
        _hwnd = new WindowInteropHelper(window).Handle;
    }

    public IntPtr Handle
    {
        get { return _hwnd; }
    }

    private IntPtr _hwnd;
}

You would then get your IWin32Window like this:

IWin32Window win32Window = new WindowWrapper(new WindowInteropHelper(this).Handle);

or (in response to KeithS' suggestion):

IWin32Window win32Window = new WindowWrapper(this);

OPTION 2 (thx to Scott Chamberlain's comment)

Use the existing NativeWindow class, which implements IWin32Window:

NativeWindow win32Parent = new NativeWindow();
win32Parent.AssignHandle(new WindowInteropHelper(this).Handle);
blins
  • 2,515
  • 21
  • 32
Tung
  • 5,334
  • 1
  • 34
  • 41
  • Great answer; the class, though, might accept a Window and handle the first layer of WindowInteropHelper wrapping as well, so all you need is `new WindowWrapper(this)` and you have something to pass in as an IWin32Window. – KeithS Apr 11 '15 at 01:56
  • 8
    Instead of making your own class .NET provides a similar class already in its [`NativeWindow`](https://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow%28v=vs.110%29.aspx) class. Just call [`AssignHandle(IntPtr)`](https://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.assignhandle(v=vs.110).aspx) with the handle from the function provided by the OP. – Scott Chamberlain Apr 16 '15 at 04:28
  • I couldn't get Option 2 to compile. My code... `System.Windows.Forms.IWin32Window win32Window = new System.Windows.Forms.NativeWindow(); win32Window.AssignHandle(new WindowInteropHelper(this).Handle);` ...results in the compile error "IWin32Window does not contain a definition for AssignHandle". I tried using the System.Windows.Interop version of IWin32Window but that doesn't have a NativeWindow() method. – Karl Hoaglund Dec 28 '17 at 15:27
  • @KarlHoaglund, thanks for catching this. `AssignHandle` is a method of NativeWindow and not IWin32Window. You would need to cast to NativeWindow or declare `win32Window` as a NativeWindow before the AssignHandle method is available . I'll update the answer – Tung Dec 28 '17 at 18:50
  • 1
    If we use Option2, do we need to call ReleaseHandle when we've finished? Do we need to 'clean up' in any way? – bornfromanegg Feb 12 '19 at 11:39
  • @bornfromanegg From the documentation, `To ensure proper garbage collection, handles must either be destroyed manually using DestroyHandle or released using ReleaseHandle.` – Tung Aug 08 '22 at 17:10