簡體   English   中英

如何跟蹤應用程序的 z 順序/焦點?

[英]How do I track the application z-order/focus?

我想與在我的應用程序之前使用的應用程序交談,我如何才能找出最后一個焦點是哪個應用程序?

我正在尋找相同的 - 我有一個在屏幕上保持打開狀態的應用程序,一旦用戶進入三個 3rd 方應用程序之一,他們就可以調用我的應用程序上的按鈕。

當他們單擊我的應用程序上的按鈕時,我需要確定他們最后使用的三個應用程序中的哪一個,以便知道要與哪個數據庫對話。 我已經沿着查看 GetForeGroundWindow 和 GetWindow 的路線走了下去,但是我從 GetWindow 獲得的窗口句柄總是指標題為 M 的窗口。我使用了托管 Windows API 工具中的 Winternal Explorer 工具,我可以找到 M 句柄返回,它是我所追求的進程的“子進程” - 但是從這個句柄我無法獲得進程名稱。

我已經使用簡單的 Windows 窗體完成了一個小示例應用程序 - 我啟動它,然后將記事本設為焦點,然后單擊我的按鈕並獲得句柄 - 但是當查看所有進程的 MainWindowHandle 時,它​​沒有列出,但使用 Winternal Explorer 我可以看到這是記事本進程的子進程。

關於為什么我只返回這個子進程句柄而不是實際進程句柄的任何建議?

示例代碼如下 - 在 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();
        }
    }
}

在創建您自己的應用程序窗口之前,請調用 GetForegroundWindow。 否則調用 GetWindow(your_hwnd,GW_HWNDNEXT) 來查找指定窗口下方的下一個窗口。

沒有現成的方法可以在 Windows 上按 Z-Order 排序打開應用程序列表。

下面的代碼在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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM