/// <summary>
        /// Auto detects the window under the mouse cursor.
        /// </summary>
        private void AutoDetectWindow()
        {
            this.Visible = false;
            Rectangle rect = Rectangle.Empty;

            try
            {
                try
                {
                    // Wait to make sure the context menu gets closed and the drape gets invisible
                    MainForm.SleepAndWait(10);

                    // Get the bounds of the window under cursor
                    rect = WinAPIHelper.RectangleFromPoint(Cursor.Position.X, Cursor.Position.Y);
                }
                catch
                {
                    // ignore errors
                }
            }
            finally
            {
                this.Visible = true;
            }

            // Add the new auto detected focus area, if not empty and not too large
            if ((!rect.IsEmpty) && (!FocusControl.IsTooLarge(rect, this)))
            {
                this.AddNewFocusArea(rect);
            }
        }
        /// <summary>
        /// Deletes all focus areas.
        /// </summary>
        private void DeleteAllFocusAreas()
        {
            List <FocusControl> controlsToDelete = new List <FocusControl>();

            FocusControl.ForEach(this, (control) => { controlsToDelete.Add(control); });
            controlsToDelete.ForEach((control) => { control.Delete(); });
        }
        // ********************************************************************
        // Multiple Focus Controls
        // ********************************************************************

        /// <summary>
        /// Counts the number of focus controls that have the specified owner.
        /// </summary>
        /// <param name="owner">The owner of the focus controls.</param>
        /// <returns>The number of focus controls.</returns>
        public static int GetCount(Control owner)
        {
            int count = 0;

            FocusControl.ForEach(owner, (control) => { count++; });
            return(count);
        }
 /// <summary>
 /// Completes the drawing of a new focus area.
 /// </summary>
 /// <param name="focusArea">The focus area control to complete.</param>
 private void CompleteNewFocusArea(FocusControl focusArea)
 {
     if ((!focusArea.IsDisposed) && (focusArea != null))
     {
         focusArea.SizeMoveBegin        += (sender, e) => { this.TransparentForEditing = true; };
         focusArea.SizeMoveEnd          += (sender, e) => { this.TransparentForEditing = false; };
         focusArea.OtherFocusableControl = this.focusableListBox;
     }
 }
 /// <summary>
 /// Performs an action on all focus controls that have the specified owner.
 /// </summary>
 /// <param name="owner">The owner of the focus controls.</param>
 /// <param name="action">The action delegate to perform.</param>
 public static void ForEach(Control owner, Action <FocusControl> action)
 {
     if (action != null)
     {
         foreach (Control control in owner.Controls)
         {
             FocusControl focusControl = control as FocusControl;
             if (focusControl != null)
             {
                 action(focusControl);
             }
         }
     }
 }
        // ********************************************************************
        // Events - Main Menu - Opening/Closing
        // ********************************************************************

        /// <summary>
        /// Enables/disables certain items based on the current state of the program.
        /// </summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">Cancelable event data.</param>
        private void EventMenuMainOpening(object sender, CancelEventArgs e)
        {
            this.CancelAutoDetectMenuMode();
            this.menuMainDeleteAll.Visible = FocusControl.GetCount(this) > 0;

            // Disable most of the menu items if on pause
            this.menuMainColor.Enabled = this.menuMainOpacity.Enabled = this.menuMainResetToBlack.Enabled = this.menuMainCoverMonitors.Enabled =
                this.menuMainAutoDetectArea.Enabled = this.menuMainAutoDetectWindow.Enabled =
                    this.menuMainRandomArea.Enabled = this.menuMainDeleteAll.Enabled = this.menuMainLoad.Enabled =
                        this.menuMainSave.Enabled   = this.menuMainSettings.Enabled = this.menuMainQuickStart.Enabled = this.Visible;

            // Hide separators on very small resolutions
            this.menuMainSeparator1.Visible = this.menuMainSeparator2.Visible = this.menuMainSeparator3.Visible = this.menuMain.Height < this.Height - 100;
        }
        /// <summary>
        /// Auto detects the area under the mouse cursor.
        /// </summary>
        private void AutoDetectArea()
        {
            this.Visible = false;
            Rectangle rect = Rectangle.Empty;

            try
            {
                try
                {
                    // Wait to make sure the context menu gets closed and the drape gets invisible
                    MainForm.SleepAndWait(10);

                    // Get the bounds of the control under cursor using Accessible Objects
                    rect = WinAPIHelper.GetAccessibleObjectBounds(Cursor.Position.X, Cursor.Position.Y);
                }
                catch
                {
                    // ignore errors
                }

                // If we fail to get the bounds, or the area is too large, retry using Window methods
                if (rect.IsEmpty || FocusControl.IsTooLarge(rect, this))
                {
                    try
                    {
                        rect = WinAPIHelper.RectangleFromPoint(Cursor.Position.X, Cursor.Position.Y);
                    }
                    catch
                    {
                        // ignore errors
                    }
                }
            }
            finally
            {
                this.Visible = true;
            }

            // Add the new auto detected focus area, if not empty and not too large
            if ((!rect.IsEmpty) && (!FocusControl.IsTooLarge(rect, this)))
            {
                this.AddNewFocusArea(rect);
            }
        }
        /// <summary>
        /// Saves the drape color, opacity, and the current focus areas to a CinemaDrape configuration file.
        /// </summary>
        /// <param name="filePath">The location of the configuration file.</param>
        /// <param name="saveAreas">True to save the current focus areas, false otherwise.</param>
        private void SaveLayout(string filePath, bool saveAreas)
        {
            VerySimpleIni iniFile = string.IsNullOrEmpty(filePath) ?
                                    new VerySimpleIni(Properties.Resources.StringDefaultSettingsFile, Application.ExecutablePath, Application.CompanyName, Application.ProductName, true) :
                                    new VerySimpleIni(filePath, true);

            if (iniFile.IsReady)
            {
                iniFile.SetValue(Properties.Resources.StringSettingsDrapeColor, ColorTranslator.ToHtml(this.BackColor));
                int intlastUserOpacity = (int)(this.lastUserOpacity * 100);
                iniFile.SetValue(Properties.Resources.StringSettingsDrapeOpacity, intlastUserOpacity.ToString(CultureInfo.InvariantCulture));
                iniFile.SetValue(Properties.Resources.StringSettingsHotkey, this.hotKeyString);
                int intPeekOpacity = (int)(this.peekOpacity * 100);
                iniFile.SetValue(Properties.Resources.StringSettingsPeekOpacity, intPeekOpacity.ToString(CultureInfo.InvariantCulture));
                iniFile.SetValue(Properties.Resources.StringSettingsAutoRestoreAreas, this.autoRestoreAreas.ToString());

                if (saveAreas)
                {
                    FocusControl.ForEach(
                        this,
                        (control) =>
                    {
                        iniFile.SetValue(Properties.Resources.StringSettingsFocusArea, new RectangleConverter().ConvertToInvariantString(control.RealBounds));
                    });
                }

                iniFile.SetValue(Properties.Resources.StringSettingsShowQuickStart, this.quickStartForm.ShowAtStartupCheckBox.Checked.ToString());
                iniFile.SetValue(
                    Properties.Resources.StringSettingsQuickStartLocation,
                    new PointConverter().ConvertToInvariantString(this.quickStartForm.Location));

                try
                {
                    iniFile.Save();
                }
                catch
                {
                    // Ignore configuration save errors
                }
            }
        }
        /// <summary>
        /// Adds and completes a new focus area with the specified bounds.
        /// </summary>
        /// <param name="rect">The bounds of the new focus area.</param>
        private void AddNewFocusArea(Rectangle rect)
        {
            FocusControl focusArea = new FocusControl(this, rect, this.menuFocus, this.appColor, true);

            this.CompleteNewFocusArea(focusArea);
        }
 /// <summary>
 /// Sets the new drape color, but first ensures it's different from the transparency key color value.
 /// </summary>
 /// <param name="color">The new color value for the drape.</param>
 private void SetDrapeColor(Color color)
 {
     this.BackColor = ColorsCommon.EnsureDifferentColor(color, this.TransparencyKey);    // Ensure the color is different from the transparency color
     FocusControl.ForEach(this, (control) => { control.InitBorderPens(); });             // Reinitialize the border pens of each focus control
     this.Invalidate(true);                                                              // Force the redrawing of the drape
 }