如何在Winforms中创建一个"弹出"(提示,下拉,弹出)窗口?

Ian*_*oyd 6 winapi popup popupwindow winforms

我如何制作,我将称之为"WinForms中的"弹出窗口"?


由于我使用了自己的单词"popup",让我举一个这个所谓的"弹出窗口"窗口的例子:

  • 一个提示窗口(可在其母体形式的边界之外延伸,不会出现在任务栏,不是模态,并且不偷焦点):

    在此输入图像描述

  • 一个弹出菜单窗口(可以扩展到其父窗体的边界之外,不会出现在任务栏中,不是模态的,也不会偷取焦点):

    在此输入图像描述

  • 一个下拉窗口(可以在其父窗体的边界之外延伸,不会出现在任务栏中,不是模态的,也不会偷取焦点):

    在此输入图像描述

  • 主菜单窗口(可在其母体形式的边界之外延伸,不会出现在任务栏,不是模态,并且不偷焦点):

    在此输入图像描述

  • 更新一个弹出窗口,不会让自己的"活动"窗口时,使用鼠标或键盘交互("所有者"窗口保持活动窗口):

在此输入图像描述

我在这个神秘的"弹出窗口"中寻找的属性是:

  • 可以扩展到其父表单的边界之外(即不是子窗口)
  • 没有出现在任务栏中(即窗口应该出现的窗口的启发式没有启动,也没有WS_EX_APPWINDOW扩展窗口样式)
  • 不是模态的(即不禁用其"所有者")
  • 没有窃取焦点
  • 总是它的"所有者" 的顶部
  • 在与(所有者保持活跃)交互时不会成为"活动"窗口

Windows应用程序已经设法创建这样的窗口.我怎么能在WinForms应用程序中执行此操作?

相关问题

  • 我如何在本机代码中实现上述所有功能?
  • 如何在Delphi中创建弹出窗口?
  • 我有这个本机代码来显示一个"弹出窗口"窗口 - 在.NET中执行相同的操作需要什么P/Invokes?
  • 我在.NET中有一组P/Invoke - 我可以重用常规的WinForm,覆盖某些方法,以达到同样的效果吗?
  • 我有WinForm,我通过覆盖某些方法显示为"弹出窗口" - 是否有内置Control可以作为我的弹出窗口?
  • 如何模拟WinForms中的下拉窗口?

尝试#1

我试过这个Show(onwer) + ShowWithoutActivation方法:

PopupForm dd = new PopupForm ();
dd.Show(this);
Run Code Online (Sandbox Code Playgroud)

使用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; } }
}
Run Code Online (Sandbox Code Playgroud)

几乎解决了这个问题,但后来我发现了"弹出"窗口的另一个属性:他们不会从他们的"所有者"表单中获取焦点,在与鼠标或键盘交互时变得活跃.

arx*_*arx 3

你想要一个拥有的窗口。在你的主窗体中:

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

PopupForm 应该是这样的:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并确保PopupForm.ShowInTaskbar = false.