代码之家  ›  专栏  ›  技术社区  ›  Phil Hannent

如何跟踪应用程序的z顺序/焦点?

  •  0
  • Phil Hannent  · 技术社区  · 16 年前

    我想谈谈在我的应用程序之前使用的应用程序,我怎样才能找出哪一个应用程序最后使用了focus?

    2 回复  |  直到 16 年前
        1
  •  1
  •   sth    16 年前

    我正在寻找相同的-我有一个应用程序,保持在屏幕上打开,用户可以调用我的应用程序按钮,一旦他们进入三个第三方应用程序之一。

    当他们单击我的应用程序上的按钮时,我需要确定他们最后使用的三个应用程序中的哪一个,以便知道与哪个数据库对话。我一直在关注GetForeGroundWindow和GetWindow,但是我从GetWindow获得的窗口句柄总是指一个标题为M的窗口。我使用了托管Windows API工具中的Winternal Explorer工具,我可以找到返回的M句柄,它是我所追求的进程的“子进程”——但从这个角度来看我无法获取进程名称。

    我用简单的windows窗体制作了一个小的示例应用程序-我启动它,然后将记事本作为焦点,然后单击我的按钮,我得到了句柄-但是当查看所有进程的MainWindowHandle时,它没有列出,但使用Winternal资源管理器,我可以看到这是记事本进程的一个子进程。

    关于为什么只返回此子进程句柄而不是实际进程句柄,有什么建议吗??

    示例代码如下-在Windows XP sp 3计算机上运行

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace TestWindowsAPI
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll")]
            public static extern IntPtr GetForegroundWindow();
    
            [DllImport("user32.dll", SetLastError = true)]
            static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                IntPtr thisWindow = GetForegroundWindow();
                IntPtr lastWindow = GetWindow(thisWindow, 2);
    
                tbThisWindow.Text = thisWindow.ToString();
                tbLastWindow.Text = lastWindow.ToString();
            }
        }
    }
    
        2
  •  0
  •   Chris Becke    16 年前

    在创建自己的应用程序窗口之前,请调用GetForeGroundIndow。 否则,请调用GetWindow(your_hwnd,GW_HWNDNEXT)以查找指定窗口下方的下一个窗口。

        3
  •  0
  •   Sergio Cabral    6 年前

    没有现成的方法可以按Z顺序获取Windows上打开的应用程序列表。

    下面的代码在中实现了这一点 GetWindowsInOrder Process.GetCurrentProcess().MainWindowHandle

    这个 词典 窗把手 窗口名 作为它的价值。

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    
    public static class WindowsApi
    {
        public static Dictionary<IntPtr, string> GetWindowsInOrder()
        {
            return Process
                .GetProcesses()
                .Where(process => process.MainWindowHandle != IntPtr.Zero)
                .Select(process => process.MainWindowHandle)
                .OrderBy(GetWindowZOrder)
                .ToDictionary(hWnd => hWnd, GetWindowText);
        }
    
        public static int GetWindowZOrder(IntPtr hWnd)
        {
            var zOrder = -1;
            while ((hWnd = GetWindow(hWnd, 2 /* GW_HWNDNEXT */)) != IntPtr.Zero) zOrder++;
            return zOrder;
        }
    
        public static string GetWindowText(IntPtr hWnd)
        {
            var text = new StringBuilder(255);
            GetWindowText(hWnd, text, text.Capacity);
            return text.ToString();
        }
    
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
    
        [DllImport("user32.dll", CharSet = CharSet.None, SetLastError = true)]
        static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    }