Вопрос

Я делаю приложение, в котором я взаимодействую с каждым запущенным приложением. Прямо сейчас мне нужен способ получить z-порядок окна. Например, если Firefox и блокнот запущены, мне нужно знать, какой из них находится впереди.

Есть идеи? Кроме того, чтобы сделать это для главного окна каждого приложения, мне также нужно сделать это для его дочерних и дочерних окон (окон, принадлежащих одному и тому же процессу).

Это было полезно?

Решение

Вы можете использовать функцию GetTopWindow для поиска во всех дочерних окнах родительского окна и возврата дескриптора для дочернего окна, которое является самым высоким в z-порядке. Функция GetNextWindow извлекает дескриптор следующего или предыдущего окна в z-порядке.

GetTopWindow: http://msdn.microsoft.com /en-us/library/ms633514(VS.85).aspx
GetNextWindow: http://msdn.microsoft.com/en- нас / библиотека / ms633509 (VS.85) .aspx

Другие советы

Красиво и кратко:

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

Если вам нужно больше надежности:

/// <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;
}

(Согласно разделу «Примечания» на GetWindow , EnumChildWindows безопаснее, чем вызов GetWindow в цикле, поскольку ваш цикл GetWindow не является атомарным для внешних изменений. в раздел «Параметры» для EnumChildWindows вызов с нулевым родителем эквивалентен EnumWindows .)

Затем вместо отдельного вызова EnumWindows для каждого окна, которое также не будет атомарным и защищенным от одновременных изменений, вы отправляете каждое окно, которое хотите сравнить, в массиве params, чтобы их z Все заказы могут быть получены одновременно.

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

Вот мое решение на C #: Функция возвращает zIndex среди братьев и сестер данного HWND, начиная с 0 для самого низкого 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;
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top