I've done something similar before and I did not find any managed way of doing this. Hence, it's not really a WPF question, but rather "back to unmanaged" or "good old PInvoke" sort of thing. Here's an extract adapted for your task:
XAML definition.
<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 code behind.
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;
}
}
}
Having a fresh look at the code, GetWindowPlacement could probably be sufficient by itself, eliminating the GetWindowRect call, you can also try that.