20

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

4

7 回答 7

15

这对我有用。它提供 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

于 2014-08-09T14:11:05.630 回答
6

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

protected override bool ShowWithoutActivation
{
    get { return true; }
}
于 2010-09-16T19:31:22.703 回答
2

您可以设置:

this.TopMost = True;

在该表单的加载事件上。

我没关系!

于 2014-04-11T08:50:09.850 回答
2

你可以这样做:

    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
        }
    }
于 2014-04-11T09:04:01.627 回答
1

我使用 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 并使用 ShowWithoutActivation 的覆盖,如 Hans Passant 所述。

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

于 2010-09-16T20:04:02.233 回答
1

我遇到了同样的问题。我使用的不是 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 参数对我有用。

于 2012-05-10T03:24:19.123 回答
0

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

于 2016-01-25T10:57:42.067 回答