【问题标题】:Switch to last active application like Alt-Tab切换到上次活动的应用程序,例如 Alt-Tab
【发布时间】:2012-02-27 16:27:36
【问题描述】:

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

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

我打开了我的自定义 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";
            }
        }         

    }

【问题讨论】:

  • 我已经看过这个了。它对我不起作用。 HWND 在哪个班级?我好像没有 System.Windows.Interop 我有 System.Runtime.InteropServices 但是好像没有这个类。
  • HWND 来自 Windows SDK,代表一个窗口的句柄。
  • 您的 cmets 无法帮助我处理您提供的信息。我发布了这个问题,因为我遇到了死胡同。不过我会研究 Windows SDK。
  • 您不需要“查看 Windows SDK”。你只需要一个更清晰的指南。你想做什么在互联网上都有解释。你可能只是不懂行话。例如:stackoverflow.com/questions/6434475/…

标签: c# winforms winforms-interop alt-tab


【解决方案1】:

查看这篇文章:http://www.whitebyte.info/programming/how-to-get-main-window-handle-of-the-last-active-window

具体来说,这段代码:

[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);

【讨论】:

  • 这正是我想要做的。
  • 有趣的笔记。这段代码在我的测试窗口窗体应用程序中工作,但是当我把它放在我正在玩的小实用程序中时,它不会切换到以前的应用程序。它切换到一个看起来只是一个进程的应用程序。
【解决方案2】:

由于我的cmets没有帮助你,这里有一个小简历(虽然没有测试过):

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

【讨论】:

  • 谢谢 Vulkanino,主要问题是我没有真正使用过 DLLImport 很多次,而且我不完全理解代码。我正在查看您添加的代码,如果我理解正确,我将使用 GetPreviousWindow 返回最后一个活动窗口的 hwnd。但是当我添加 MessageBox.Show(GetPreviousWindow());到一个按钮操作它告诉我GetPreviousWindow 需要一个hwnd 的IntPtr。我认为这就是它为我找到的。
  • 对不起,我的错,参数没用。我编辑我的答案以更正。
  • 好的,所以当我通过将方法放在按钮操作中使用此代码 vulkanino 时,它只返回句柄或按钮所在的应用程序调用的任何内容。 (意味着它不会调用之前的应用程序)
  • 是的,它给你上一个窗口的句柄,如果你想设置焦点到它,你必须显式调用 SetForegroundWindow 函数。编辑我的答案只是为了添加。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-26
  • 2014-06-17
  • 2021-03-11
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多