/// <summary>
 /// Decode this PDU to the PduMarshaler.
 /// </summary>
 /// <param name="marshaler">This is used to Decode the fields of this PDU.</param>
 /// <returns></returns>
 public override bool Decode(PduMarshaler marshaler)
 {
     try
     {
         base.Decode(marshaler);
         MonitorLayoutSize = marshaler.ReadUInt32();
         NumMonitors       = marshaler.ReadUInt32();
         Monitors          = new DISPLAYCONTROL_MONITOR_LAYOUT[NumMonitors];
         for (int i = 0; i < Monitors.Length; i++)
         {
             Monitors[i] = new DISPLAYCONTROL_MONITOR_LAYOUT();
             Monitors[i].Decode(marshaler);
         }
         return(true);
     }
     catch
     {
         marshaler.Reset();
         throw new PDUDecodeException(this.GetType(), marshaler.ReadToEnd());
     }
 }
        /// <summary>
        /// Method to create DISPLAYCONTROL_MONITOR_LAYOUT structure
        /// </summary>
        /// <param name="flags">A 32-bit unsigned integer that specifies monitor configuration flags.</param>
        /// <param name="left">A 32-bit signed integer that specifies the x-coordinate of the upper-left corner of the display monitor.</param>
        /// <param name="top">A 32-bit signed integer that specifies the y-coordinate of the upper-left corner of the display monitor.</param>
        /// <param name="width">A 32-bit unsigned integer that specifies the width of the monitor in pixels. </param>
        /// <param name="height">A 32-bit unsigned integer that specifies the height of the monitor in pixels. </param>
        /// <param name="physicalWidth">A 32-bit unsigned integer that specifies the physical width of the monitor, in millimeters (mm).</param>
        /// <param name="physicalHeight">A 32-bit unsigned integer that specifies the physical height of the monitor, in millimeters.</param>
        /// <param name="orientation">A 32-bit unsigned integer that specifies the orientation of the monitor in degrees.</param>
        /// <param name="desktopScaleFactor">A 32-bit, unsigned integer that specifies the desktop scale factor of the monitor.</param>
        /// <param name="deviceScaleFactor">A 32-bit, unsigned integer that specifies the device scale factor of the monitor. </param>
        /// <returns></returns>
        public DISPLAYCONTROL_MONITOR_LAYOUT createMonitorLayout(
            MonitorLayout_FlagValues flags,
            int left,
            int top,
            uint width,
            uint height,
            uint physicalWidth,
            uint physicalHeight,
            MonitorLayout_OrientationValues orientation,
            uint desktopScaleFactor,
            uint deviceScaleFactor)
        {
            DISPLAYCONTROL_MONITOR_LAYOUT monitorLayout = new DISPLAYCONTROL_MONITOR_LAYOUT();

            monitorLayout.Flags = flags;
            monitorLayout.Left  = left;
            monitorLayout.Top   = top;
            if (forceRestriction && width >= MinMonitorSize && width <= MaxMonitorSize && width % 2 == 0)
            {
                monitorLayout.Width = width;
            }
            else
            {
                return(null);
            }
            if (forceRestriction && height >= MinMonitorSize && height <= MaxMonitorSize)
            {
                monitorLayout.Height = height;
            }
            else
            {
                return(null);
            }
            monitorLayout.PhysicalWidth      = physicalWidth;
            monitorLayout.PhysicalHeight     = physicalHeight;
            monitorLayout.Orientation        = orientation;
            monitorLayout.DesktopScaleFactor = desktopScaleFactor;
            monitorLayout.DeviceScaleFactor  = desktopScaleFactor;
            return(monitorLayout);
        }
 /// <summary>
 /// Check none of the specified monitors overlap
 /// </summary>
 /// <param name="monitors">Monitor array</param>
 /// <returns></returns>
 private bool VerifyMonitorsOverlap(DISPLAYCONTROL_MONITOR_LAYOUT[] monitors)
 {
     bool anyOverlap = false;
     for (int i = 0; i < monitors.Length-1; i++)
     {
         for (int j = i+1; j < monitors.Length; j++)
         {
             if (isOverlap(monitors[i], monitors[j])) anyOverlap = true;
         }
     }
     return anyOverlap;
 }
 /// <summary>
 /// Check each monitor is adjacent to at least one other monitor (even if only at a single point) 
 /// </summary>
 /// <param name="monitors">Monitor array</param>
 /// <returns></returns>
 private bool VerifyMonitorsAdjacent(DISPLAYCONTROL_MONITOR_LAYOUT[] monitors)
 {
     for (int i = 0; i < monitors.Length - 1; i++)
     {
         bool adjacent = false;
         for (int j = i + 1; j < monitors.Length; j++)
         {
             if (isAdjacent(monitors[i], monitors[j])) adjacent = true;
         }
         if (!adjacent) return false;
     }
     return true;
 }
 /// <summary>
 /// Check whether two monitors are overlapped
 /// </summary>
 /// <param name="monitor1">Monitor 1</param>
 /// <param name="Monitor2">Monitor 2</param>
 /// <returns></returns>
 private bool isOverlap(DISPLAYCONTROL_MONITOR_LAYOUT monitor1, DISPLAYCONTROL_MONITOR_LAYOUT Monitor2)
 {
     bool overlap = true;
     // Monitor2 in left of Monitor1
     if (Monitor2.Left + Monitor2.Width <= monitor1.Left) overlap = false;
     // Monitor2 is above of Monitor1
     if (Monitor2.Top + Monitor2.Height <= monitor1.Top) overlap = false;
     // Monitor2 in right of Monitor1
     if (Monitor2.Left >= monitor1.Left + monitor1.Width) overlap = false;
     // Monitor2 is beneath of Monitor1
     if (Monitor2.Top >= monitor1.Top + monitor1.Height) overlap = false;
     return overlap;
 }
 /// <summary>
 /// Check whether two monitors are adjacent and not overlapped
 /// </summary>
 /// <param name="monitor1">Monitor 1</param>
 /// <param name="monitor2">Monitor 2</param>
 /// <returns></returns>
 private bool isAdjacent(DISPLAYCONTROL_MONITOR_LAYOUT monitor1, DISPLAYCONTROL_MONITOR_LAYOUT monitor2)
 {
     bool adjacent = false;
     // Monitor2 is adjacent to left of monitor1
     if (monitor2.Left + monitor2.Width == monitor1.Left
         && monitor2.Top + monitor2.Height >= monitor1.Top
         && monitor2.Top <= monitor1.Top + monitor1.Height)
         adjacent = true;
     // Monitor2 is adjacent to top of monitor1
     if (monitor2.Top + monitor2.Height == monitor1.Top
         && monitor2.Left + monitor2.Width >= monitor1.Left
         && monitor2.Left <= monitor1.Left + monitor1.Width)
         adjacent = true;
     // Monitor2 is adjacent to right of monitor1
     if (monitor2.Left == monitor1.Left + monitor1.Width
         && monitor2.Top + monitor1.Height >= monitor1.Top
         && monitor2.Top <= monitor1.Top + monitor1.Height)
         adjacent = true;
     // Monitor2 is adjacent to bottom of monitor1
     if (monitor2.Top == monitor1.Top + monitor1.Height
         && monitor2.Left + monitor2.Width >= monitor1.Left
         && monitor2.Left <= monitor1.Left + monitor1.Width)
         adjacent = true;
     return adjacent;
 }
 /// <summary>
 /// Decode this PDU to the PduMarshaler.
 /// </summary>
 /// <param name="marshaler">This is used to Decode the fields of this PDU.</param>
 /// <returns></returns>
 public override bool Decode(PduMarshaler marshaler)
 {
     try
     {
         base.Decode(marshaler);
         MonitorLayoutSize = marshaler.ReadUInt32();
         NumMonitors = marshaler.ReadUInt32();
         Monitors = new DISPLAYCONTROL_MONITOR_LAYOUT[NumMonitors];
         for (int i = 0; i < Monitors.Length;i++)
         {
             Monitors[i] = new DISPLAYCONTROL_MONITOR_LAYOUT();
             Monitors[i].Decode(marshaler);
         }
         return true;
     }
     catch
     {
         marshaler.Reset();
         throw new PDUDecodeException(this.GetType(), marshaler.ReadToEnd());
     }
 }