Открытие формы WinForms с TopMost = true, но без фокуса? - PullRequest
18 голосов
/ 16 сентября 2010

У меня есть форма, которая появляется на экране пользователя и имеет TopMost=true, но она крадет фокус.Как я могу получить , а не украсть фокус при первом появлении?

Ответы [ 7 ]

14 голосов
/ 09 августа 2014

Вот что у меня сработало.Он обеспечивает 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;
       }
    }

Не забудьте пропустить настройку TopMost в конструкторе Visual Studio или в другом месте.

Это украдено, ошибочно, заимствовано отсюда (нажмите на обходные пути):

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

6 голосов
/ 16 сентября 2010

Вставьте этот код в вашу форму:

protected override bool ShowWithoutActivation
{
    get { return true; }
}
2 голосов
/ 11 апреля 2014

Вы можете сделать это так:

    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
        }
    }
1 голос
/ 11 апреля 2014

Вы можете установить:

this.TopMost = True;

при событии загрузки этой формы.

Со мной все в порядке!

1 голос
/ 10 мая 2012

Я столкнулся с той же проблемой. Я не использую 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 сработала для меня.

1 голос
/ 17 сентября 2010

Я протестировал приведенный ниже код, используя таймер в форме form1, чтобы создать экземпляр и показать form2 с form1 в качестве владельца.

В событии Shown формы 2 я затем установил фокус на владельца, который является текущей активной формой.

У меня есть текстовое поле в форме form1, и я смог непрерывно писать в текстовом поле, не теряя фокус во время этого процесса.

Мой код таймера в форме 1:

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

Мой код в показанном событии формы 2:

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

Вы можете сделать это или просто установить TopMost в значение false и использовать переопределение ShowWithoutActivation, как указано Гансом Пассантом.

Редактировать: (Или использовать p / invoke, как видно из дополнительного комментария Ганса Пассанта, который я пропустил, когда писал это)

0 голосов
/ 25 января 2016

Вместо записи .setfocus() в _activated событие;запишите это .shown событие формы.

...