找到窗口的zorder

时间:2009-03-31 18:37:12

标签: wpf winforms

我有一个wpf应用程序,我需要查看当前窗口是否有任何其他窗口。我不能使用IsActive,因为你可以并排放置2个窗口(例如IE和wpf应用程序)并让其他应用程序处于活动状态,但不能超过wpf应用程序。

基本上我想知道是否有什么东西是虚拟的,并且无论激活如何都会遮挡部分wpf窗口。

我尝试了以下内容 GetWindowRect GetTopWindow

并将顶部窗口流程与当前流程进行比较,这样可行,但似乎只能工作一次。

任何想法?

1 个答案:

答案 0 :(得分:0)

之前我做过类似的事情,但我没有找到任何管理方式。因此,它不是真正的WPF问题,而是“回到无管理”或“旧的PInvoke”之类的东西。这是适合您任务的摘录:

XAML定义。

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <Label Name="IsSomethingOverLabel">Label</Label>
</Grid>
</Window>

CS代码背后。

using System;
using System.Windows;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using System.Windows.Threading;

namespace WpfApplication1 {
using LONG = System.Int32;
using UINT = System.UInt32;    

public partial class Window1: Window {
    DispatcherTimer tmr;

    public Window1() {
        InitializeComponent();

        tmr = new DispatcherTimer();
        tmr.Tick += new EventHandler(tmr_Tick);
        tmr.Start();
    }

    void tmr_Tick(object sender, EventArgs e) {
        RECT Rect2 = GetWindowRect(Handle);
        IntPtr h = GetWindow(Handle, GW_HWNDPREV);
        while(h != IntPtr.Zero) {
            if(IsWindowShown(h))//This is to check that the window found is not minimized etc.
            {
                RECT Rect1 = GetWindowRect(h);
                if(Rect1OverlapsRect2(Rect1, Rect2)) {
                    IsSomethingOverLabel.Content = GetWindowText(h);
                    return;
                }
            }
            h = GetWindow(h, GW_HWNDPREV);
        }
        IsSomethingOverLabel.Content = "Nothing over";
    }

    bool Rect1OverlapsRect2(RECT Rect1, RECT Rect2) {
        return Rect1.left < Rect2.right && Rect1.right > Rect2.left &&
            Rect1.top < Rect2.bottom && Rect1.bottom > Rect2.top;
    }

    private IntPtr Handle {
        get { return new WindowInteropHelper(this).Handle; }
    }


    public const uint GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_MAX = 5;
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd);

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT {
        public LONG left;
        public LONG top;
        public LONG right;
        public LONG bottom;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
    public static RECT GetWindowRect(IntPtr hWnd) {
        RECT lpRect = new RECT();
        if(!GetWindowRect(hWnd, ref lpRect)) {
            lpRect.top = lpRect.left = lpRect.bottom = lpRect.right = -1;
        }
        return lpRect;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetWindowTextLength(IntPtr hWnd);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetWindowText(IntPtr hWnd, string lpString, int nMaxCount);
    public static string GetWindowText(IntPtr hWnd) {
        int len = GetWindowTextLength(hWnd) + 1;
        string s = new string(' ', len);
        if(GetWindowText(hWnd, s, len) != 0) {
            return s.Substring(0, len - 1);
        } else {
            return "";
        }
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool IsWindowVisible(IntPtr hWnd);
    public const int SW_HIDE = 0,
        SW_SHOWNORMAL = 1,
        SW_NORMAL = 1,
        SW_SHOWMINIMIZED = 2,
        SW_SHOWMAXIMIZED = 3,
        SW_MAXIMIZE = 3,
        SW_SHOWNOACTIVATE = 4,
        SW_SHOW = 5,
        SW_MINIMIZE = 6,
        SW_SHOWMINNOACTIVE = 7,
        SW_SHOWNA = 8,
        SW_RESTORE = 9,
        SW_SHOWDEFAULT = 10,
        SW_MAX = 10;
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
    [StructLayout(LayoutKind.Sequential)]
    public struct POINT {
        public LONG x;
        public LONG y;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct WINDOWPLACEMENT {
        public UINT length;
        public UINT flags;
        public UINT showCmd;
        public POINT ptMinPosition;
        public POINT ptMaxPosition;
        public RECT rcNormalPosition;
    }

    public static bool IsWindowShown(IntPtr hWnd) {
        bool res = IsWindowVisible(hWnd);
        WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
        if(res && GetWindowPlacement(hWnd, ref placement)) {
            switch(placement.showCmd) {
                case SW_RESTORE:
                case SW_SHOW:
                case SW_SHOWMAXIMIZED:
                case SW_SHOWNA:
                case SW_SHOWNORMAL:
                    res = true;
                    break;
                default:
                    res = false;
                    break;
            }
        }
        return res;
    }
}
}

重新审视代码,GetWindowPlacement本身可能就足够了,取消GetWindowRect调用,你也可以试试。