Question

Je crée une application dans laquelle j'interagis avec chaque application en cours d'exécution. À l'heure actuelle, j'ai besoin d'un moyen d'obtenir l'ordre z de la fenêtre. Par exemple, si Firefox et le bloc-notes sont en cours d’exécution, j’ai besoin de savoir lequel se trouve devant.

Des idées? En plus de faire cela pour la fenêtre principale de chaque application, je dois également le faire pour ses fenêtres enfants et soeurs (fenêtres appartenant au même processus).

Était-ce utile?

La solution

Vous pouvez utiliser la fonction GetTopWindow pour effectuer une recherche dans toutes les fenêtres enfants d'une fenêtre parent et renvoyer un descripteur à la fenêtre enfant la plus haute dans l'ordre z. La fonction GetNextWindow récupère un handle vers la fenêtre suivante ou précédente dans l'ordre z.

GetTopWindow: http://msdn.microsoft.com /en-us/library/ms633514(VS.85).aspx
GetNextWindow: http://msdn.microsoft.com/fr us / library / ms633509 (VS.85) .aspx

Autres conseils

Sympa et laconique:

int GetZOrder(IntPtr hWnd)
{
    var z = 0;
    for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++;
    return z;
}

Si vous avez besoin de plus de fiabilité:

/// <summary>
/// Gets the z-order for one or more windows atomically with respect to each other. In Windows, smaller z-order is higher. If the window is not top level, the z order is returned as -1. 
/// </summary>
int[] GetZOrder(params IntPtr[] hWnds)
{
    var z = new int[hWnds.Length];
    for (var i = 0; i < hWnds.Length; i++) z[i] = -1;

    var index = 0;
    var numRemaining = hWnds.Length;
    EnumWindows((wnd, param) =>
    {
        var searchIndex = Array.IndexOf(hWnds, wnd);
        if (searchIndex != -1)
        {
            z[searchIndex] = index;
            numRemaining--;
            if (numRemaining == 0) return false;
        }
        index++;
        return true;
    }, IntPtr.Zero);

    return z;
}

(Selon la section Remarques sur GetWindow , EnumChildWindows est plus sûr que d'appeler GetWindow dans une boucle, car votre boucle GetWindow n'est pas atomique par rapport aux modifications externes. dans la section Paramètres pour EnumChildWindows , appeler avec un parent nul équivaut à EnumWindows .)

Ensuite, au lieu d'un appel séparé à EnumWindows pour chaque fenêtre, qui ne serait pas non plus atomique et protégé des modifications simultanées, vous envoyez chaque fenêtre que vous souhaitez comparer dans un tableau params afin que leur z Les commandes peuvent toutes être récupérées en même temps.

            // Find z-order for window.
            Process[] procs = Process.GetProcessesByName("notepad");
            Process top = null;
            int topz = int.MaxValue;
            foreach (Process p in procs)
            {
                IntPtr handle = p.MainWindowHandle;
                int z = 0;
                do
                {
                    z++;
                    handle = GetWindow(handle, 3);
                } while(handle != IntPtr.Zero);

                if (z < topz)
                {
                    top = p;
                    topz = z;
                }
            }

            if(top != null)
                Debug.WriteLine(top.MainWindowTitle);

Voici ma solution C #: La fonction renvoie le zIndex parmi les frères et sœurs du HWND donné, en commençant à 0 pour le plus petit zOrder.

using System;
using System.Runtime.InteropServices;

namespace Win32
{
    public static class HwndHelper
    {
        [DllImport("user32.dll")]
        private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

        public static bool GetWindowZOrder(IntPtr hwnd, out int zOrder)
        {
            const uint GW_HWNDPREV = 3;
            const uint GW_HWNDLAST = 1;

            var lowestHwnd = GetWindow(hwnd, GW_HWNDLAST);

            var z = 0;
            var hwndTmp = lowestHwnd;
            while (hwndTmp != IntPtr.Zero)
            {
                if (hwnd == hwndTmp)
                {
                    zOrder = z;
                    return true;
                }

                hwndTmp = GetWindow(hwndTmp, GW_HWNDPREV);
                z++;
            }

            zOrder = int.MinValue;
            return false;
        }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top