【问题标题】:How to focus on last activated program?如何专注于上次激活的程序?
【发布时间】:2012-11-19 13:04:15
【问题描述】:

如果您正在制作windows窗体应用程序并且您打开了“记事本”和“网络浏览器”,如何在您的应用程序获得焦点之前将焦点分配给最后一个获得焦点的应用程序?

【问题讨论】:

    标签: .net windows vb.net winforms focus


    【解决方案1】:

    您可以使用回调函数和一组 API 来查找 Alt-Tab 可以看到的程序列表(打开的窗口)(不查看 Alt-Tab 窗口)。

    首先声明要使用的API集合:

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
    
    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWindowVisible(IntPtr hWnd);
    
    [DllImport("user32.dll")]
    private static extern int EnumWindows(CallBackPtr callPtr, int lPar);
    
    [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    public static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder         lParam);
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wparam, int lparam);
    
    const int WM_GETTEXT = 0xD;
    
    private static int windowCount = 0;
    

    那你需要通过windows枚举并激活最后一个:

    public static bool EnumWindowProc(int hwnd, int lParam)
    {
        if (!IsWindowVisible((IntPtr)hwnd) || GetWindow((IntPtr)hwnd, GW_OWNER) != IntPtr.Zero)
        return true;
    
        string name = GetWindowTextRaw((IntPtr)hwnd);
        if (name.Length > 0)
        {
            windowCount++;
            if (windowCount == 2) //The previouse active window
            {
                SetForegroundWindow((IntPtr)hwnd);
                return false;
            }
        }
    
    
        return true;
    }
    

    并使用以下代码检索窗口名称。

    public static string GetWindowTextRaw(IntPtr hwnd)
    {
        var length = (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
        var sb = new StringBuilder(length + 1);
        SendMessage(hwnd, WM_GETTEXT, sb.Capacity, sb);
        return sb.ToString();
    }
    

    最后调用以下函数:

    public void ActivateLastWindow()
    {
        callBackPtr = EnumWindowProc;
        windowCount = 0;
        EnumWindows(callBackPtr, 0);
    }
    

    【讨论】:

    • 您可以通过在程序开始时调用 GetForegroundWindow() 来简化此操作。
    • 这种方式比较通用,可以在程序启动后使用,在窗体上按一个按钮等。程序的开始不再适用。
    • @Thunder-KC inc 感谢您的快速回答,我是 User32.dll 的新手,所以我需要时间来使用您的“代码”。
    • @Hans Passant Passant , GetForegroundWindow() 是否返回另一个应用程序的窗口?
    【解决方案2】:

    按 Alt+Tab 总是会让您回到之前的活动窗口。它是单行代码:

        SendKeys.Send("%{TAB}")
    

    【讨论】:

    • 请注意,如果您在引用中包含 System.Windows.Forms,这将适用于 WPF。
    猜你喜欢
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多