How to set focus back to form after opening up a process (Notepad)?

前端 未结 5 1997
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-06 12:01

I open up a notepad from my program using Process.Start() but the new opened notepad covers the screen. But I do want my application to maintain its focus.

相关标签:
5条回答
  • 2020-12-06 12:19

    I had the same problem, i eventually wound up with programmatically calling alt-tab:

    [DllImport("user32.dll")]
    static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
    
    private void alttab()
    {
         uint WM_SYSCOMMAND = 0x0112;
         int SC_PREVWINDOW = 0xF050;            
    
         PostMessage(Process.GetCurrentProcess().MainWindowHandle, WM_SYSCOMMAND, SC_PREVWINDOW, 0);
    }
    

    //EDIT: You should use process.MainWindowHandle instead ofcourse

    0 讨论(0)
  • 2020-12-06 12:22

    I tried almost everything on internet (so sure about it :)). At best I could get my form on top of all other forms, but without focus (going by @Hans Passant's method). Going by heavy blocks of codes all over, I somehow felt this aint gonna be easy. So I always used SetForegroundWindow() with chunks of other code. Never thought merely SetForegroundWindow() would do the trick.

    This worked.

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    
    private void button1_Click(object sender, EventArgs e)
    { 
        Process process = new Process();
        process.StartInfo.FileName = @...\abc.log";
        process.Start();
    
        process.WaitForInputIdle(); //this is the key!!
    
        SetForegroundWindow(this.Handle);
    }
    

    At times this method yields in a focus on the parent form (in cases where my desired form is a modal child form of its parent form); in such cases, just add this.Focus() to the last line..

    Even this worked:

    Microsoft.VisualBasic.Interaction.Shell(@"notepad.exe D:\abc.log", 
                                            Microsoft.VisualBasic.AppWinStyle.NormalNoFocus);
    

    Solution provided by here

    0 讨论(0)
  • 2020-12-06 12:35

    If you want to start a process and focus back to the form, then start that process with minimized state, like this:

    Dim psi As New ProcessStartInfo("notepad")
    psi.WindowStyle = ProcessWindowStyle.Minimized
    Process.Start(psi)
    
    0 讨论(0)
  • 2020-12-06 12:40

    Windows prevents apps from shoving their window into the user's face, you are seeing this at work. The exact rules when an app may steal the focus are documented in the MSDN docs for AllowSetForegroundWindow().

    A back-door around this restriction is the AttachThreadInput() function. This code worked well, I did take a shortcut on finding the thread ID for the thread that owns the foreground window. Good enough for Notepad, possibly not for other apps. Do beware that Raymond Chen does not approve of this kind of hack.

        private void button1_Click(object sender, EventArgs e) {
            var prc = Process.Start("notepad.exe");
            prc.WaitForInputIdle();
            int tid = GetCurrentThreadId();
            int tidTo = prc.Threads[0].Id;
            if (!AttachThreadInput(tid, tidTo, true)) throw new Win32Exception();
            this.BringToFront();
            AttachThreadInput(tid, tidTo, false);
        }
    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool AttachThreadInput(int tid, int tidTo, bool attach);
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();
    
    0 讨论(0)
  • 2020-12-06 12:43

    Try this:

    public partial class MainForm : Form
    {
        private ShowForm showForm;
    
        public MainForm()
        {
            InitializeComponent();
        }
    
        private void showButton_Click(object sender, EventArgs e)
        {
            this.showForm = new ShowForm();
            this.showForm.FormClosed += showForm_FormClosed;
            this.showForm.Show(this);
        }
    
        private void showForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Focus();
        }
    }
    
    0 讨论(0)
提交回复
热议问题