将焦点切换到另一个应用程序的正确方法(在 .NET 中)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2315561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Correct way (in .NET) to switch the focus to another application
提问by Jonathan Allen
This is what I have so far:
这是我到目前为止:
Dim bProcess = Process.GetProcessesByName("By").FirstOrDefault
If bProcess IsNot Nothing Then
SwitchToThisWindow(bProcess.MainWindowHandle, True)
Else
Process.Start("C:\Program Files\B\B.exe")
End If
It has two problems.
它有两个问题。
- Some people have told me that SwitchToThisWindow is depricated.
- If application B is minimized, this function silently fails from the user's perspective.
- 有人告诉我 SwitchToThisWindow 已被弃用。
- 如果应用程序 B 被最小化,从用户的角度来看,这个函数会默默地失败。
So what's the right way to do this?
那么这样做的正确方法是什么?
回答by caesay
Get the window handle (hwnd), and then use this user32.dll function:
获取窗口句柄(hwnd),然后使用这个 user32.dll 函数:
VB.net declaration:
VB.net声明:
Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Integer) As Integer
C# declaration:
C#声明:
[DllImport("user32.dll")] public static extern int SetForegroundWindow(int hwnd)
One consideration is that this will not work if the window is minimized, so I've written the following method which also handles this case. Here is the C# code, it should be fairly straight forward to migrate this to VB.
一个考虑是如果窗口被最小化,这将不起作用,所以我编写了以下方法来处理这种情况。这是 C# 代码,将其迁移到 VB 应该相当简单。
[System.Runtime.InteropServices.DllImport("user32.dll")]
[return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
private static extern bool ShowWindow(IntPtr hWnd, ShowWindowEnum flags);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SetForegroundWindow(IntPtr hwnd);
private enum ShowWindowEnum
{
Hide = 0,
ShowNormal = 1, ShowMinimized = 2, ShowMaximized = 3,
Maximize = 3, ShowNormalNoActivate = 4, Show = 5,
Minimize = 6, ShowMinNoActivate = 7, ShowNoActivate = 8,
Restore = 9, ShowDefault = 10, ForceMinimized = 11
};
public void BringMainWindowToFront(string processName)
{
// get the process
Process bProcess = Process.GetProcessesByName(processName).FirstOrDefault();
// check if the process is running
if (bProcess != null)
{
// check if the window is hidden / minimized
if (bProcess.MainWindowHandle == IntPtr.Zero)
{
// the window is hidden so try to restore it before setting focus.
ShowWindow(bProcess.Handle, ShowWindowEnum.Restore);
}
// set user the focus to the window
SetForegroundWindow(bProcess.MainWindowHandle);
}
else
{
// the process is not running, so start it
Process.Start(processName);
}
}
Using that code, it would be as simple as setting the appropriate process variables and calling BringMainWindowToFront("processName");
使用该代码,只需设置适当的流程变量并调用 BringMainWindowToFront("processName");
回答by Simon Mourier
There is another way, which uses the not well-known UI Automation API:
还有另一种方法,它使用了不知名的 UI 自动化 API:
AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
if (element != null)
{
element.SetFocus();
}
Most of the time, this will work if it's possible to switch to that window. There are a lot of limitations in Windows (security, UAC, specific configuration, etc...) that can prevent you to change the end-user focus.
大多数情况下,如果可以切换到该窗口,这将起作用。Windows 中有很多限制(安全性、UAC、特定配置等)可能会阻止您更改最终用户的关注点。
回答by Tijo Tom
Create a New Class in your project and copy-paste the below code in it.
在您的项目中创建一个新类并将以下代码复制粘贴到其中。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace MyProject
{
public class ProcessHelper
{
public static void SetFocusToExternalApp(string strProcessName)
{
Process[] arrProcesses = Process.GetProcessesByName(strProcessName);
if (arrProcesses.Length > 0)
{
IntPtr ipHwnd = arrProcesses[0].MainWindowHandle;
Thread.Sleep(100);
SetForegroundWindow(ipHwnd);
}
}
//API-declaration
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
}
Now copy-paste the below code in your required area.
现在将以下代码复制粘贴到您需要的区域。
string procName = Process.GetCurrentProcess().ProcessName;
ProcessHelper.SetFocusToExternalApp(procName);
Here you are calling the function to bring focus to the other application's window.
在这里,您正在调用该函数将焦点移至其他应用程序的窗口。
回答by Snake
In VB.Net, you can use the AppActivatefunction.
在 VB.Net 中,您可以使用AppActivate函数。
Dim App As Process() = Process.GetProcessesByName("program.exe")
If App.Length > 0 Then
AppActivate(App(0).Id)
End If
回答by Daniel N
I used SetForegroundWindow to make the window from another application appear.
我使用 SetForegroundWindow 来显示来自另一个应用程序的窗口。
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
回答by CrazyTim
Imports:
进口:
Imports System.Runtime.InteropServices
Put this in a Module
把它放在一个模块中
<DllImport("user32.dll")> _
Private Function SetForegroundWindow(hWnd As IntPtr) As Boolean
End Function
Public Sub FocusWindow(ByVal ProcessName As String)
Dim p As System.Diagnostics.Process = System.Diagnostics.Process.GetProcessesByName(ProcessName).FirstOrDefault
If p IsNot Nothing Then
SetForegroundWindow(p.MainWindowHandle)
SendKeys.SendWait("~") ' maximize the application if it's minimized
End If
End Sub
Usage:
用法:
FocusWindow("Notepad")
Source: http://www.codeproject.com/Tips/232649/Setting-Focus-on-an-External-application#_rating
来源:http: //www.codeproject.com/Tips/232649/Setting-Focus-on-an-External-application#_rating
回答by Kelin
This work for me
这对我有用
[DllImport("user32.dll", SetLastError = true)]
static extern void SwitchToThisWindow(IntPtr hWnd, bool turnOn);
[STAThread]
static void Main()
{
Process bProcess = Process.GetProcessesByName(processnamehere).FirstOrDefault() ;
if (bProcess != null)
{
SwitchToThisWindow(bProcess.MainWindowHandle, true);
}
GC.Collect();
}

