如何将一个窗体置于另一个窗体之上,但不占用焦点(避免窗体闪烁)?涉及IT技术。

4
我的应用程序需要在满足某些条件(由我的应用程序知道)时,在光标位置附近显示弹出窗口。
因此,我想显示表单(而不从活动应用程序中窃取焦点)。我尝试使用带有SW_SHOWNOACTIVATE参数的ShowWindow,但是这样,我的表单会显示在当前活动表单下面。
如何强制我的表单显示在屏幕上任何活动表单的顶部,而不会窃取输入焦点?
谢谢。

可能是在C#中显示一个不会窃取焦点的窗体的方法的重复问题。 - Hans Passant
2个回答

1
你想要的是使用所需保持在顶部的窗体的TopMost属性。

0

你需要在弹出窗口表单中添加一些管道,以便你可以覆盖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,看起来效果不错(但是我必须将进程附加到活动应用程序的输入上)。我还没有测试过你的代码,但是你的方法会在活动窗口中产生闪烁吗? - Andrea Nagar
我使用它来创建类似Outlook弹出窗口的效果(例如新邮件到达时)。没有闪烁。我的弹出窗口会出现,并在一段时间后淡出,我已经测试了很多弹出窗口而没有出现视觉干扰。 - Edwin Groenendaal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接