Opening a WinForm with TopMost=true but not having it steal focus?

匿名 (未验证) 提交于 2019-12-03 03:12:02

问题:

I have a form that pops up on a user's screen and has TopMost=true, but it steals the focus. How can I get it to not steal focus when it first appears?

回答1:

Paste this code in your form:

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


回答2:

This is what worked for me. It provides TopMost but without focus-stealing.

    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;        }     } 

Remember to omit setting TopMost in Visual Studio designer, or elsewhere.

This is stolen, err, borrowed, from here (click on Workarounds):

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



回答3:

You can do it like this:

    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         }     } 


回答4:

I tested the below code using a timer on form1 to instantiate and show form2 with form1 as owner.

In form2's Shown event I then set focus to the owner, which is the current active form.

I have a textbox on form1 and was able to continuesly write in the textbox without loosing focus during this process.

My timer code in form1:

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

My code in the Shown event of form2:

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

You can do this or simply set TopMost to false and use the override of ShowWithoutActivation as Hans Passant stated.

Edit: (Or use p/invoke as seen in Hans Passant's additional comment I missed while I wrote this)



回答5:

I came across the same problem. I'm not using C# but C++. I figure this could be useful anyways:

Using 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 ); 

Passing the flag SWP_NOACTIVATE to the uFlags argument worked for me.



回答6:

You can set:

this.TopMost = True; 

on Load event of that form.

It's OK with me!



回答7:

Instead of writing .setfocus()in _activated event; write it to .shown event of the form.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!