найти порядок окна - PullRequest
1 голос
/ 31 марта 2009

У меня есть приложение wpf, для которого мне нужно выяснить, находится ли какое-либо другое окно поверх текущего окна. Я не могу использовать IsActive, так как у вас может быть 2 окна рядом (например, IE и приложение wpf) и другое приложение должно быть активным, но не поверх приложения wpf.

По сути, я хочу знать, если что-то закончилось физически и закрывает часть окна wpf независимо от активации.

Я пробовал следующее GetWindowRect GetTopWindow

и сравнение процесса topwindow с текущим процессом, это работает, но, кажется, работает только один раз.

есть идеи?

1 Ответ

0 голосов
/ 07 апреля 2009

Я делал нечто подобное раньше, и я не нашел никакого управляемого способа сделать это. Следовательно, это на самом деле не вопрос 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, вы также можете попробовать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...