これは、 @ MarvinDickhausの回答のコードの変更されたC#バージョンです。
特定のポイントのみをチェックすることで、ウィンドウまたはコントロールが表示されているか、部分的に表示されているかをテストできます。
主な基本的な関心は、完全にまたは部分的に覆われたフォームを前面に出すことができることです。
13点を使用しますが、さらに追加することができ、任意の数を渡してその数から座標を計算するように方法を改善できます。Windows 10フォームの場合、デフォルトのマージンは15に設定されています。
static partial class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public struct PointStruct
{
public int X;
public int Y;
public PointStruct(int x, int y)
{
X = x;
Y = y;
}
}
[DllImport("user32.dll")]
static public extern IntPtr WindowFromPoint(PointStruct Point);
}
static public IEnumerable<T> GetAllControls<T>(this Control control)
{
var controls = control.Controls.OfType<T>();
return control.Controls.Cast<Control>()
.SelectMany(c => c.AllControls<T>())
.Concat(controls);
}
static public List<Point> GetGridPoints(this Control control, int margin = 15)
{
int widthDiv2 = control.Width / 2;
int heightDiv2 = control.Height / 2;
int widthDiv4 = widthDiv2 / 4;
int heightDiv4 = heightDiv2 / 4;
var points = new List<Point>();
// Center
points.Add(new Point(control.Left + widthDiv2, control.Top + heightDiv2));
// Corners
points.Add(new Point(control.Left + margin, control.Top + margin));
points.Add(new Point(control.Right - margin, control.Top + margin));
points.Add(new Point(control.Left + margin, control.Bottom - margin));
points.Add(new Point(control.Right - margin, control.Bottom - margin));
// Borders
points.Add(new Point(control.Left + widthDiv4, control.Top + heightDiv4));
points.Add(new Point(control.Right - widthDiv4, control.Top + heightDiv4));
points.Add(new Point(control.Left + widthDiv4, control.Bottom - heightDiv4));
points.Add(new Point(control.Right - widthDiv4, control.Bottom - heightDiv4));
// Inner
points.Add(new Point(control.Left + widthDiv2, control.Top + margin));
points.Add(new Point(control.Left + widthDiv2, control.Bottom - margin));
points.Add(new Point(control.Left + margin, control.Top + heightDiv2));
points.Add(new Point(control.Right - margin, control.Top + heightDiv2));
return points;
}
static public bool IsVisibleOnTop(this Control control, int requiredPercent = 100, int margin = 15)
{
if ( !control.Visible ) return false;
var controls = control.GetAllControls<Control>().Select(c => c.Handle).ToList();
var points = control.GetGridPoints(margin);
bool all = requiredPercent == 100;
int found = 0;
int required = points.Count();
if (!all) required = required * requiredPercent / 100;
foreach ( var point in points )
{
var handle = NativeMethods.WindowFromPoint(new NativeMethods.PointStruct(point.X, point.Y));
if ( handle == control.Handle || controls.Contains(handle) )
{
if ( ++found == required ) return true;
}
else
{
if ( all ) return false;
}
}
return false;
}