C# 切换到上一个活动应用程序,如Alt Tab

C# 切换到上一个活动应用程序,如Alt Tab,c#,winforms,winforms-interop,alt-tab,C#,Winforms,Winforms Interop,Alt Tab,好的,我已经找到了很多关于按名称查找窗口等的帖子。我没有找到的是如何查找并将窗口应用程序焦点切换到最后一个活动窗口。下面显示的代码将提供任务管理器中处于活动状态的活动应用程序列表 我不知道怎么做的是找出最后一个活动应用程序是什么应用程序,然后切换到它。例如 我已打开自定义winform应用程序 我点击一个按钮 我的应用程序切换到最后一个活动窗口/应用程序 这是我到目前为止的工作代码。(这是按钮上的操作,它希望应用程序有一个名为textbox1的文本框。您还需要使用System.Diagnosti

好的,我已经找到了很多关于按名称查找窗口等的帖子。我没有找到的是如何查找并将窗口应用程序焦点切换到最后一个活动窗口。下面显示的代码将提供任务管理器中处于活动状态的活动应用程序列表

我不知道怎么做的是找出最后一个活动应用程序是什么应用程序,然后切换到它。例如

我已打开自定义winform应用程序

我点击一个按钮

我的应用程序切换到最后一个活动窗口/应用程序

这是我到目前为止的工作代码。(这是按钮上的操作,它希望应用程序有一个名为textbox1的文本框。您还需要使用System.Diagnostics添加

    private void button1_Click(object sender, EventArgs e)
    {

        Process[] procs = Process.GetProcesses();
        IntPtr hWnd;
        foreach (Process proc in procs)
        {
            if ((hWnd = proc.MainWindowHandle) != IntPtr.Zero)
            {
                textBox1.Text += (proc.ProcessName.ToString());
                textBox1.Text += "\t";
                textBox1.Text += (hWnd.ToString());
                textBox1.Text += "\r\n";
            }
        }         

    }
请查看这篇文章:

具体而言,该代码:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
enum GetWindow_Cmd : uint
{
    GW_HWNDFIRST = 0,
    GW_HWNDLAST = 1,
    GW_HWNDNEXT = 2,
    GW_HWNDPREV = 3,
    GW_OWNER = 4,
    GW_CHILD = 5,
    GW_ENABLEDPOPUP = 6
}
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

[...]

IntPtr targetHwnd = GetWindow(Process.GetCurrentProcess().MainWindowHandle, (uint)GetWindow_Cmd.GW_HWNDNEXT);
while (true)
{
    IntPtr temp = GetParent(targetHwnd);
    if (temp.Equals(IntPtr.Zero)) break;
    targetHwnd = temp;
}
SetForegroundWindow(targetHwnd);

由于我的评论对你没有帮助,这里有一份小简历(虽然没有测试):


我已经看过这个了。它对我不起作用。HWND在哪个类中?我似乎没有System.Windows.Interop我有System.Runtime.InteropServices,但它似乎不在这个类中。HWND来自Windows SDK,代表窗口的句柄。你的评论对你提供的信息没有帮助。我发布了这是一个问题,因为我已经走到了死胡同。不过我会研究Windows SDK。你不需要“研究Windows SDK”。你只需要一个更清晰的指南。你想做的事情在互联网上到处都有解释。你可能只是不懂行话。例如:谢谢你,Vulkanino,主要问题是我没有多次真正使用DLLImport,我不完全理解代码。我正在查看你添加的代码,如果我理解正确,我会使用它GetPreviousWindow返回上一个活动窗口的hwnd。但是如果我添加MessageBox.Show(GetPreviousWindow());对于按钮操作,它告诉我GetPreviousWindow需要一个hwnd的IntPtr。我认为这就是它为我找到的。对不起,我的错误,参数是无用的。我编辑我的答案以更正。好的,所以当我将此代码vulkanino放在按钮操作中使用时,它只返回句柄或为按钮所在的应用程序。(意味着它不调用上一个应用程序)是的,它给你上一个窗口的句柄,如果你想设置焦点,你必须显式调用setForeGroundIndow函数。编辑我的答案只是为了添加它。这正是我想做的。有趣的注意。这段代码在我的测试窗口窗体应用程序中工作,但当我把它放在小实用程序中时,我正在玩w它不会切换到上一个应用程序,而是切换到一个看起来只是一个过程的应用程序。
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("user32.dll")]
static extern IntPtr GetLastActivePopup(IntPtr hWnd);

[DllImport("user32.dll", ExactSpelling = true)]
static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

const uint GA_PARENT = 1;
const uint GA_ROOT = 2;
const uint GA_ROOTOWNER = 3;

public IntPtr GetPreviousWindow()
{
        IntPtr activeAppWindow = GetForegroundWindow();
        if ( activeAppWindow == IntPtr.Zero )
            return IntPtr.Zero;

        IntPtr prevAppWindow = GetLastActivePopup(activeAppWindow);
        return IsWindowVisible(prevAppWindow) ? prevAppWindow : IntPtr.Zero;
 }

 public void FocusToPreviousWindow()
 {
     IntPtr prevWindow = GetPreviousWindow();
     if (  prevWindow != IntPtr.Zero )
         SetForegroundWindow(prevWindow);
 }