【问题标题】:Opening a WinForms Form with TopMost = true but not having it steal focus?使用 TopMost = true 打开 WinForms 表单但不让它窃取焦点?
【发布时间】:2010-09-16 19:09:30
【问题描述】:

我有一个在用户屏幕上弹出的表单,并且有TopMost=true,但它窃取了焦点。我怎样才能让它在第一次出现时窃取焦点?

【问题讨论】:

  • +1:我讨厌窃取焦点的窗口!
  • 如果可能的话,我敢打赌 Raymond Chen 写过:blogs.msdn.com/b/oldnewthing
  • 我很惊讶这不仅仅是 WinForms 内置的东西......

标签: c# winforms topmost


【解决方案1】:

这对我有用。它提供 TopMost 但没有窃取焦点。

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

    private const int WS_EX_TOPMOST = 0x00000008;
    protected override CreateParams CreateParams
    {
       get
       {
          CreateParams createParams = base.CreateParams;
          createParams.ExStyle |= WS_EX_TOPMOST;
          return createParams;
       }
    }

记得在 Visual Studio 设计器或其他地方省略设置 TopMost。

这是从这里被盗、出错、借来的(点击解决方法):

https://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost

【讨论】:

  • 这个链接也失效了
  • @FactorMystic 嗯,迟到了,但Archive.org link
【解决方案2】:

将此代码粘贴到您的表单中:

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

【讨论】:

  • 当 TopMost 设置为 True 时,它​​在 VS2008 中不起作用。我现在在 VS2010 上试试。
  • 在 VS 2010 中仍然不起作用。仅当弹出表单上的 TopMost 设置为 false 时才起作用。
  • 天哪,这是真的,TopMost 搞砸了。在 VS2010 中也不起作用。您必须使用 HWND_TOPMOST 和 SWP_NOACTIVATE P/Invoke SetWindowPos()。使用 pinvoke.net 进行声明。
  • @Soo:不知道你是如何让它工作的,因为它是一个众所周知的错误。 @Hans:+1 评论添加提及 P/Invoke 以解决该问题。
【解决方案3】:

你可以设置:

this.TopMost = True;

关于该表单的加载事件。

我没关系!

【讨论】:

  • 别忘了先在 IDE 上禁用 .topmost - 就像一个魅力
【解决方案4】:

你可以这样做:

    private const int SW_SHOWNOACTIVATE = 4;
    private const int HWND_TOPMOST = -1;
    private const uint SWP_NOACTIVATE = 0x0010;

    [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    private static extern bool SetWindowPos(
         int hWnd,             // Window handle
         int hWndInsertAfter,  // Placement-order handle
         int X,                // Horizontal position
         int Y,                // Vertical position
         int cx,               // Width
         int cy,               // Height
         uint uFlags);         // Window positioning flags

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);

    public static void ShowInactiveTopmost(System.Windows.Forms.Form frm)
    {
        try
        {
            ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
            SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
            frm.Left, frm.Top, frm.Width, frm.Height,
            SWP_NOACTIVATE);
        }
        catch (System.Exception ex)
        {
            // error handling
        }
    }

【讨论】:

    【解决方案5】:

    我使用 form1 上的计时器对以下代码进行了测试,以实例化并显示 form2,其中 form1 为所有者。

    在 form2 的 Shown 事件中,我将焦点设置为所有者,即当前活动的表单。

    我在 form1 上有一个文本框,并且能够在此过程中继续在文本框中书写而不会失去焦点。

    form1 中的计时器代码:

    private void timer1_Tick(object sender, EventArgs e)
    {
        Form2 popup = new Form2();
        popup.TopMost = true;
        popup.Show(this);
        timer1.Enabled = false;
    }
    

    我在form2的Shown事件中的代码:

    private void Form2_Shown(object sender, EventArgs e)
    {
        this.Owner.Focus();
    }
    

    您可以执行此操作,也可以简单地将 TopMost 设置为 false,并按照 Hans Passant 的说明使用 ShowWithoutActivation 的覆盖。

    编辑:(或使用 p/invoke,如我在写这篇文章时错过的 Hans Passant 的附加评论中所见)

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题。我使用的不是 C#,而是 C++。我认为这无论如何都是有用的:

      使用 windows.h:

      BOOL WINAPI SetWindowPos(
        __in      HWND hWnd,
        __in_opt  HWND hWndInsertAfter,
        __in      int X,
        __in      int Y,
        __in      int cx,
        __in      int cy,
        __in      UINT uFlags
      );
      

      将标志 SWP_NOACTIVATE 传递给 uFlags 参数对我有用。

      【讨论】:

        【解决方案7】:

        而不是在_activated事件中写.setfocus();将其写入表单的.shown 事件。

        【讨论】:

          猜你喜欢
          • 2023-04-02
          • 2020-10-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-13
          • 1970-01-01
          相关资源
          最近更新 更多