How to adjust focus to a form after opening a process (Notepad)?

I open the notebook from my program using Process.Start() , but a new open notebook closes the screen. But I want my application to be in the spotlight.

I also (using the same Process.Start) open MS Excel and Word, but in order to return focus to my form, I need to write the following:

 this.Focus(); 

But the quirk with Notepad: I open the notepad (and all other processes like this)

 Process process = new Process(); process.StartInfo.UseShellExecute = true; process.EnableRaisingEvents = true; process.StartInfo.FileName = @"abc.log"; process.Start(); 

Now the notebook focuses.

I tried:

  • this.Activate() , this.Focus() , optional

  •  [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] public static extern IntPtr SetFocus(HandleRef hWnd); { IntPtr hWnd = myProcess.Handle; SetFocus(new HandleRef(null, hWnd)); } 
  •  [DllImport("User32")] private static extern int SetForegroundWindow(IntPtr hwnd); [DllImportAttribute("User32.DLL")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); private const int SW_SHOW = 5; private const int SW_MINIMIZE = 6; private const int SW_RESTORE = 9; { ShowWindow(Process.GetCurrentProcess().MainWindowHandle, SW_RESTORE); SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle); } 
  • Another longer solution is obtained from here .

Everything is still focused on notepad. Why is it so difficult to just focus on the window, is this also the applicationโ€™s own window?

EDIT: At best, I can open a notebook that was minimized, but it still didn't give focus to the form after trying all of the above codes. The notebook opens with minimal values, but the focus will still remain in the notebook (something that we sometimes see in xp windows), and the shape will not be focused.

+6
source share
4 answers

I tried almost everything on the Internet (so sure of that :)). In the best case, I could get my form on top of all the other forms, but without focus (using the @Hans Passant method). Walking through the heavy blocks of codes throughout, for some reason I felt that it was not easy. Therefore, I always used SetForegroundWindow() with pieces of other code. I never thought that just SetForegroundWindow() would do the trick.

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

Sometimes this method gives focus to 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); 

The solution provided here

+9
source

I had the same problem, I ended up with the alt-tab programmatic call:

 [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 of thecourse

+2
source

Windows prevents applications from dragging their window into the user's face, you see this at work. The exact rules when an application can steal focus are documented in MSDN docs for AllowSetForegroundWindow ().

The back element of this restriction is the AttachThreadInput () function. This code worked well, I found a shortcut to find the thread id for the thread that owns the foreground window. Good enough for Notepad, perhaps not for other applications. Beware that Raymond Chen does not approve of such a 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(); 
+1
source

Try the following:

 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(); } } 
-1
source

Source: https://habr.com/ru/post/906101/


All Articles