【C#】ウィンドウ領域リストの取得【忘備録】

スポンサーリンク
スポンサーリンク

はじめに

ウィンドウ領域リストを取得するクラスを作成したので、忘備録として残しておきます。

インスタンス生成と同時にウィンドウ領域リストを作成し、インスタンスが消えるまで保持するクラスです。

コード

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;

/// <summary>
/// ウィンドウ領域を管理するクラス
/// インスタンス生成時にウィンドウ領域を確定し,ウィンドウ領域を取得できる.
/// </summary>
public class Common_WindowRectList
{
    #region Private
    private const int DWMWA_CLOAKED = 14;
    private const int DWMWA_EXTENDED_FRAME_BOUNDS = 9;
    private readonly List<Rectangle>? WindowRectList;
    [StructLayout(LayoutKind.Sequential)]
    private struct Rect
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
    [DllImport("user32.dll")]
    private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, IntPtr lParam);
    private delegate bool WNDENUMPROC(IntPtr hWnd, IntPtr lParam);
    private bool EnumerateWindows(IntPtr hWnd, IntPtr lParam)
    {
        //例外処理
        if (!IsWindowVisible(hWnd))
        {
            return true;
        }
        _ = DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, out bool IsCloaked, Marshal.SizeOf(typeof(bool)));
        if (IsCloaked)
        {
            return true;
        }

        //一時変数
        Rectangle WindowRect = new();

        //ウィンドウ領域の取得
        _ = DwmGetWindowAttribute(hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, out Rect ExtendedRect, Marshal.SizeOf(typeof(Rect)));
        WindowRect.X = ExtendedRect.left;
        WindowRect.Y = ExtendedRect.top;
        WindowRect.Width = ExtendedRect.right - ExtendedRect.left;
        WindowRect.Height = ExtendedRect.bottom - ExtendedRect.top;

        //例外処理
        if (WindowRect.Width == 0 || WindowRect.Height == 0)
        {
            return true;
        }

        //ウィンドウ領域リストの更新
        if (WindowRectList == null)
        {
            return false;
        }
        WindowRectList.Add(WindowRect);

        //処理継続
        return true;
    }
    [DllImport("user32.dll")]
    private static extern bool IsWindowVisible(IntPtr hWnd);
    [DllImport("dwmapi.dll")]
    private static extern int DwmGetWindowAttribute(IntPtr hWnd, int dwAttribute, out Rect pvAttribute, int cbAttribute);
    [DllImport("dwmapi.dll")]
    private static extern int DwmGetWindowAttribute(IntPtr hWnd, int dwAttribute, out bool pvAttribute, int cbAttribute);
    #endregion

    #region Internal
    /// <summary>
    /// コンストラクタ
    /// ウィンドウ領域を確定し,保存する.
    /// </summary>
    public Common_WindowRectList()
    {
        WindowRectList = new List<Rectangle>();
        _ = EnumWindows(EnumerateWindows, IntPtr.Zero);
    }

    /// <summary>
    /// 保存したウィンドウ領域を出力する.
    /// </summary>
    /// <returns>ウィンドウ領域のリスト(Rectangle型のリスト)/null</returns>
    public List<Rectangle>? GetWindowRectList()
    {
        return WindowRectList;
    }
    #endregion
}

コメント

タイトルとURLをコピーしました