문제

각 실행중인 응용 프로그램과 상호 작용하는 응용 프로그램을 만들고 있습니다. 지금은 창의 zorord를 얻는 방법이 필요합니다. 예를 들어, Firefox와 Notepad가 실행중인 경우 어느쪽에 있는지 알아야합니다.

어떤 아이디어? 각 응용 프로그램의 기본 창에 대해이 작업을 수행하는 것 외에도 자녀와 자매 창 (동일한 프로세스에 속하는 창)을 위해 수행해야합니다.

도움이 되었습니까?

해결책

getTopWindow 함수를 사용하여 부모 창의 모든 자식 창을 검색하고 Z-Order에서 가장 높은 어린이 창으로 핸들을 반환 할 수 있습니다. getNextWindow 함수는 Z-Order의 다음 또는 이전 창으로의 핸들을 검색합니다.

GetTopWindow : http://msdn.microsoft.com/en-us/library/ms633514(vs.85).aspx
getNextWindow : http://msdn.microsoft.com/en-us/library/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, null 부모와 함께 호출하는 것은 동일합니다 EnumWindows.)

그런 다음 별도의 전화 대신 EnumWindows 원자력이없고 동시 변경으로부터 안전하지 않은 각 창에 대해 매개 변수 배열에서 비교하려는 각 창을 보내므로 Z-ord를 모두 동시에 검색 할 수 있습니다.

            // 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# 솔루션은 다음과 같습니다. 함수는 주어진 HWND의 형제 자매들 사이에서 zindex를 반환하여 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