1

I need to show a modeless dialog in .NET 1.1. The following code works in .NET 2.0 or higher:

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern IntPtr GetActiveWindow();

private void ShowModelessOwnedDialog()
{
   IntPtr wHnd = GetActiveWindow();
   NativeWindow parent = NativeWindow.FromHandle(wHnd);
   MyForm f = new MyForm();
   f.Show(parent);
}

The call Show(IWin32Window) was introduced in .NET 2.0. Do you know how to trick this code to work in .NET 1.1? Maybe any unmanaged call?

Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219

4 Answers4

2

Here is an article from way back in 1999, showing how you call SetWindowLong to accomplish this. My condolences to you for having to use .NET version 1.

Dave Markle
  • 95,573
  • 20
  • 147
  • 170
2

This is the way to assign an owner to a managed form in .NET 1.1. I extracted the following code from @Dave Markle answer and the Show(IWin32Window) implemantation of .NET 2.0.

    private void AssignOwner()
    {
        AssignOwner(this, GetActiveWindow());
    }

    private void AssignOwner(Form f, IntPtr ownerHandle)
    {
        if (ownerHandle == IntPtr.Zero) return;

        NativeWindow parent = NativeWindow.FromHandle(ownerHandle);

        GetWindowLong(new HandleRef(f, f.Handle), -8);
        SetWindowLong(new HandleRef(f, f.Handle), -8, new HandleRef(parent, ownerHandle));
    }

    public static IntPtr GetWindowLong(HandleRef hWnd, int nIndex)
    {
        if (IntPtr.Size == 4)
        {
            return GetWindowLong32(hWnd, nIndex);
        }
        return GetWindowLongPtr64(hWnd, nIndex);
    }

    public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, HandleRef dwNewLong)
    {
        if (IntPtr.Size == 4)
        {
            return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
        }
        return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    private static extern IntPtr GetActiveWindow();
    [DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
    public static extern IntPtr GetWindowLong32(HandleRef hWnd, int nIndex);
    [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)]
    public static extern IntPtr GetWindowLongPtr64(HandleRef hWnd, int nIndex);
    [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
    public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, HandleRef dwNewLong);
    [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
    public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, HandleRef dwNewLong);
Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219
1

MSDN states that after creating the window ownership cannot be transferred.
Because creating the window occurs in Form constructor, this poses a problem for you.

However Raymond Chen says:

Ownership is a concept that relates top-level windows. A top-level window can optionally have an owner, which is also specified when you call CreateWindowEx, and which you can change by a complicated mechanism described in my talk.

I assume the talk in question is from PDC 05 but I can't be certain.

Did you give SetParent a try?

static extern void SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • This is a simplified problem, the original, and the reason I need to show a modeless (but owned) dialog one is described here: http://stackoverflow.com/questions/7000532/close-child-dialogs-when-closing-the-parent – Daniel Peñalba Aug 10 '11 at 10:02
  • Would you try to put a bounty on it? This is in itself a very interesting question. – Dan Abramov Aug 10 '11 at 10:04
0

There is a MessageBox.Show overload taking and IWin32Window in .net 1.1

http://msdn.microsoft.com/en-us/library/aa335416(v=VS.71).aspx

public static DialogResult Show(
 IWin32Window owner,
 string text,
 string caption,
 MessageBoxButtons buttons,
 MessageBoxIcon icon,
 MessageBoxDefaultButton defaultButton
);

And this and example of getting an IWin2Window here

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216