打开进程(记事本)后如何将焦点设置回窗体?
我使用 Process.Start() 从程序中打开记事本,但新打开的记事本覆盖了屏幕。但我确实希望我的应用程序能够保持其焦点。
我类似地(使用相同的 Process.Start)打开 MS Excel 和 Word,但为了将焦点返回到我的表单,我需要写的是:
this.Focus();
但是记事本的怪癖:我打开记事本(以及所有其他类似的进程)
Process process = new Process();
process.StartInfo.UseShellExecute = true;
process.EnableRaisingEvents = true;
process.StartInfo.FileName = @"abc.log";
process.Start();
现在记事本需要焦点。
我尝试了这些:
this.Activate()
、this.Focus()
,不用提[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] 公共静态 extern IntPtr SetFocus(HandleRef hWnd); { IntPtr hWnd = myProcess.Handle; SetFocus(new HandleRef(null, hWnd)); }
[DllImport("User32")] 私有静态 extern int SetForegroundWindow(IntPtr hwnd); [DllImportAttribute(“User32.DLL”)] 私有静态 extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 私有常量 int SW_SHOW = 5; 私有常量 int SW_MINIMIZE = 6; 私有常量 int SW_RESTORE = 9; { ShowWindow(Process.GetCurrentProcess().MainWindowHandle, SW_RESTORE); SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle); }
从此处获得另一个更长的解决方案。
所有这些仍然将焦点放在记事本上。为什么仅仅将焦点集中到一个窗口(也是应用程序自己的窗口)如此困难?
编辑:我最多可以最小化地打开记事本,但在尝试了上述所有代码后,它仍然不会将焦点放在表单上。记事本以最小化方式打开,但焦点仍位于记事本上(有时我们在 Windows XP 中会看到这种情况),并且窗体将失去焦点。
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.
I similarly (using the same Process.Start) open up MS Excel and Word but to get focus back to my form all I need to write is:
this.Focus();
But quirk with Notepad: I open 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 notepad takes the focus.
I tried these:
this.Activate()
,this.Focus()
, needless to mention[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 lengthier solution got from here.
All which still keeps the focus on notepad. Why is it so difficult to merely get focus to a window, that too application's own window?
EDIT: At best I can open the notepad minimized, but it still wouldn't give the focus to the form after trying all the above codes. Notepad opens minimized, but focus will be still on notepad (something that sometimes we see in windows xp) and form will be out of focused.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我几乎尝试了互联网上的所有内容(所以确定:))。最好的情况是我可以将我的表单放在所有其他表单之上,但没有焦点(采用@Hans Passant 的方法)。经过大量的代码块,我不知何故觉得这并不容易。所以我总是将
SetForegroundWindow()
与其他代码块一起使用。从来没想过仅仅SetForegroundWindow()
就能解决这个问题。这有效。
有时,此方法会集中于父表单(如果我所需的表单是其父表单的模态子表单);在这种情况下,只需将
this.Focus()
添加到最后一行。即使这样也有效:
这里
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 merelySetForegroundWindow()
would do the trick.This worked.
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:
Solution provided by here
我遇到了同样的问题,我最终以编程方式调用 alt-tab:
//编辑:你应该使用 process.MainWindowHandle 而不是
I had the same problem, i eventually wound up with programmatically calling alt-tab:
//EDIT: You should use process.MainWindowHandle instead ofcourse
如果您想启动一个流程并将焦点返回到表单,请以最小化状态启动该流程,如下所示:
If you want to start a process and focus back to the form, then start that process with minimized state, like this:
Windows 会阻止应用程序将窗口推到用户的脸上,您会在工作中看到这一点。应用程序可能窃取焦点的确切规则记录在AllowSetForegroundWindow() 的MSDN 文档中。
围绕此限制的一个后门是 AttachThreadInput() 函数。这段代码运行良好,我确实采取了捷径来查找拥有前台窗口的线程的线程 ID。对于记事本来说足够好,但可能不适合其他应用程序。请注意,Raymond Chen不赞同这种黑客行为。
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.
试试这个:
Try this: