using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Common.system
{
    /// <summary>
    /// 获取系统DPI缩放倍数和真实大小
    /// </summary>
    public class PrimaryScreen
    {
        #region Win32 API
        [DllImport("user32.dll")]
        private static extern IntPtr GetDC(IntPtr ptr);
        [DllImport("gdi32.dll")]
        private static extern int GetDeviceCaps(
       IntPtr hdc, // handle to DC
       int nIndex // index of capability
       );
        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
        #endregion
        #region DeviceCaps常量
        /// <summary>
        /// 屏幕的宽度（像素）；
        /// </summary>
        private const int HORZRES = 8;

        /// <summary>
        /// 屏幕的高度
        /// </summary>
        private const int VERTRES = 10;

        /// <summary>
        /// 沿屏幕宽度每逻辑英寸的像素数，在多显示器系统中，该值对所显示器相同
        /// </summary>
        private const int LOGPIXELSX = 88;

        /// <summary>
        /// 沿屏幕高度每逻辑英寸的像素数，在多显示器系统中，该值对所显示器相同；
        /// </summary>
        private const int LOGPIXELSY = 90;

        /// <summary>
        /// Windows NT：可视桌面的以像素为单位的高度。
        /// </summary>
        private const int DESKTOPVERTRES = 117;

        /// <summary>
        /// DESKTOPHORZRES：Windows NT：可视桌面的以像素为单位的宽度。如果设备支持一个可视桌面或双重显示则此值可能大于VERTRES；
        /// </summary>
        private const int DESKTOPHORZRES = 118;
        #endregion

        #region 属性
        /// <summary>
        /// 获取屏幕分辨率当前物理大小 设置缩放后
        /// </summary>
        public static Size WorkingArea
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                Size size = new Size
                {
                    Width = GetDeviceCaps(hdc, HORZRES),
                    Height = GetDeviceCaps(hdc, VERTRES)
                };
                ReleaseDC(IntPtr.Zero, hdc);
                return size;
            }
        }
        /// <summary>
        /// 当前系统DPI_X 大小 一般为96
        /// </summary>
        public static int DpiX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
                ReleaseDC(IntPtr.Zero, hdc);
                return DpiX;
            }
        }
        /// <summary>
        /// 当前系统DPI_Y 大小 一般为96
        /// </summary>
        public static int DpiY
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int DpiX = GetDeviceCaps(hdc, LOGPIXELSY);
                ReleaseDC(IntPtr.Zero, hdc);
                return DpiX;
            }
        }
        /// <summary>
        /// 获取真实设置的桌面分辨率大小
        /// </summary>
        public static Size DESKTOP
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                Size size = new Size
                {
                    Width = GetDeviceCaps(hdc, DESKTOPHORZRES),
                    Height = GetDeviceCaps(hdc, DESKTOPVERTRES)
                };
                ReleaseDC(IntPtr.Zero, hdc);
                return size;
            }
        }

        /// <summary>
        /// 获取宽度缩放百分比
        /// </summary>
        public static float ScaleX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                /*int t = */
                GetDeviceCaps(hdc, DESKTOPHORZRES);
                /* int d = */
                GetDeviceCaps(hdc, HORZRES);
                float ScaleX = GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return ScaleX;
            }
        }
        /// <summary>
        /// 获取高度缩放百分比
        /// </summary>
        public static float ScaleY
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                float ScaleY = (float)GetDeviceCaps(hdc, DESKTOPVERTRES) / GetDeviceCaps(hdc, VERTRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return ScaleY;
            }
        }

        /// <summary>
        /// 缩放后的大小
        /// </summary>
        /// <returns></returns>
        public static SizeF ScaleScreenSize => new SizeF(DESKTOP.Width / (DpiX / 96f), DESKTOP.Height / (DpiY / 96f));
        /// <summary>
        /// 获取缩放后的工作区域大小
        /// </summary>
        public static RectangleF ScaleWorkingAreaSize
        {
            get
            {
                RectangleF rect = System.Windows.Forms.Screen.GetWorkingArea(new System.Drawing.Point((int)ScaleScreenSize.Width, (int)ScaleScreenSize.Height));
                return new RectangleF(((float)rect.X) / (DpiX / 96f), ((float)rect.Y) / (DpiX / 96f), ((float)rect.Width) / (DpiX / 96f), ((float)rect.Height) / (DpiY / 96f));
            }
        }
        #endregion
    }
}
