【问题标题】:How to position a form on top of another form without taking the focus如何在不获取焦点的情况下将表单放置在另一个表单之上
【发布时间】:2011-05-23 19:58:23
【问题描述】:

当满足某些条件时(我的应用知道),我的应用需要在任何活动应用的光标位置附近显示一个弹出窗口。

所以我想显示表单(不从活动应用程序中窃取焦点)。我尝试使用带有 SW_SHOWNOACTIVATE 参数的 ShowWindow,但是这样,我的表单会显示在当前活动的表单下。

如何强制我的表单显示在屏幕上任何活动表单的顶部而不窃取输入焦点?

谢谢。

【问题讨论】:

标签: c# winforms


【解决方案1】:

您想要的是使用您想要保持在顶部的表单的TopMost 属性。

【讨论】:

    【解决方案2】:

    您需要在弹出表单中添加一些管道,以便您可以覆盖 WM_ACTIVATE 消息:

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_ACTIVATE)
            {
                if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
                {
                    if (m.LParam != IntPtr.Zero)
                    {
                        SetActiveWindow(m.LParam);
                    }
                    else
                    {
                        // Could not find sender, just in-activate it.
                        SetActiveWindow(IntPtr.Zero);
                    }
                }
            }
    
            base.WndProc(ref m);
        } 
    

    确保您也将以下内容添加到弹出表单中:

        [DllImport("user32.dll")]
        private extern static IntPtr SetActiveWindow(IntPtr handle);
        private const int WM_ACTIVATE = 6;
        private const int WA_INACTIVE = 0;
    

    您可以像使用其他任何方式一样使用弹出式表单,方法是在其上调用 Show()。与其他窗体一样,您可以通过 TopMost 属性使其成为最顶层的窗口。

    【讨论】:

    • 我尝试了另一种方法。执行 showWindow(NO_ACTIVATE) 然后调用 SetWindowPosition API,它看起来工作正常(但我必须将进程附加到活动应用程序的输入)。我尚未测试您的代码,但您的方法会在活动窗口中创建任何闪烁吗?
    • 我将它用于 Outlook 样式的弹出窗口(例如新邮件到达时)。没有闪烁。我的弹出窗口出现,并在一段时间后淡出,我用 lots 的弹出窗口对其进行了测试,没有视觉干扰。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多