简体   繁体   中英

How to show modeless owned dialog in .NET 1.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?

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.

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);

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);

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM