Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a "popup" (hint, drop-down, popup) window in Winforms?

How can i make, what i will call, a "popup" window" in WinForms?


Since i used my own made-up word "popup", let me give examples of this so-called "popup" window:

  • a tooltip window (can extend outside the boundaries of its parent form, doesn't appear in the taskbar, is not modal, and doesn't steal focus):

    enter image description here

  • a popup menu window (can extend outside the boundaries of its parent form, doesn't appear in the taskbar, is not modal, and doesn't steal focus):

    enter image description here

  • a drop-down window (can extend outside the boundaries of its parent form, doesn't appear in the taskbar, is not modal, and doesn't steal focus):

    enter image description here

  • A main menu window (can extend outside the boundaries of its parent form, doesn't appear in the taskbar, is not modal, and doesn't steal focus):

    enter image description here

  • Update A popup window not make itself the "active" window when interacted with using a mouse or keyboard (the "owner" window remains the active window):

enter image description here

The attributes that i'm looking for in this mythical "popup" are that it:

  • can extend outside the boundaries of its parent form (i.e. is not a child window)
  • doesn't appear in the taskbar (i.e. Window's heuristics of which windows should appear doesn't kick in, nor does it have WS_EX_APPWINDOW extended window style)
  • is not modal (i.e. doesn't disable its "owner")
  • doesn't steal focus
  • is always on-top of of it's "owner"
  • does not become the "active" window when interacted with (the owner remains active)

Windows applications are already managing to create such windows. How can i do it in a WinForms application?

Related questions

  • How do i achieve all the above in native code?
  • How do i create a popup window in Delphi?
  • i have this native code to show a "popup" window - what P/Invokes are required to perform the same actions in .NET?
  • i have a set of P/Invoke's in .NET - can i reuse a regular WinForm, overriding certain methods, to achieve the same effect?
  • i have WinForm that i'm showing as a "popup" by overriding certain methods - is there a built-in Control that can act as a popup for me?
  • How to simulate a drop-down window in WinForms?

Attempt#1

i tried the Show(onwer) + ShowWithoutActivation method:

PopupForm dd = new PopupForm ();
dd.Show(this);

with PopupForm:

public class PopupForm: Form
{
    public PopupForm()
    {
        InitilizeComponent();
    }

    private void InitilizeComponent()
    {
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        this.WindowState = FormWindowState.Normal;
        this.ShowInTaskbar = false;
    }

    protected override bool ShowWithoutActivation
    { get { return true; } }
}

Very nearly solved the problem, but then i discovered was reminded of another property of "popup" windows: they do not take focus from their "owner" form become active when interacted with by mouse or keyboard.

like image 353
Ian Boyd Avatar asked Dec 29 '11 14:12

Ian Boyd


1 Answers

You want an owned window. In your main form:

private void showPopup_Click(object sender, EventArgs e)
{
    PopupForm popupForm = new PopupForm();
    // Make "this" the owner of form2
    popupForm.Show(this);
}

PopupForm should look like this:

public partial class PopupForm : Form
{
    private bool _activating = false;

    public PopupForm()
    {
        InitializeComponent();
    }

    // Ensure the popup isn't activated when it is first shown
    protected override bool ShowWithoutActivation
    {
        get
        {
            return true;
        }
    }

    private const int WM_NCACTIVATE = 0x86;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    protected override void WndProc(ref Message m)
    {
        // The popup needs to be activated for the user to interact with it,
        // but we want to keep the owner window's appearance the same.
        if ((m.Msg == WM_NCACTIVATE) && !_activating && (m.WParam != IntPtr.Zero))
        {
            // The popup is being activated, ensure parent keeps activated appearance
            _activating = true;
            SendMessage(this.Owner.Handle, WM_NCACTIVATE, (IntPtr) 1, IntPtr.Zero);
            _activating = false;
            // Call base.WndProc here if you want the appearance of the popup to change
        }
        else
        {
            base.WndProc(ref m);
        }
    }
}

And make sure that PopupForm.ShowInTaskbar = false.

like image 184
arx Avatar answered Oct 11 '22 05:10

arx