在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#图形和图像处理 → <赞>GIF屏幕录制工具源码下载

<赞>GIF屏幕录制工具源码下载

C#图形和图像处理

下载此实例
  • 开发语言:C#
  • 实例大小:4.47M
  • 下载次数:42
  • 浏览次数:426
  • 发布时间:2017-04-12
  • 实例类别:C#图形和图像处理
  • 发 布 人:inscan
  • 文件格式:.zip
  • 所需积分:2
 相关标签: gif 录制 工具 屏幕

实例介绍

【实例简介】
【实例截图】


【核心代码】

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using ScreenToGif.Capture;
using ScreenToGif.Controls;
using ScreenToGif.Encoding;
using ScreenToGif.Pages;
using ScreenToGif.Properties;
using ScreenToGif.Util;
using Application = System.Windows.Forms.Application;
using MessageBox = System.Windows.Forms.MessageBox;
using Point = System.Drawing.Point;
using Size = System.Drawing.Size;
using DataFormats = System.Windows.Forms.DataFormats;
using DragDropEffects = System.Windows.Forms.DragDropEffects;

namespace ScreenToGif
{
    /// <summary>
    /// Modern
    /// </summary>
    public partial class Modern : Form
    {
        #region Variables

        /// <summary>
        /// The animated gif encoder, this encodes the list of frames to a gif format.
        /// </summary>
        private AnimatedGifEncoder _encoder = new AnimatedGifEncoder();
        /// <summary>
        /// This object retrieves the icon of the cursor.
        /// </summary>
        readonly CaptureCursor _capture = new CaptureCursor();
        /// <summary>
        /// The object of the keyboard hook.
        /// </summary>
        private readonly UserActivityHook _actHook;
        /// <summary>
        /// The editor may increase the size of the form, use this to go back to the last size (The size before opening the editor).
        /// </summary>
        private Size _lastSize;
        /// <summary>
        /// To hold the update of the size of the form while typing in the size textBoxes.
        /// </summary>
        private bool _screenSizeEdit;
        /// <summary>
        /// The amount of seconds of the pre start delay, plus 1 (1 1=2);
        /// </summary>
        private int _preStartCount = 1;
        /// <summary>
        /// The numbers of frames, this is updated while recording.
        /// </summary>
        private int _frameCount = 0;
        /// <summary>
        /// The output path of the recording.
        /// </summary>
        private string _outputpath;
        /// <summary>
        /// The actual stage of the program.
        /// </summary>
        private Stage _stage = Stage.Stopped; //0 Stopped, 1 Recording, 2 Paused, 3 PreStart, 4 Editing, 5 Encoding
        /// <summary>
        /// The list of information about the cursor.
        /// </summary>
        private List<CursorInfo> _listCursor = new List<CursorInfo>(); //List that stores the icon
        /// <summary>
        /// The list of individual delays.
        /// </summary>
        private List<int> _listDelay = new List<int>();
        /// <summary>
        /// Object that holds the information of the cursor.
        /// </summary>
        private CursorInfo _cursorInfo;
        /// <summary>
        /// Stores the last position of the click, this is used in the drag of the window.
        /// </summary>
        static Point _lastClick;
        /// <summary>
        /// Holds the position of the cursor.
        /// </summary>
        private Point _posCursor;
        /// <summary>
        /// True if it is a IBeam cursor.
        /// </summary>
        private bool _isIbeam;
        /// <summary>
        /// The maximum size of the recording. Also the maximum size of the window.
        /// </summary>
        private Point _sizeScreen = new Point(SystemInformation.PrimaryMonitorSize);

        /// <summary>
        /// The resolution of the primary screen.
        /// </summary>
        private Size _sizeResolution;

        private Bitmap _bt;
        private Graphics _gr;

        /// <summary>
        /// The encode worker thread.
        /// </summary>
        private Thread _workerThread;

        /// <summary>
        /// The point position on the bitmap, used to insert text.
        /// </summary>
        private Point _pointTextPosition;

        /// <summary>
        /// The text of the "All" label of the TreeView.
        /// </summary>
        private readonly string _parentNodeLabel = Resources.Label_All;

        /// <summary>
        /// Displays a tray icon.
        /// </summary>
        private readonly ScreenToGifTrayIcon _trayIcon = new ScreenToGifTrayIcon();

        /// <summary>
        /// Indicates when the user is mouse-clicking.
        /// </summary>
        private bool _recordClicked = false;

        /// <summary>
        /// The Path of the Temp folder.
        /// </summary>
        private readonly string _pathTemp = Path.GetTempPath()  
            String.Format(@"ScreenToGif\Recording\{0}\", DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"));

        #region Enums

        private enum Stage : int
        {
            Stopped = 0,
            Recording = 1,
            Paused = 2,
            PreStarting = 3,
            Editing = 4,
            Encoding = 5,
            Snapping = 6,
        };

        private enum ActionEnum : int
        {
            Grayscale = 0,
            Color,
            Pixelate,
            Blur,
            Negative,
            Sepia,
            Delete,
            Border,
            Speed,
            Caption,
            Export,
            AddText,
            FlipRotate,
            FreeDraw,
            Progress,
        };

        #endregion

        #region Lists

        /// <summary>
        /// Lists of frames as file names.
        /// </summary>
        List<string> _listFrames = new List<string>();

        /// <summary>
        /// Lists of frames as file names.
        /// </summary>
        List<string> _listFramesEdit;
        List<string> _listFramesUndo;

        /// <summary>
        /// List of delays that will be edited.
        /// </summary>
        private List<int> _listDelayEdit;

        /// <summary>
        /// List of delays that holds the last alteration.
        /// </summary>
        private List<int> _listDelayUndo;

        #endregion

        #endregion

        #region Native

        //[DllImport("user32.dll")]
        //private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);

        //[DllImport("gdi32.dll")]
        //private static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);

        //[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
        //private static extern bool DeleteObject(System.IntPtr hObject);

        //For the hit test area
        private const int cGrip = 20;
        private const int cCaption = 35;
        private const int cBorder = 7;

        /// <summary>
        /// Indicates the position of the cursor hot spot.
        /// </summary>
        public enum HitTest : int
        {
            /// <summary>
            /// On the screen background or on a dividing line between windows (same as HTNOWHERE, except that the DefWindowProc function produces a system beep to indicate an error).
            /// </summary>
            HTERROR = -2,

            /// <summary>
            /// In a window currently covered by another window in the same thread (the message will be sent to underlying windows in the same thread until one of them returns a code that is not HTTRANSPARENT).
            /// </summary>
            HTTRANSPARENT = -1,

            /// <summary>
            /// On the screen background or on a dividing line between windows.
            /// </summary>
            HTNOWHERE = 0,

            /// <summary>
            /// In a client area.
            /// </summary>
            HTCLIENT = 1,

            /// <summary>
            /// In a title bar.
            /// </summary>
            HTCAPTION = 2,

            /// <summary>
            /// In a window menu or in a Close button in a child window.
            /// </summary>
            HTSYSMENU = 3,

            /// <summary>
            /// In a size box (same as HTSIZE).
            /// </summary>
            HTGROWBOX = 4,

            /// <summary>
            /// In a size box (same as HTGROWBOX).
            /// </summary>
            HTSIZE = 4,

            /// <summary>
            /// In a menu.
            /// </summary>
            HTMENU = 5,

            /// <summary>
            /// In a horizontal scroll bar.
            /// </summary>
            HTHSCROLL = 6,

            /// <summary>
            /// In the vertical scroll bar.
            /// </summary>
            HTVSCROLL = 7,

            /// <summary>
            /// In a Minimize button.
            /// </summary>
            HTMINBUTTON = 8,

            /// <summary>
            /// In a Minimize button.
            /// </summary>
            HTREDUCE = 8,

            /// <summary>
            /// In a Maximize button.
            /// </summary>
            HTMAXBUTTON = 9,

            /// <summary>
            /// In a Maximize button.
            /// </summary>
            HTZOOM = 9,

            /// <summary>
            /// In the left border of a resizable window (the user can click the mouse to resize the window horizontally).
            /// </summary>
            HTLEFT = 10,

            /// <summary>
            /// In the right border of a resizable window (the user can click the mouse to resize the window horizontally).
            /// </summary>
            HTRIGHT = 11,

            /// <summary>
            /// In the upper-horizontal border of a window.
            /// </summary>
            HTTOP = 12,

            /// <summary>
            /// In the upper-left corner of a window border.
            /// </summary>
            HTTOPLEFT = 13,

            /// <summary>
            /// In the upper-right corner of a window border.
            /// </summary>
            HTTOPRIGHT = 14,

            /// <summary>
            /// In the lower-horizontal border of a resizable window (the user can click the mouse to resize the window vertically).
            /// </summary>
            HTBOTTOM = 15,

            /// <summary>
            /// In the lower-left corner of a border of a resizable window (the user can click the mouse to resize the window diagonally).
            /// </summary>
            HTBOTTOMLEFT = 16,

            /// <summary>
            /// In the lower-right corner of a border of a resizable window (the user can click the mouse to resize the window diagonally).
            /// </summary>
            HTBOTTOMRIGHT = 17,

            /// <summary>
            /// In the border of a window that does not have a sizing border.
            /// </summary>
            HTBORDER = 18,

            /// <summary>
            /// In a Close button.
            /// </summary>
            HTCLOSE = 20,

            /// <summary>
            /// In a Help button.
            /// </summary>
            HTHELP = 21,
        };

        #endregion

        /// <summary>
        /// Default constructor of the form Modern.
        /// </summary>
        public Modern()
        {
            InitializeComponent();

            #region Load Save Data

            //Gets and sets the fps
            numMaxFps.Value = Properties.Settings.Default.maxFps;

            //Load last saved window size
            this.Size = new Size(Settings.Default.size.Width, Settings.Default.size.Height);

            //Put the grid as background.
            RightSplit.Panel2.BackgroundImage =
                (con_showGrid.Checked = Settings.Default.ShowGrid) ? //If
                Properties.Resources.grid : null;  //True-False

            //Recording options.
            con_Fullscreen.Checked = Settings.Default.fullscreen;
            con_Snapshot.Checked = Settings.Default.snapshot;

            #endregion

            //Gets the window size and show in the textBoxes
            tbHeight.Text = panelTransparent.Height.ToString();
            tbWidth.Text = panelTransparent.Width.ToString();

            #region Performance and flickering tweaks

            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.ResizeRedraw |
                          ControlStyles.OptimizedDoubleBuffer |
                          ControlStyles.AllPaintingInWmPaint |
                          ControlStyles.UserPaint, true);

            #endregion

            #region Global Hook

            try
            {
                _actHook = new UserActivityHook();
                _actHook.KeyDown  = KeyHookTarget;
                _actHook.Start(false, true);
            }
            catch (Exception) { }

            #endregion

            #region If there is a gif file as argument, read the file and jump directly to the editor.

            if (!String.IsNullOrEmpty(ArgumentUtil.FileName))
            {
                CreateTemp();

                //TODO: Redo this code. It works, but...
                _listFramesEdit = new List<string>();
                _listDelayEdit = new List<int>();

                _listFramesUndo = new List<string>();
                _listDelayUndo = new List<int>();

                _delay = 66; //We should get the true delay.

                AddPictures(ArgumentUtil.FileName);

                int width = _listFramesEdit[0].From().Size.Width < 500 ? 500 : _listFramesEdit[0].From().Size.Width;
                int height = _listFramesEdit[0].From().Size.Height < 300 ? 300 : _listFramesEdit[0].From().Size.Height;

                _lastSize = new Size(width, height);

                btnUndo.Enabled = false;
                btnReset.Enabled = false;

                _listFrames = new List<string>(_listFramesEdit);
                _listDelay = new List<int>(_listDelayEdit);

                this.TopMost = false;

                EditFrames();
                ShowHideButtons(true);

                pictureBitmap.AllowDrop = true;
                _stage = Stage.Editing;
                ArgumentUtil.FileName = null;
            }

            #endregion

            _trayIcon.NotifyIconClicked  = NotifyIconClicked;

            #region Detect High DPI Settings

            float dpiX;
            using (Graphics graphics = this.CreateGraphics())
            {
                dpiX = graphics.DpiX;
            }

            if (dpiX > 96)
            {
                if (Settings.Default.showHighDpiWarn)
                {
                    var highDpi = new HighDpi();
                    highDpi.ShowDialog();

                    highDpi.Dispose();
                }
            }
            else
            {
                Settings.Default.showHighDpiWarn = false;
            }

            #endregion
        }

        #region Override

        /// <summary>
        /// System's constant used to define a drop shadow of the form.
        /// </summary>
        private const int CS_DROPSHADOW = 0x00020000;
        /// <summary>
        /// System's constant that defines the hit test of the form.
        /// </summary>
        public const int WM_NCHITTEST = 0x84;

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ClassStyle |= CS_DROPSHADOW;
                return cp;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            //Creates a border around the form
            Graphics g = e.Graphics;
            var rectOutside = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
            var rectInside = new Rectangle(new Point(panelTransparent.Left - 1, panelTransparent.Top - 1), new Size(panelTransparent.Width   1, panelTransparent.Height   1));

            Pen pen;

            if (_stage == Stage.Recording)
            {
                pen = new Pen(Color.FromArgb(255, 25, 0));
            }
            else if (_stage == Stage.Editing)
            {
                pen = new Pen(Color.FromArgb(30, 180, 30));
            }
            else
            {
                pen = new Pen(Color.FromArgb(0, 151, 251));
            }

            g.DrawRectangle(pen, rectOutside);
            g.DrawRectangle(pen, rectInside);

            //Create a round border, not so beautiful
            //System.IntPtr ptrBorder = CreateRoundRectRgn(0, 0,
            //this.ClientSize.Width, this.ClientSize.Height, 15, 15);
            //SetWindowRgn(this.Handle, ptrBorder, true);

            //Create a rectangle around the form, to make a hit test
            Rectangle rc = new Rectangle(this.ClientSize.Width - cGrip,
                this.ClientSize.Height - cGrip, cGrip, cGrip);

            //Paints the size grip
            //ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);

        }

        protected override void WndProc(ref Message m)
        {
            if (_stage == Stage.Stopped || _stage == Stage.Editing)
            {
                if (m.Msg == (int)WM_NCHITTEST)
                {
                    #region Hit Test
                    // Trap WM_NCHITTEST
                    Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
                    pos = this.PointToClient(pos);

                    //Bottom Left
                    if (pos.X <= cGrip && pos.Y >= this.ClientSize.Height - cGrip)
                    {
                        m.Result = (IntPtr)HitTest.HTBOTTOMLEFT;
                        return;
                    }

                    //Bottom Right
                    else if (pos.X >= this.ClientSize.Width - cGrip &&
                        pos.Y >= this.ClientSize.Height - cGrip)
                    {
                        m.Result = (IntPtr)HitTest.HTBOTTOMRIGHT;
                        return;
                    }

                    //Top Left
                    else if (pos.Y <= cBorder && pos.X <= cBorder)
                    {
                        m.Result = (IntPtr)HitTest.HTTOPLEFT;
                        return;
                    }

                    //Top Right
                    else if (pos.Y <= cBorder && pos.X >= this.ClientSize.Width - cBorder)
                    {
                        m.Result = (IntPtr)HitTest.HTTOPRIGHT;
                        return;
                    }

                    //Top
                    else if (pos.Y <= cBorder)
                    {
                        m.Result = (IntPtr)HitTest.HTTOP;
                        return;
                    }

                    //Caption
                    else if (pos.Y < cCaption && pos.X > 50 && pos.Y < ClientSize.Width)
                    {
                        m.Result = (IntPtr)HitTest.HTCAPTION;
                        return;
                    }

                    //Bottom
                    else if (pos.Y >= this.ClientSize.Height - cBorder)
                    {
                        m.Result = (IntPtr)HitTest.HTBOTTOM;
                        return;
                    }

                    //Left
                    else if (pos.X <= cBorder)
                    {
                        m.Result = (IntPtr)HitTest.HTLEFT;
                        return;
                    }

                    //Right
                    else if (pos.X >= this.ClientSize.Width - cBorder)
                    {
                        m.Result = (IntPtr)HitTest.HTRIGHT;
                        return;
                    }
                    #endregion
                }
            }

            base.WndProc(ref m);
        }

        /// <summary>
        /// Process the Key events, such as pressing. This handles the keyboard shortcuts.
        /// </summary>
        /// <param name="msg">A Message, passed by reference, that represents the window message to process. </param>
        /// <param name="keyData">One of the Keys values that represents the key to process. </param>
        /// <returns><code>true</code> if the character was processed by the control; otherwise, <code>false</code>.</returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            //If not in the editor page.
            if (_stage != Stage.Editing)
            {
                return base.ProcessCmdKey(ref msg, keyData);
            }

            switch (keyData)
            {
                case Keys.Delete: //Delete this frame
                    con_deleteSelectedFrame_Click(null, null);
                    return true;
                case Keys.Control | Keys.G: //Show grid
                    con_showGrid.Checked = !con_showGrid.Checked; //Inverse the checkState.
                    con_showGrid_CheckedChanged(null, null);
                    return true;
                case Keys.Right: //Next frame
                    btnNext_Click(null, null);
                    return true;
                case Keys.Left: //Previous frame
                    btnPrevious_Click(null, null);
                    return true;
                case Keys.Alt | Keys.Right: //Delete everything after this
                    con_deleteAfter_Click(null, null);
                    return true;
                case Keys.Alt | Keys.Left: //Delete everything before this
                    con_deleteBefore_Click(null, null);
                    return true;
                case Keys.Control | Keys.E: //Export Frame
                    con_exportFrame_Click(null, null);
                    return true;
                case Keys.Control | Keys.T: //Export Frame
                    con_addText_Click(null, null);
                    return true;
                case Keys.Shift | Keys.Escape: //Cancel
                    btnCancel_Click(null, null);
                    return true;
                case Keys.Shift | Keys.Enter: //Done
                    btnDone_Click(null, null);
                    return true;
                case Keys.Alt | Keys.D: //Show the Delay Context
                    #region Show Delay

                    contextDelay.Show(lblDelay, 0, lblDelay.Height);
                    con_tbDelay.Text = _delay.ToString();
                    con_tbDelay.Focus();

                    #endregion
                    return true;
                case Keys.Control | Keys.Up: //Move Frame Upwards
                    con_MoveUpwards_Click(null, null);
                    return true;
                case Keys.Control | Keys.Down: //Move Frame Downwards
                    con_MoveDownwards_Click(null, null);
                    return true;
                case Keys.F2: //Rename Frame
                    con_RenameFrame_Click(null, null);
                    return true;
                case Keys.Control | Keys.C: //Make a Copy
                    con_MakeACopy_Click(null, null);
                    return true;
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        #endregion

        #region TitleBar Buttons

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnMaximize_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Normal)
            {
                this.WindowState = FormWindowState.Maximized;
                btnMaximize.Image = Resources.MaximizePlus;
            }
            else
            {
                this.WindowState = FormWindowState.Normal;
                btnMaximize.Image = Resources.MaximizeMinus;
            }

        }

        private void btnMinimize_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        #endregion

        #region Main Form Move/Resize/Closing

        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _lastClick = new Point(e.X, e.Y); //We'll need this for when the Form starts to move
            }

            Application.DoEvents();
        }

        private void MainForm_MouseMove(object sender, MouseEventArgs e)
        {
            //Application.DoEvents();
            if (e.Button == MouseButtons.Left)
            {
                //Move the Form the same difference the mouse cursor moved;
                this.Left  = e.X - _lastClick.X;
                this.Top  = e.Y - _lastClick.Y;
            }
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (!_screenSizeEdit)
            {
                tbHeight.Text = panelTransparent.Height.ToString();
                tbWidth.Text = panelTransparent.Width.ToString();
            }

            if (this.WindowState == FormWindowState.Normal)
                btnMaximize.Image = Resources.MaximizeMinus;

            AutoFitButtons();
        }

        /// <summary>
        /// Changes the way that the Record and Stop buttons are shown.
        /// </summary>
        private void AutoFitButtons()
        {
            if (panelTransparent.Width < 200)
            {
                if (btnRecordPause.ImageAlign == ContentAlignment.MiddleLeft)
                {
                    btnRecordPause.Text = String.Empty;
                    btnRecordPause.ImageAlign = ContentAlignment.MiddleCenter;
                    btnStop.Text = String.Empty;
                    btnStop.ImageAlign = ContentAlignment.MiddleCenter;
                }
            }
            else
            {
                if (btnRecordPause.ImageAlign == ContentAlignment.MiddleCenter)
                {
                    if (_stage == Stage.Recording)
                        btnRecordPause.Text = Resources.Pause;
                    else if (_stage == Stage.Paused)
                        btnRecordPause.Text = Resources.btnRecordPause_Continue;
                    else if (Settings.Default.snapshot)
                        btnRecordPause.Text = Resources.btnSnap;
                    else
                        btnRecordPause.Text = Resources.btnRecordPause_Record;

                    btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
                    btnStop.Text = Resources.Label_Stop;
                    btnStop.ImageAlign = ContentAlignment.MiddleLeft;
                }
            }
        }

        /// <summary>
        /// Before close, all settings must be saved and the timer must be disposed.
        /// </summary>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            #region Save Settings

            Settings.Default.maxFps = Convert.ToInt32(numMaxFps.Value);

            if (_stage == Stage.Editing)
            {
                Settings.Default.size = _lastSize;
            }
            else
            {
                Settings.Default.size = this.Size;
            }

            Settings.Default.Save();

            #endregion

            try
            {
                _actHook.Stop(); //Stop the keyboard watcher.
            }
            catch (Exception) { }

            if (_stage != (int)Stage.Stopped)
            {
                timerCapture.Stop();
                timerCapture.Dispose();

                timerCapWithCursor.Stop();
                timerCapWithCursor.Dispose();
            }

            _trayIcon.Dispose();
        }

        /// <summary>
        /// When the Text property changes, set the text to the labelTitle.
        /// </summary>
        private void Modern_TextChanged(object sender, EventArgs e)
        {
            labelTitle.Text = this.Text;
        }

        #endregion

        #region Bottom buttons

        private readonly Control _info = new Information();
        private readonly Control _appSettings = new AppSettings(false); //false = modern, true = legacy
        private readonly Control _gifSettings = new GifSettings();

        private void btnStop_Click(object sender, EventArgs e)
        {
            btnMaximize.Enabled = true;
            btnMinimize.Enabled = true;

            Stop();
        }

        private void btnRecordPause_Click(object sender, EventArgs e)
        {
            RecordPause(); //And start the pre-start tick
        }

        private void btnConfig_Click(object sender, EventArgs e)
        {
            Control ctrlParent = panelTransparent; //Defines the parent

            if (!btnConfig.Checked)
            {
                ctrlParent.Controls.Clear(); //Removes all pages

                this.TransparencyKey = Color.LimeGreen;
                panelTransparent.BackColor = Color.LimeGreen;
            }
            else
            {
                panelTransparent.BackColor = Color.FromArgb(239, 239, 242);

                panelTransparent.Visible = false;
                ctrlParent.Controls.Clear(); //Removes all pages
                ctrlParent.Controls.Add(_appSettings);
                _appSettings.Dock = DockStyle.Fill;
                panelTransparent.Visible = true;

                btnGifConfig.Checked = false;
                btnInfo.Checked = false;

                this.TransparencyKey = Color.Empty;
            }
        }

        private void btnGifConfig_Click(object sender, EventArgs e)
        {
            Control ctrlParent = panelTransparent; //Defines the parent

            if (_stage == Stage.Editing)
            {
                if (!btnInfo.Checked)
                {
                    panelEdit.Visible = !panelEdit.Visible;
                }
            }

            if (!btnGifConfig.Checked)
            {
                ctrlParent.Controls.Clear(); //Removes all pages

                this.TransparencyKey = Color.LimeGreen;
                panelTransparent.BackColor = Color.LimeGreen;
            }
            else
            {
                //Need this line, because there is a pictureBox with color, so if the user select the same color 
                //as this.TransparencyKey, the color won't be showed. This needs to be re-set after closing the gif config page.
                panelTransparent.BackColor = Color.FromArgb(239, 239, 242);

                panelTransparent.Visible = false;
                ctrlParent.Controls.Clear(); //Removes all pages
                ctrlParent.Controls.Add(_gifSettings);
                panelTransparent.Visible = true;
                _gifSettings.Dock = DockStyle.Fill;

                btnConfig.Checked = false;
                btnInfo.Checked = false;

                this.TransparencyKey = Color.Empty;
            }
        }

        private void btnInfo_Click(object sender, EventArgs e)
        {
            Control ctrlParent = panelTransparent; //Defines the parent

            if (_stage == Stage.Editing)
            {
                if (!btnGifConfig.Checked)
                {
                    panelEdit.Visible = !panelEdit.Visible;
                }
            }

            if (!btnInfo.Checked)
            {
                ctrlParent.Controls.Clear(); //Removes all pages

                this.TransparencyKey = Color.LimeGreen;
                panelTransparent.BackColor = Color.LimeGreen;

                GC.Collect();
            }
            else
            {
                panelTransparent.BackColor = Color.FromArgb(239, 239, 242);

                panelTransparent.Visible = false;
                ctrlParent.Controls.Clear(); //Removes all pages
                ctrlParent.Controls.Add(_info);
                panelTransparent.Visible = true;
                _info.Dock = DockStyle.Fill;

                btnConfig.Checked = false;
                btnGifConfig.Checked = false;

                GC.Collect();

                this.TransparencyKey = Color.Empty;
            }
        }

        private void btnPrevious_Click(object sender, EventArgs e)
        {
            StopPreview(true);

            if (trackBar.Value == 0)
            {
                trackBar.Value = trackBar.Maximum;
            }
            else
            {
                trackBar.Value = trackBar.Value - 1;
            }

            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);
            DelayUpdate();
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            StopPreview(true);

            if (trackBar.Value == trackBar.Maximum)
            {
                trackBar.Value = 0;
            }
            else
            {
                trackBar.Value = trackBar.Value   1;
            }

            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);
            DelayUpdate();
        }

        private void btnFreeDrawing_Click(object sender, EventArgs e)
        {
            StopPreview(true);
            FreeDrawing freeDraw = null;

            if (tvFrames.SelectedFrames().Count > 0)
            {
                freeDraw = new FreeDrawing(Resources.grid, ImageLayout.Tile, pictureBitmap.Image.Size);
            }
            else
            {
                freeDraw = new FreeDrawing(pictureBitmap.Image, ImageLayout.None, pictureBitmap.Image.Size);
            }

            if (freeDraw.ShowDialog() == DialogResult.OK)
            {
                this.Cursor = Cursors.AppStarting;

                ApplyActionToFrames("FreeDraw", ActionEnum.FreeDraw, 0F, freeDraw.ImagePainted);

                this.Cursor = Cursors.Default;
            }

            freeDraw.Dispose();
            GC.Collect();
        }

        #endregion

        #region Functions

        /// <summary>
        /// KeyHook event method. This fires when the user press a key.
        /// </summary>
        private void KeyHookTarget(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Settings.Default.startPauseKey)
            {
                btnRecordPause_Click(null, null);
            }
            else if (e.KeyCode == Settings.Default.stopKey)
            {
                btnStop_Click(null, null);
            }
        }

        /// <summary>
        /// MouseHook event method, not implemented.
        /// </summary>
        private void MouseHookTarget(object sender, MouseEventArgs keyEventArgs)
        {
            _recordClicked = keyEventArgs.Button == MouseButtons.Left;
        }

        /// <summary>
        /// Method that starts or pauses the recording
        /// </summary>
        private void RecordPause()
        {
            CreateTemp();

            if (_stage == Stage.Stopped) //if stoped, starts recording
            {
                #region To Record

                #region Remove all pages

                panelTransparent.BackColor = Color.LimeGreen;
                this.TransparencyKey = Color.LimeGreen;
                panelTransparent.Controls.Clear(); //Removes all pages from the top

                btnConfig.Checked = false;
                btnGifConfig.Checked = false;
                btnInfo.Checked = false;

                #endregion

                timerCapture.Interval =
                timerCaptureFull.Interval =
                timerCapWithCursor.Interval =
                timerCapWithCursorFull.Interval = 1000 / Convert.ToInt32(numMaxFps.Value);

                _listFrames = new List<string>(); //List that contains the path of all frames.
                _listCursor = new List<CursorInfo>(); //List that contains all the icon information

                if (Settings.Default.fullscreen)
                {
                    _sizeResolution = new Size(_sizeScreen);
                    _bt = new Bitmap(_sizeResolution.Width, _sizeResolution.Height);

                    HideWindowAndShowTrayIcon();
                }
                else
                {
                    _bt = new Bitmap(panelTransparent.Width, panelTransparent.Height);
                }
                _gr = Graphics.FromImage(_bt);

                tbHeight.Enabled = false;
                tbWidth.Enabled = false;
                numMaxFps.Enabled = false;
                this.TopMost = true;

                _addDel = AddFrames;

                if (Settings.Default.preStart) //if should show the pre start countdown
                {
                    this.Text = "Screen To Gif (2"   Resources.TitleSecondsToGo;
                    btnRecordPause.Enabled = false;

                    _actHook.OnMouseActivity  = MouseHookTarget;

                    _stage = Stage.PreStarting;
                    _preStartCount = 1; //Reset timer to 2 seconds, 1 second to trigger the timer so 1   1 = 2

                    timerPreStart.Start();
                }
                else
                {
                    btnRecordPause.Enabled = true;
                    btnMaximize.Enabled = false;

                    if (Settings.Default.showCursor) //if show cursor
                    {
                        #region If show cursor

                        if (!Settings.Default.snapshot)
                        {
                            #region Normal Recording

                            _actHook.OnMouseActivity  = MouseHookTarget;

                            if (!Settings.Default.fullscreen)
                            {
                                //To start recording right away, I call the tick before starting the timer,
                                //because the first tick will only occur after the delay.
                                btnMinimize.Enabled = false;

                                timerCapWithCursor_Tick(null, null);
                                timerCapWithCursor.Start();
                            }
                            else
                            {
                                this.MinimizeBox = false;
                                timerCapWithCursorFull_Tick(null, null);
                                timerCapWithCursorFull.Start();
                            }

                            _stage = Stage.Recording;
                            btnRecordPause.Text = Resources.Pause;
                            btnRecordPause.Image = Resources.Pause_17Blue;
                            btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;

                            AutoFitButtons();

                            #endregion
                        }
                        else
                        {
                            #region SnapShot Recording

                            //Set to snapshot mode, change the text of the record button to "Snap" and 
                            //every press of the button, takes a screenshot
                            _stage = Stage.Snapping;
                            btnRecordPause.Image = Properties.Resources.Snap16x;
                            btnRecordPause.Text = Resources.btnSnap;
                            btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
                            this.Text = "Screen To Gif - "   Resources.Con_SnapshotMode;

                            AutoFitButtons();

                            #endregion
                        }

                        #endregion
                    }
                    else
                    {
                        #region If not

                        if (!Settings.Default.snapshot)
                        {
                            #region Normal Recording

                            if (!Settings.Default.fullscreen)
                            {
                                btnMaximize.Enabled = false;
                                timerCapture_Tick(null, null);
                                timerCapture.Start();
                            }
                            else
                            {
                                timerCaptureFull_Tick(null, null);
                                timerCaptureFull.Start();
                            }

                            _stage = Stage.Recording;
                            btnRecordPause.Text = Resources.Pause;
                            btnRecordPause.Image = Resources.Pause_17Blue;
                            btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;

                            AutoFitButtons();

                            #endregion
                        }
                        else
                        {
                            #region SnapShot Recording

                            _stage = Stage.Snapping;
                            btnRecordPause.Image = Resources.Snap16x;
                            btnRecordPause.Text = Resources.btnSnap;
                            btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
                            this.Text = "Screen To Gif - "   Resources.Con_SnapshotMode;

                            AutoFitButtons();

                            #endregion
                        }

                        #endregion
                    }
                }

                this.Invalidate();

                #endregion
            }
            else if (_stage == Stage.Recording) //if recording, pauses
            {
                #region To Pause

                this.Text = Resources.TitlePaused;
                btnRecordPause.Text = Resources.btnRecordPause_Continue;
                btnRecordPause.Image = Resources.Record;
                btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
                _stage = Stage.Paused;

                AutoFitButtons();

                ModifyCaptureTimerAndChangeTrayIconVisibility(false);

                #endregion
            }
            else if (_stage == Stage.Paused) //if paused, starts recording again
            {
                #region To Record Again

                this.Text = Resources.TitleRecording;
                btnRecordPause.Text = Resources.Pause;
                btnRecordPause.Image = Resources.Pause_17Blue;
                btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
                _stage = Stage.Recording;

                AutoFitButtons();

                ModifyCaptureTimerAndChangeTrayIconVisibility(true);

                #endregion
            }
            else if (_stage == Stage.Snapping)
            {
                #region Take Screenshot (All possibles types)

                if (Settings.Default.showCursor)
                {
                    if (Settings.Default.fullscreen)
                    {
                        timerCapWithCursorFull_Tick(null, null);
                    }
                    else
                    {
                        timerCapWithCursor_Tick(null, null);
                    }
                }
                else
                {
                    if (Settings.Default.fullscreen)
                    {
                        timerCaptureFull_Tick(null, null);
                    }
                    else
                    {
                        timerCapture_Tick(null, null);
                    }
                }

                #endregion
            }
        }

        /// <summary>
        /// Stops the recording or stops the pre-start timer.
        /// </summary>
        private void Stop()
        {
            try
            {
                _frameCount = 0; //put this in other location

                timerCapture.Stop();
                timerCaptureFull.Stop();
                timerCapWithCursor.Stop();
                timerCapWithCursorFull.Stop();

                if (_stage != Stage.Stopped && _stage != Stage.PreStarting && _listFrames.Any()) //if not already stoped or pre starting, stops
                {
                    #region To Stop and Save

                    try
                    {
                        _actHook.Stop(); //Stops the hook.
                    }
                    catch (Exception ex) { }

                    _stopDel = StopAsync;
                    _stopDel.BeginInvoke(CallBackStop, null);

                    this.Cursor = Cursors.AppStarting;
                    panelBottom.Enabled = false;

                    return;

                    #endregion
                }
                else if ((_stage == Stage.PreStarting || _stage == Stage.Snapping) && !_listFrames.Any()) // if Pre-Starting or in Snapmode and no frames, stops.
                {
                    #region To Stop

                    timerPreStart.Stop();
                    _stage = Stage.Stopped;

                    //Enables the controls that are disabled while recording;
                    numMaxFps.Enabled = true;
                    btnRecordPause.Enabled = true;
                    tbHeight.Enabled = true;
                    tbWidth.Enabled = true;

                    btnMaximize.Enabled = true;
                    btnMinimize.Enabled = true;

                    btnRecordPause.Text = Resources.btnRecordPause_Record;
                    btnRecordPause.Image = Resources.Record;
                    btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
                    this.Text = Resources.TitleStoped;

                    AutoFitButtons();
                    this.Invalidate();

                    try
                    {
                        //Re-starts the keyboard hook.
                        _actHook.OnMouseActivity  = null;
                        _actHook.Start(false, true);
                    }
                    catch (Exception) { }

                    #endregion
                }
            }
            catch (NullReferenceException nll)
            {
                MessageBox.Show(nll.Message, "NullReference", MessageBoxButtons.OK, MessageBoxIcon.Error);
                LogWriter.Log(nll, "NullPointer in the Stop function");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                LogWriter.Log(ex, "Error in the Stop function");
            }
        }

        #region Async Stop

        private delegate void StopDelegate();

        private StopDelegate _stopDel;

        private void StopAsync()
        {
            #region Processing Page

            this.Invoke((Action)delegate //Needed because it's a cross thread call.
            {
                #region Verifies the minimum size to display the Processing page

                if (this.Size.Height < 220)
                {
                    this.Size = new Size(this.Size.Width, 220);
                }

                if (this.Size.Width < 400)
                {
                    this.Size = new Size(400, this.Size.Height);
                }

                #endregion

                this.TransparencyKey = Color.Empty;
                panelBottom.Visible = false;

                //Using this makes all Processing calls to change threads.
                panelTransparent.Controls.Add(Processing.Page = new Processing { Dock = DockStyle.Fill });
                Processing.Undefined("Finishing record...");
                Application.DoEvents();
            });

            #endregion

            #region If show cursor is true, merge all bitmaps

            //TODO: Make lighter
            if (Settings.Default.showCursor)
            {
                this.Invoke((Action)(() => Processing.Undefined("Merging Cursors...")));

                #region Merge Cursor and Bitmap

                int numImage = 0;

                foreach (var filename in _listFrames)
                {
                    try
                    {
                        var imageTemp = filename.From();

                        using (var graph = Graphics.FromImage(imageTemp))
                        {
                            #region Mouse Clicks

                            if (_listCursor[numImage].Clicked && Settings.Default.showMouseClick)
                            {
                                //Draws the ellipse first, to  get behind the cursor.
                                var rectEllipse = new Rectangle(
                                        _listCursor[numImage].Position.X - (_listCursor[numImage].IconImage.Width / 2),
                                        _listCursor[numImage].Position.Y - (_listCursor[numImage].IconImage.Height / 2),
                                        _listCursor[numImage].IconImage.Width - 10,
                                        _listCursor[numImage].IconImage.Height - 10);

                                graph.DrawEllipse(new Pen(new SolidBrush(Color.Yellow), 3), rectEllipse);
                            }

                            #endregion

                            var rect = new Rectangle(_listCursor[numImage].Position.X,
                                _listCursor[numImage].Position.Y, _listCursor[numImage].IconImage.Width,
                                _listCursor[numImage].IconImage.Height);

                            graph.DrawImage(_listCursor[numImage].IconImage, rect);
                            graph.Flush();

                            _listCursor[numImage].IconImage.Dispose();
                        }

                        imageTemp.Save(filename);
                        imageTemp.Dispose();
                    }
                    catch (Exception) { }

                    numImage  ;
                }

                #endregion
            }

            #endregion

            #region If fullscreen, resizes all the images, half of the size

            if (Settings.Default.fullscreen)
            {
                this.Invoke((Action)ShowWindowAndHideTrayIcon);

                this.Invoke((Action)(() => Processing.Undefined("Resizing Fullscreen Recording...")));

                var bitmapAux = _listFrames[0].From();

                ImageUtil.ResizeBitmap(_listFrames,
                    Convert.ToInt32(bitmapAux.Size.Width / 2),
                    Convert.ToInt32(bitmapAux.Size.Height / 2));

                bitmapAux.Dispose();
                GC.Collect();
            }

            #endregion

            #region Creates the Delay

            _listDelay = new List<int>();

            int delayGlobal;
            if (Settings.Default.snapshot)
            {
                delayGlobal = 600;
            }
            else
            {
                delayGlobal = 1000 / (int)numMaxFps.Value;
            }

            for (int i = 0; i < _listFrames.Count; i  )
            {
                _listDelay.Add(delayGlobal);
            }

            #endregion
        }

        private void CallBackStop(IAsyncResult r)
        {
            if (IsDisposed) return;

            _stopDel.EndInvoke(r);

            this.Invoke((Action)delegate
            {
                this.Cursor = Cursors.Default;
                panelBottom.Enabled = true;

                this.TransparencyKey = Color.LimeGreen;
                this.Invalidate();

                panelBottom.Visible = true;
                panelTransparent.Visible = true;

                #region If the user wants to edit the frames or not

                if (Settings.Default.allowEdit)
                {
                    //To return back to the last form size after the editor
                    _lastSize = this.Size;
                    _stage = Stage.Editing;
                    btnMaximize.Enabled = true;
                    btnMinimize.Enabled = true;
                    this.TopMost = false;

                    EditFrames();

                    ShowHideButtons(true);
                }
                else
                {
                    _lastSize = this.Size; //Not sure why this is here
                    Save();

                    Processing.Page.Dispose();
                }

                #endregion
            });
        }

        #endregion

        /// <summary>
        /// Prepares the recorded frames to be saved/edited
        /// </summary>
        private void Save()
        {
            this.Cursor = Cursors.WaitCursor;

            this.Size = _lastSize;
            this.Invalidate();
            Application.DoEvents();

            if (!Settings.Default.saveLocation) // to choose the location to save the gif
            {
                #region If Not Save Directly to the Desktop

                var sfd = new SaveFileDialog();
                sfd.Filter = "GIF file (*.gif)|*gif";
                sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                sfd.DefaultExt = "gif";

                this.Cursor = Cursors.Default;

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    _outputpath = sfd.FileName;

                    _workerThread = new Thread(DoWork);
                    _workerThread.IsBackground = true;
                    _workerThread.Name = "Gif Encoding";
                    _workerThread.Start();
                }
                else //if user don't want to save the gif
                {
                    FinishState();

                    btnRecordPause.Text = Resources.btnRecordPause_Record;
                    btnRecordPause.Image = Resources.Record;
                    btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
                    this.Text = Resources.TitleStoped;

                    AutoFitButtons();
                    this.Invalidate();

                    try
                    {
                        //_actHook.KeyDown  = KeyHookTarget;
                        _actHook.OnMouseActivity  = null;
                        _actHook.Start(false, true);
                    }
                    catch (Exception) { }

                    Directory.Delete(_pathTemp, true);
                }

                #endregion
            }
            else
            {
                #region Search For Filename

                bool searchForName = true;
                int numOfFile = 0;

                string path;

                //If there is no defined save location, saves in the desktop.
                if (String.IsNullOrEmpty(Settings.Default.folder))
                {
                    path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
                }
                else
                {
                    path = Settings.Default.folder;
                }

                this.Cursor = Cursors.Default;

                #region Ask if should encode

                DialogResult ask = MessageBox.Show(this, Resources.Msg_WantEncodeAnimation   path, "Screen To Gif",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                //Only saves the recording if the user wants to.
                if (ask != DialogResult.Yes)
                {
                    //If the user don't want to save the recording.
                    this.Text = Resources.TitleStoped;

                    #region Clear Variables

                    _listFrames.Clear();
                    _listDelay.Clear();

                    //These variables are only used in the editor.
                    if (_listFramesEdit != null)
                    {
                        _listFramesEdit.Clear();
                        _listFramesUndo.Clear();

                        _listDelayEdit.Clear();
                        _listDelayUndo.Clear();
                    }

                    GC.Collect();

                    #endregion

                    Directory.Delete(_pathTemp, true);
                    FinishState();

                    try
                    {
                        //Restart the keyhook.
                        //_actHook.KeyDown  = KeyHookTarget;
                        _actHook.Start(false, true);
                    }
                    catch (Exception) { }

                    return;
                }

                #endregion

                #region FileName

                while (searchForName)
                {
                    if (!File.Exists(path   "\\Animation "   numOfFile   ".gif"))
                    {
                        _outputpath = path   "\\Animation "   numOfFile   ".gif";
                        searchForName = false;
                    }
                    else
                    {
                        if (numOfFile > 999)
                        {
                            searchForName = false;
                            if (saveFileDialog.ShowDialog() == DialogResult.OK)
                            {
                                _outputpath = saveFileDialog.FileName;
                            }
                            else
                            {
                                _outputpath = "No filename for you.gif";
                            }
                        }
                        numOfFile  ;
                    }
                }

                #endregion

                #endregion

                _workerThread = new Thread(DoWork);
                _workerThread.IsBackground = true;
                _workerThread.Name = "Gif Encoding";
                _workerThread.Start();
            }

            //FinishState();
        }

        /// <summary>
        /// Cancels the editor phase, returning to the recording.
        /// </summary>
        private void Cancel()
        {
            FinishState();

            btnRecordPause.Text = Resources.btnRecordPause_Record;
            btnRecordPause.Image = Resources.Record;
            btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;
            this.Text = Resources.TitleStoped;

            AutoFitButtons();

            try
            {
                //_actHook.KeyDown  = KeyHookTarget;
                _actHook.OnMouseActivity  = null;
                _actHook.Start(true, true);
            }
            catch (Exception) { }

            Directory.Delete(_pathTemp, true);
        }

        /// <summary>
        /// Do all the work to set the controls to the finished state. (i.e. Finished encoding)
        /// </summary>
        private void FinishState()
        {
            this.Cursor = Cursors.Default;
            //panelTransparent.Visible = true;
            panelBottom.Visible = true;
            _stage = Stage.Stopped;
            this.MinimumSize = new Size(100, 100);
            this.Size = _lastSize;

            numMaxFps.Enabled = true;
            tbHeight.Enabled = true;
            tbWidth.Enabled = true;
            btnMaximize.Enabled = true;
            btnMinimize.Enabled = true;

            btnRecordPause.Text = Resources.btnRecordPause_Record;
            btnRecordPause.Image = Resources.Record;
            btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;

            AutoFitButtons();

            this.Invalidate(this.DisplayRectangle);
        }

        /// <summary>
        /// Thread method that encodes the list of frames.
        /// </summary>
        private void DoWork()
        {
            _stage = Stage.Encoding;
            int countList = _listFrames.Count;

            #region Show Processing

            this.Invoke((Action)delegate //Needed because it's a cross thread call.
            {
                #region Verifies the minimum size to display the Processing page

                if (this.Size.Height < 220)
                {
                    this.Size = new Size(this.Size.Width, 220);
                }

                if (this.Size.Width < 400)
                {
                    this.Size = new Size(400, this.Size.Height);
                }

                #endregion

                this.TransparencyKey = Color.Empty;
                panelBottom.Visible = false;

                //Control ctrlParent = panelTransparent;

                //The Modern one needs to use the panelTransparent.
                panelTransparent.Controls.Add(Processing.Page = new Processing { Dock = DockStyle.Fill });
                Processing.MaximumValue(countList);

                this.Text = "Screen To Gif - "   Resources.Label_Processing;

                //Only set the dispose of the Processing page, if needed.
                if (Settings.Default.showFinished)
                {
                    Processing.Page.Disposed  = processing_Disposed;
                }

                Processing.Status(0);
                Application.DoEvents();
            });

            #endregion

            if (Settings.Default.encodingCustom)
            {
                #region Ngif encoding

                int numImage = 0;

                #region Paint Unchanged Pixels

                var listToEncode = new List<FrameInfo>();

                if (Settings.Default.paintTransparent)
                {
                    this.Invoke((Action)(delegate
                    {
                        Processing.Defined(Resources.Label_AnalyzingUnchanged);
                        Processing.Status(0);
                    }));

                    listToEncode = ImageUtil.PaintTransparentAndCut(_listFrames, Settings.Default.transparentColor);
                }

                #endregion

                using (_encoder = new AnimatedGifEncoder())
                {
                    _encoder.Start(_outputpath);
                    _encoder.SetQuality(Settings.Default.quality);
                    _encoder.SetRepeat(Settings.Default.loop ? (Settings.Default.repeatForever ? 0 : Settings.Default.repeatCount) : -1); // 0 = Always, -1 once

                    this.Invoke((Action)(() => Processing.Defined(Resources.Label_Processing)));

                    #region For Each Frame

                    try
                    {
                        if (Settings.Default.paintTransparent)
                        {
                            #region With Transparency

                            _encoder.SetTransparent(Settings.Default.transparentColor);
                            _encoder.SetDispose(1); //Undraw Method, "Leave".

                            foreach (FrameInfo image in listToEncode)
                            {
                                var bitmapAux = new Bitmap(image.Image);

                                _encoder.SetDelay(_listDelay[numImage]);
                                _encoder.AddFrame(bitmapAux, image.PositionTopLeft.X, image.PositionTopLeft.Y);

                                bitmapAux.Dispose();
                                numImage  ;

                                this.BeginInvoke((Action)(() => Processing.Status(numImage)));
                            }

                            #endregion
                        }
                        else
                        {
                            #region Without

                            foreach (var image in _listFrames)
                            {
                                _encoder.SetDelay(_listDelay[numImage]);
                                _encoder.AddFrame(image.From());
                                numImage  ;

                                this.BeginInvoke((Action)(() => Processing.Status(numImage)));
                            }

                            #endregion
                        }
                    }
                    catch (Exception ex)
                    {
                        LogWriter.Log(ex, "Error in the Ngif encoding.");
                    }

                    #endregion
                }

                #region Clean Speciffic Variables

                listToEncode.Clear();
                listToEncode = null;

                #endregion

                #endregion
            }
            else
            {
                #region paint.NET encoding

                //BUG: The minimum amount of iterations is -1 (no repeat) or 3 (repeat number being 2), if you set repeat as 1, it will repeat 2 times, instead of just 1.
                //0 = Always, -1 = no repeat, n = repeat number (first shown   repeat number = total number of iterations)
                var repeat = (Settings.Default.loop ? (Settings.Default.repeatForever ? 0 : Settings.Default.repeatCount) : -1); // 0 = Always, -1 once

                using (var stream = new MemoryStream())
                {
                    using (var encoderNet = new GifEncoder(stream, null, null, repeat))
                    {
                        for (int i = 0; i < _listFrames.Count; i  )
                        {
                            var bitmapAux = new Bitmap(_listFrames[i]);
                            encoderNet.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(_listDelay[i]));
                            bitmapAux.Dispose();

                            this.BeginInvoke((Action)(() => Processing.Status(i)));
                        }
                    }

                    stream.Position = 0;

                    try
                    {
                        using (var fileStream = new FileStream(_outputpath, FileMode.Create, FileAccess.Write, FileShare.None,
                        Constants.BufferSize, false))
                        {
                            stream.WriteTo(fileStream);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogWriter.Log(ex, "Error while writing to disk");
                    }
                }

                #endregion
            }

            Directory.Delete(_pathTemp, true);

            #region Finish

            if (Settings.Default.showFinished)
            {
                this.Invoke((Action)delegate
                {
                    Processing.FinishedState(_outputpath, Resources.btnDone   "!");
                    this.Text = Resources.Title_EncodingDone;
                });

                //After the user hits "Close", the processing_Disposed is called. To set to the right stage.
            }
            else
            {
                this.Invoke((Action)delegate
                {
                    Processing.Page.Dispose();
                    this.Text = Resources.Title_EncodingDone;

                    this.Invalidate();
                    //Set again the transparency color
                    this.TransparencyKey = Color.LimeGreen;

                    FinishState();
                });

                try
                {
                    _actHook.Start(false, true); //start again the keyboard hook watcher
                }
                catch (Exception) { }
            }

            #endregion

            #region Memory Clearing

            _listFrames.Clear();
            _listDelay.Clear();

            if (_listFramesEdit != null)
            {
                _listFramesEdit.Clear();
                _listFramesUndo.Clear();

                _listDelayEdit.Clear();
                _listDelayUndo.Clear();
            }

            _listFrames = null;
            _listFramesEdit = null;
            _listFramesUndo = null;

            _listDelay = null;
            _listDelayEdit = null;
            _listDelayUndo = null;
            _encoder = null;

            GC.Collect(); //call the garbage colector to empty the memory

            #endregion
        }

        /// <summary>
        /// Resets the state of the program, after closing the "Finished" page.
        /// </summary>
        private void processing_Disposed(object sender, EventArgs e)
        {
            this.Text = Resources.TitleStoped;
            this.TransparencyKey = Color.LimeGreen;
            this.Invalidate();

            FinishState();

            try
            {
                _actHook.Start(false, true); //start again the keyboard hook watcher
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Insert text in the picture with specific font and color.
        /// </summary>
        /// <param name="text">Content to insert</param>
        public void InsertText(String text)
        {
            this.Cursor = Cursors.WaitCursor;

            ApplyActionToFrames("AddText", ActionEnum.AddText, 0, text);
            GC.Collect();

            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// Show or hide the panelBottom buttons.
        /// </summary>
        /// <param name="isEdit">True if Editor is openning</param>
        private void ShowHideButtons(bool isEdit)
        {
            #region Enable/Disable Buttons

            btnStop.Visible = !isEdit;
            btnRecordPause.Visible = !isEdit;
            tbHeight.Visible = !isEdit;
            lblX.Visible = !isEdit;
            tbWidth.Visible = !isEdit;
            lblSize.Visible = !isEdit;
            numMaxFps.Visible = !isEdit;
            lblFps.Visible = !isEdit;
            pbSeparator.Visible = !isEdit;
            btnConfig.Visible = !isEdit;

            //Inverted

            btnNext.Visible = isEdit;
            btnPrevious.Visible = isEdit;
            pbSeparator2.Visible = isEdit;
            btnFreeDrawing.Visible = isEdit;
            btnAddText.Visible = isEdit;
            lblDelay.Visible = isEdit;
            pictureBitmap.AllowDrop = isEdit;

            #endregion
        }

        /// <summary>
        /// Select frame by its System.Int32 index.
        /// </summary>
        /// <param name="index"> The value of index</param>
        /// <exception cref="IndexOutOfRangeException">
        /// When index value doesn't match any frame.
        /// </exception>
        private void SelectFrame(int index)
        {
            if (index >= 0 && index < _listFramesEdit.Count)
            {
                trackBar.Value = index;
                StopPreview(false);
            }
            else
                throw new IndexOutOfRangeException
                    ("Frame index: "   index   ", is out of range.");
        }

        /// <summary>
        /// Apply desired option on selected frame(s)
        /// </summary>
        /// <param name="actionLabel">
        /// Name of option used to display error message</param>
        /// <param name="actionType">
        /// Type of option referenced by an enumerator </param>
        /// <param name="pickerValue">
        /// Value of picker used for Pixelate and Blur filter</param>
        /// <exception cref="ArgumentException">
        /// Thrown when we have an invalid value of pickerValue</exception>
        /// /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown when we have an unknown option [optionType]</exception>
        /// <remarks> 
        /// The purpose of this function is that we can apply 
        /// almost every action/option to the selected frame(s), so if you want to use it
        /// please be sure that the desired action is added to [_actionEnum] Enum.
        /// </remarks>
        private void ApplyActionToFrames(string actionLabel, ActionEnum actionType, float pickerValue = 0, object param = null)
        {
            IList listIndexSelectedFrames;

            this.Invoke((Action)ResetUndoProp);

            int actualFrame = 0;

            this.Invoke((Action)delegate
            { actualFrame = trackBar.Value; });

            #region Apply Action to the Selected Frames

            if (tvFrames.IsFrameSelected(out listIndexSelectedFrames, actualFrame))
            {
                int removedCount = 0;
                bool overwrite = true;

                for (int i = 0; i < listIndexSelectedFrames.Count; i  )
                {
                    var frameIndex = (int)listIndexSelectedFrames[i];
                    var currentFrame = _listFramesEdit[frameIndex - removedCount].From();

                    #region Switch ActionType

                    switch (actionType)
                    {
                        case ActionEnum.Pixelate:
                            currentFrame = ImageUtil.Pixelate(currentFrame,
                                                        new Rectangle(0, 0, currentFrame.Width,
                                                        currentFrame.Height), Convert.ToInt32(pickerValue));
                            break;

                        case ActionEnum.Blur:
                            currentFrame = ImageUtil.Blur(currentFrame,
                                                        new Rectangle(0, 0, currentFrame.Width,
                                                        currentFrame.Height), Convert.ToInt32(pickerValue));
                            break;

                        case ActionEnum.Grayscale:
                            currentFrame =
                                        ImageUtil.Grayscale(currentFrame);
                            break;

                        case ActionEnum.Color:
                            currentFrame =
                                        ImageUtil.Colorize(currentFrame, (Color)param);
                            break;

                        case ActionEnum.Negative:
                            currentFrame =
                                        ImageUtil.Negative(currentFrame);
                            break;

                        case ActionEnum.Sepia:
                            currentFrame =
                                        ImageUtil.SepiaTone(currentFrame);
                            break;

                        case ActionEnum.Border:
                            currentFrame =
                                        ImageUtil.Border(currentFrame, pickerValue, (Color) param);
                            break;
                        case ActionEnum.Delete:
                            #region Delete

                            //index - 1 to delete the right frame.
                            _listFramesEdit.RemoveAt(frameIndex - removedCount);
                            _listDelayEdit.RemoveAt(frameIndex - removedCount);
                            tvFrames.Remove(1);
                            trackBar.Maximum = _listFramesEdit.Count - 1;
                            removedCount  ;
                            overwrite = false;

                            #endregion
                            break;

                        case ActionEnum.Speed:
                            #region Speed

                            int value = Convert.ToInt32(_listDelayEdit[frameIndex] * pickerValue);

                            if (value >= 10 && value <= 2500)
                            {
                                _listDelayEdit[frameIndex] = value;
                            }
                            else if (value < 10) //Minimum
                            {
                                _listDelayEdit[frameIndex] = 10;
                            }
                            else if (value > 2500) //Maximum
                            {
                                _listDelayEdit[frameIndex] = 2500;
                            }

                            #endregion
                            break;

                        case ActionEnum.Caption:

                            #region Caption

                            if (param == null) break;

                            currentFrame = _listFramesEdit[frameIndex].From();

                            using (Graphics imgGr = Graphics.FromImage(currentFrame))
                            {
                                var graphPath = new GraphicsPath();

                                var fSt = (int)Settings.Default.fontCaption.Style;
                                var fF = Settings.Default.fontCaption.FontFamily;

                                StringFormat sFr = StringFormat.GenericDefault;

                                #region Horizontal Alignment

                                if (Settings.Default.captionHorizontalAlign == StringAlignment.Near)
                                {
                                    sFr.Alignment = StringAlignment.Near;
                                }
                                else if (Settings.Default.captionHorizontalAlign == StringAlignment.Center)
                                {
                                    sFr.Alignment = StringAlignment.Center;
                                }
                                else
                                {
                                    sFr.Alignment = StringAlignment.Far;
                                }

                                #endregion

                                #region Vertical Alignment

                                if (Settings.Default.captionVerticalAlign == StringAlignment.Near)
                                {
                                    sFr.LineAlignment = StringAlignment.Near;
                                }
                                else if (Settings.Default.captionVerticalAlign == StringAlignment.Center)
                                {
                                    sFr.LineAlignment = StringAlignment.Center;
                                }
                                else
                                {
                                    sFr.LineAlignment = StringAlignment.Far;
                                }

                                #endregion

                                #region Draw the string using a specific sizing type. Percentage of the height or Points

                                if (Settings.Default.fontSizeAsPercentage)
                                {
                                    graphPath.AddString(param.ToString(), fF, fSt, (currentFrame.Height * Settings.Default.fontCaptionPercentage),
                                        new Rectangle(new Point(0, 0), currentFrame.Size), sFr);
                                }
                                else
                                {
                                    graphPath.AddString(param.ToString(), fF, fSt, Settings.Default.fontCaption.Size, new Rectangle(new Point(0, 0), currentFrame.Size), sFr);
                                }

                                #endregion

                                #region Draw the path to the surface

                                if (Settings.Default.captionUseOutline)
                                {
                                    imgGr.DrawPath(new Pen(Settings.Default.captionOutlineColor,
                                            Settings.Default.captionOutlineThick), graphPath);
                                }
                                else
                                {
                                    imgGr.DrawPath(new Pen(Color.Transparent), graphPath);
                                }

                                #endregion

                                #region Fill the path with a solid color or a hatch brush

                                if (Settings.Default.captionUseHatch)
                                {
                                    imgGr.FillPath(new HatchBrush(Settings.Default.captionHatch, Settings.Default.captionHatchColor,
                                            Settings.Default.fontCaptionColor), graphPath);
                                }
                                else
                                {
                                    imgGr.FillPath(new SolidBrush(Settings.Default.fontCaptionColor), graphPath);
                                }

                                #endregion
                            }

                            #endregion
                            break;
                        case ActionEnum.Export:

                            #region Export

                            if (param.Equals(ImageFormat.Png))
                            {
                                currentFrame.Save(actionLabel   " ("   frameIndex   ").png", ImageFormat.Png);
                            }
                            else
                            {
                                currentFrame.Save(actionLabel   " ("   frameIndex   ").jpg", ImageFormat.Jpeg);
                            }

                            #endregion
                            break;
                        case ActionEnum.AddText:

                            #region AddText

                            Brush textBrush = new SolidBrush(Settings.Default.forecolorInsertText);

                            using (var myGraphic = Graphics.FromImage(currentFrame))
                            {
                                //Define the rectangle size by taking in consideration [X] and [Y] of 
                                // [_pointTextPosition] so the text matches the Bitmap l
                                var rectangleSize = new Size(currentFrame.Width - _pointTextPosition.X,
                                    currentFrame.Height - _pointTextPosition.Y);

                                //Insert text in the specified Point
                                myGraphic.DrawString(param.ToString(), Settings.Default.fontInsertText, textBrush, new Rectangle(_pointTextPosition,
                                    rectangleSize), new StringFormat());
                            }

                            #endregion
                            break;
                        case ActionEnum.FlipRotate:

                            currentFrame.RotateFlip((RotateFlipType)param);

                            break;
                        case ActionEnum.FreeDraw:

                            #region FreeDraw

                            using (var graphics = Graphics.FromImage(currentFrame))
                            {
                                graphics.DrawImage((Image)param, 0, 0);
                            }

                            #endregion
                            break;
                        case ActionEnum.Progress:

                            #region Progress

                            using (Graphics imgGr = Graphics.FromImage(currentFrame))
                            {
                                float actualValue = frameIndex   1;
                                float maxValue = _listFramesEdit.Count;

                                Brush fillBrush = null;

                                #region Pen

                                float thickness = Settings.Default.progressThickAsPercentage ? Settings.Default.progressThickPercentage : Settings.Default.progressThickness;

                                if (Settings.Default.progressUseHatch)
                                {
                                    fillBrush = new HatchBrush(Settings.Default.progressHatch, Settings.Default.progressColor, Color.Transparent);
                                }
                                else
                                {
                                    fillBrush = new SolidBrush(Settings.Default.progressColor);
                                }

                                #endregion

                                #region Position

                                var rectangle = new Rectangle();

                                if (Settings.Default.progressPosition.Equals('T'))
                                {
                                    // 100 * 50 / 100
                                    float width = ((100 * actualValue) / maxValue) / 100;
                                    rectangle = new Rectangle(0, 0, (int)(currentFrame.Size.Width * width), (int)Settings.Default.progressThickness);
                                }
                                else if (Settings.Default.progressPosition.Equals('B'))
                                {
                                    float width = ((100 * actualValue) / maxValue) / 100;
                                    rectangle = new Rectangle(0, (int)(currentFrame.Size.Height - Settings.Default.progressThickness), (int)(currentFrame.Size.Width * width), (int)Settings.Default.progressThickness);
                                }
                                else if (Settings.Default.progressPosition.Equals('L'))
                                {
                                    float height = ((100 * actualValue) / maxValue) / 100;
                                    rectangle = new Rectangle(0, 0, (int)Settings.Default.progressThickness, (int)(currentFrame.Size.Height * height));
                                }
                                else
                                {
                                    float height = ((100 * actualValue) / maxValue) / 100;
                                    rectangle = new Rectangle((int)(currentFrame.Size.Width - Settings.Default.progressThickness), 0, (int)Settings.Default.progressThickness, (int)(currentFrame.Size.Height * height));
                                }

                                imgGr.FillRectangle(fillBrush, rectangle);

                                #endregion
                            }

                            #endregion

                            break;
                    }

                    #endregion

                    if (overwrite)
                    {
                        File.Delete(_listFramesEdit[frameIndex - removedCount]);

                        currentFrame.Save(_listFramesEdit[frameIndex - removedCount]);
                        currentFrame.Dispose();
                    }

                    GC.Collect(1);
                }

                this.Invoke((Action)delegate
                {
                    trackBar_ValueChanged(null, null);

                    //Highlight the node.
                    tvFrames.Focus();
                    tvFrames.SelectedNode =
                        tvFrames.Nodes[_parentNodeLabel].Nodes[trackBar.Value];
                });
            }

            #endregion
        }

        private void AddPictures(string fileName)
        {
            try
            {
                Cursor = Cursors.WaitCursor;

                if (_listFramesEdit.Any())
                {
                    ResetUndoProp();
                }

                Size imageSize = _listFramesEdit.Count == 0 ? new Size(0, 0) : _listFramesEdit[0].From().Size;


                // Insert the frame(s) and set the last delay used.
                List<Bitmap> bitmapsList = ImageUtil.GetBitmapsFromFile(fileName, _listFramesEdit.Count, imageSize);

                bitmapsList.Reverse();

                int frame = 0;
                foreach (Bitmap item in bitmapsList)
                {
                    string endName = String.Format("{0}{1}I{2}.bmp", _pathTemp, frame, DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss"));

                    item.Save(endName, ImageFormat.Bmp);
                    _listFramesEdit.Insert(trackBar.Value, endName);
                    _listDelayEdit.Insert(trackBar.Value, _delay); //TODO: Get the delay.

                    frame  ;
                }

                tvFrames.Add(bitmapsList.Count);

                bitmapsList.Clear();
                bitmapsList = null;

                GC.Collect();
            }
            catch (Exception ex)
            {
                LogWriter.Log(ex, "Error importing image");

                var errorViewer = new ExceptionViewer(ex);
                errorViewer.ShowDialog();
            }
            finally
            {
                // Update the content for user
                trackBar.Maximum = _listFramesEdit.Count - 1;
                pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
                this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);
                this.Cursor = Cursors.Default;

                DelayUpdate();
            }
        }

        /// <summary>
        /// Creates the temp folder that holds all frames.
        /// </summary>
        private void CreateTemp()
        {
            #region Temp Folder

            if (!Directory.Exists(_pathTemp))
            {
                Directory.CreateDirectory(_pathTemp);
                Directory.CreateDirectory(_pathTemp   "Undo");
                Directory.CreateDirectory(_pathTemp   "Edit");
            }

            #endregion
        }

        #region NotifyIcon Methods

        private void ModifyCaptureTimerAndChangeTrayIconVisibility(bool isTimerAndTrayIconEnabled)
        {
            if (Settings.Default.fullscreen)
            {
                if (isTimerAndTrayIconEnabled)
                {
                    HideWindowAndShowTrayIcon();
                }
                else
                {
                    ShowWindowAndHideTrayIcon();
                }
            }

            ModifyCaptureTimer(isTimerAndTrayIconEnabled);
        }

        private void ModifyCaptureTimer(bool isEnabled)
        {
            if (Settings.Default.fullscreen)
            {
                if (Settings.Default.showCursor)
                {
                    timerCapWithCursorFull.Enabled = isEnabled;
                }
                else
                {
                    timerCaptureFull.Enabled = isEnabled;
                }
            }
            else
            {
                if (Settings.Default.showCursor)
                {
                    timerCapWithCursor.Enabled = isEnabled;
                }
                else
                {
                    timerCapture.Enabled = isEnabled;
                }
            }
        }

        private void HideWindowAndShowTrayIcon()
        {
            _trayIcon.ShowTrayIcon();
            this.Visible = false;
        }

        private void ShowWindowAndHideTrayIcon()
        {
            _trayIcon.HideTrayIcon();
            this.Visible = true;
        }

        private void NotifyIconClicked(object sender, EventArgs eventArgs)
        {
            this.Visible = true;
        }

        #endregion

        #endregion

        #region Record Async

        /// <summary>
        /// Saves the Bitmap to the disk and adds the filename in the list of frames.
        /// </summary>
        /// <param name="filename">The final filename of the Bitmap.</param>
        /// <param name="bitmap">The Bitmap to save in the disk.</param>
        public delegate void AddFrame(string filename, Bitmap bitmap);

        private AddFrame _addDel;

        private void AddFrames(string filename, Bitmap bitmap)
        {
            _listFrames.Add(filename);
            bitmap.Save(filename);
            bitmap.Dispose();
        }

        private void CallBack(IAsyncResult r)
        {
            if (this.IsDisposed) return;

            _addDel.EndInvoke(r);
        }

        #endregion

        #region Timers

        /// <summary>
        /// Timer used after clicking in Record, to give the user a shor time to prepare recording
        /// </summary>
        private void timerPreStart_Tick(object sender, EventArgs e)
        {
            if (_preStartCount >= 1)
            {
                this.Text = String.Format("Screen To Gif ({0}", _preStartCount   Resources.TitleSecondsToGo);
                _preStartCount--;
            }
            else
            {
                timerPreStart.Stop();
                btnRecordPause.Enabled = true;
                this.Invalidate(); //To redraw the form, activating OnPaint again

                if (Settings.Default.showCursor)
                {
                    #region If Show Cursor

                    if (!con_Snapshot.Checked)
                    {
                        if (!Settings.Default.fullscreen)
                        {
                            btnMinimize.Enabled = false;
                            timerCapWithCursor.Start(); //Record with the cursor
                        }
                        else
                        {
                            timerCapWithCursorFull.Start();
                        }

                        _stage = Stage.Recording;
                        btnMaximize.Enabled = false;
                        btnRecordPause.Text = Resources.Pause;
                        btnRecordPause.Image = Resources.Pause_17Blue;
                        btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;

                        AutoFitButtons();
                    }
                    else
                    {
                        _stage = Stage.Snapping;
                        btnRecordPause.Text = Resources.btnSnap;
                        this.Text = String.Format("Screen To Gif - {0}", Resources.Con_SnapshotMode);
                        btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;

                        AutoFitButtons();
                    }

                    #endregion
                }
                else
                {
                    #region If Not

                    if (!con_Snapshot.Checked)
                    {
                        if (!Settings.Default.fullscreen)
                        {
                            btnMinimize.Enabled = false;
                            timerCapture.Start();
                        }
                        else
                        {
                            timerCaptureFull.Start();
                        }

                        _stage = Stage.Recording;
                        btnMaximize.Enabled = false;
                        btnRecordPause.Text = Resources.Pause;
                        btnRecordPause.Image = Resources.Pause_17Blue;
                        btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;

                        AutoFitButtons();
                    }
                    else
                    {
                        _stage = Stage.Snapping;
                        btnRecordPause.Text = Resources.btnSnap;
                        this.Text = String.Format("Screen To Gif - {0}", Resources.Con_SnapshotMode);
                        btnRecordPause.ImageAlign = ContentAlignment.MiddleLeft;

                        AutoFitButtons();
                    }

                    #endregion
                }
            }
        }

        #region FullScreen

        /// <summary>
        /// Takes a screenshot of the entire area and add to the list.
        /// </summary>
        private void timerCaptureFull_Tick(object sender, EventArgs e)
        {
            //Take a screenshot of the entire.
            _gr.CopyFromScreen(0, 0, 0, 0, _sizeResolution, CopyPixelOperation.SourceCopy);
            //Add the bitmap to a list

            _addDel.BeginInvoke(String.Format("{0}{1}.bmp", _pathTemp, _frameCount), new Bitmap(_bt), CallBack, null);

            this.Invoke((Action)(() => this.Text = String.Format("Screen To Gif • {0}", _frameCount)));

            _frameCount  ;
        }

        /// <summary>
        /// Takes a screenshot of th entire area and add to the list, plus add to the list the position and icon of the cursor.
        /// </summary>
        private void timerCapWithCursorFull_Tick(object sender, EventArgs e)
        {
            _cursorInfo = new CursorInfo
            {
                IconImage = _capture.CaptureImageCursor(ref _posCursor),
                Position = panelTransparent.PointToClient(_posCursor),
                Clicked = _recordClicked,
            };


            //saves to list the actual icon and position of the cursor
            _listCursor.Add(_cursorInfo);

            //Take a screenshot of the area.
            _gr.CopyFromScreen(0, 0, 0, 0, _sizeResolution, CopyPixelOperation.SourceCopy);
            //Add the bitmap to a list

            _addDel.BeginInvoke(String.Format("{0}{1}.bmp", _pathTemp, _frameCount), new Bitmap(_bt), CallBack, null);

            this.Invoke((Action)(() => this.Text = String.Format("Screen To Gif • {0}", _frameCount)));

            _frameCount  ;
            GC.Collect(1);
        }

        #endregion

        #region Area

        /// <summary>
        /// Takes a screenshot of desired area and add to the list.
        /// </summary>
        private void timerCapture_Tick(object sender, EventArgs e)
        {
            //Get the actual position of the form.
            var lefttop = new Point(this.Location.X   panelTransparent.Location.X, this.Location.Y   panelTransparent.Location.Y);
            //Take a screenshot of the area.
            _gr.CopyFromScreen(lefttop.X, lefttop.Y, 0, 0, panelTransparent.Bounds.Size, CopyPixelOperation.SourceCopy);
            //Add the bitmap to a list
            _addDel.BeginInvoke(String.Format("{0}{1}.bmp", _pathTemp, _frameCount), new Bitmap(_bt), CallBack, null);

            this.Invoke((Action)(() => this.Text = String.Format("Screen To Gif • {0}", _frameCount)));

            _frameCount  ;
            GC.Collect(1);
        }

        /// <summary>
        /// Takes a screenshot of desired area and add to the list, plus add to the list the position and icon of the cursor.
        /// </summary>
        private void timerCapWithCursor_Tick(object sender, EventArgs e)
        {
            _cursorInfo = new CursorInfo
            {
                IconImage = _capture.CaptureImageCursor(ref _posCursor),
                Position = panelTransparent.PointToClient(_posCursor),
                Clicked = _recordClicked,
            };

            //Get actual icon of the cursor
            _listCursor.Add(_cursorInfo);
            //Get the actual position of the form.
            Point lefttop = new Point(this.Location.X   panelTransparent.Location.X, this.Location.Y   panelTransparent.Location.Y);
            //Take a screenshot of the area.
            _gr.CopyFromScreen(lefttop.X, lefttop.Y, 0, 0, panelTransparent.Bounds.Size, CopyPixelOperation.SourceCopy);
            //Add the bitmap to a list

            _addDel.BeginInvoke(String.Format("{0}{1}.bmp", _pathTemp, _frameCount), new Bitmap(_bt), CallBack, null);

            this.Invoke((Action)(() => this.Text = String.Format("Screen To Gif • {0}", _frameCount)));

            _frameCount  ;
            GC.Collect(1);
        }

        #endregion

        #endregion

        #region TextBox Size

        /// <summary>
        /// Prevents keys!=numbers
        /// </summary>
        private void tbSize_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (char.IsLetter(e.KeyChar) ||
                char.IsSymbol(e.KeyChar) ||
                char.IsWhiteSpace(e.KeyChar) ||
                char.IsPunctuation(e.KeyChar))
                e.Handled = true;
        }

        /// <summary>
        /// After leaving the textBox, updates the size of the form with what is typed
        /// </summary>
        private void tbSize_Leave(object sender, EventArgs e)
        {
            Application.DoEvents();
            _screenSizeEdit = true;
            int heightTb = Convert.ToInt32(tbHeight.Text);
            int widthTb = Convert.ToInt32(tbWidth.Text);

            int offsetY = this.Height - panelTransparent.Height;
            int offsetX = this.Width - panelTransparent.Width;

            heightTb  = offsetY;
            widthTb  = offsetX;

            #region Checks if size is smaller than screen size

            if (heightTb > _sizeScreen.Y)
            {
                heightTb = _sizeScreen.Y;
                tbHeight.Text = _sizeScreen.Y.ToString();
            }

            if (widthTb > _sizeScreen.X)
            {
                widthTb = _sizeScreen.X;
                tbWidth.Text = _sizeScreen.X.ToString();
            }

            #endregion

            this.Size = new Size(widthTb, heightTb);

            _screenSizeEdit = false;
        }

        /// <summary>
        /// User press Enter, updates the form size.
        /// </summary>
        private void tbSize_KeyDown(object sender, KeyEventArgs e)
        {
            Application.DoEvents();
            if (e.KeyData == Keys.Enter)
            {
                _screenSizeEdit = true;
                int heightTb = Convert.ToInt32(tbHeight.Text);
                int widthTb = Convert.ToInt32(tbWidth.Text);

                int offsetY = this.Height - panelTransparent.Height;
                int offsetX = this.Width - panelTransparent.Width;

                heightTb  = offsetY;
                widthTb  = offsetX;

                #region Checks if size is smaller than screen size

                if (heightTb > _sizeScreen.Y)
                {
                    heightTb = _sizeScreen.Y;
                    tbHeight.Text = _sizeScreen.Y.ToString();
                }

                if (widthTb > _sizeScreen.X)
                {
                    widthTb = _sizeScreen.X;
                    tbWidth.Text = _sizeScreen.X.ToString();
                }

                #endregion

                this.Size = new Size(widthTb, heightTb);

                _screenSizeEdit = false;
            }
        }

        #endregion

        #region Frame Edit Stuff

        /// <summary>
        /// Resizes the form to hold the image
        /// </summary>
        private void ResizeFormToImage()
        {
            #region Window size

            using (var bitmap = _listFramesEdit[0].From())
            {
                var sizeBitmap = new Size(bitmap.Size.Width   100, bitmap.Size.Height   160);

                //Only resize if the form is smaller than the image.
                if (this.Size.Width >= sizeBitmap.Width && this.Size.Height >= sizeBitmap.Height)
                {
                    bitmap.Dispose();
                    return;
                }

                if (!(sizeBitmap.Width > 700)) //700 minimum width
                {
                    sizeBitmap.Width = 700;
                }

                if (!(sizeBitmap.Height > 300)) //300 minimum height
                {
                    sizeBitmap.Height = 300;
                }

                this.Size = sizeBitmap;
            }

            #endregion
        }

        /// <summary>
        /// Reset and Undo properties
        /// </summary>
        private void ResetUndoProp()
        {
            #region Reset and Undo Properties

            btnUndo.Enabled = true;
            btnReset.Enabled = true;

            _listFramesUndo.Clear();

            foreach (var name in _listFramesEdit)
            {
                _listFramesUndo.Add(name.Replace("Edit", "Undo"));
                File.Copy(name, name.Replace("Edit", "Undo"), true);
            }

            _listDelayUndo.Clear();
            _listDelayUndo = new List<int>(_listDelayEdit);

            #endregion
        }

        /// <summary>
        /// Constructor of the Frame Edit Page.
        /// </summary>
        private void EditFrames()
        {
            this.Cursor = Cursors.WaitCursor;

            _listFramesEdit = new List<string>();
            _listFramesUndo = new List<string>();

            int frameActual = 0;
            foreach (var frame in _listFrames)
            {
                File.Copy(frame, _pathTemp   String.Format(@"Edit\{0}.bmp", frameActual));
                _listFramesEdit.Add(_pathTemp   String.Format(@"Edit\{0}.bmp", frameActual));

                File.Copy(frame, _pathTemp   String.Format(@"Undo\{0}.bmp", frameActual));
                _listFramesUndo.Add(_pathTemp   String.Format(@"Undo\{0}.bmp", frameActual));

                frameActual  ;
            }

            //Copies the listDelay to all the lists
            _listDelayEdit = new List<int>(_listDelay);
            _listDelayUndo = new List<int>(_listDelay);

            Application.DoEvents();

            panelEdit.Visible = true;

            trackBar.Value = 0;
            trackBar.Maximum = _listFramesEdit.Count - 1;

            this.MinimumSize = new Size(100, 100);
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

            ResizeFormToImage(); //Resizes the form to hold the image.

            pictureBitmap.Image = _listFramesEdit.First().From();

            #region Preview Config.

            _timerPlayPreview.Interval = _listDelayEdit[trackBar.Value];

            #endregion

            #region Delay Properties

            //Sets the initial location
            _lastPosition = lblDelay.Location;
            _delay = _listDelayEdit[0];
            lblDelay.Text = _delay   " ms";

            #endregion

            MainSplit.Panel1Collapsed = true;

            #region Add List of frames to the TreeView

            if (_listFramesEdit != null)
            {
                tvFrames.UpdateListFrames(_listFramesEdit.Count, _parentNodeLabel);
            }

            Application.DoEvents();

            #endregion

            if (String.IsNullOrEmpty(ArgumentUtil.FileName))
            {
                this.Invoke((Action)(() => Processing.Page.Dispose()));
            }

            GC.Collect(3);

            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// Accepts all the alterations and hides this page.
        /// </summary>
        private void btnDone_Click(object sender, EventArgs e)
        {
            StopPreview();
            _listFrames.Clear();

            foreach (var name in _listFramesEdit)
            {
                _listFrames.Add(name.Replace(@"\Edit", ""));
                File.Copy(name, name.Replace(@"\Edit", ""), true);
            }

            _listDelay = new List<int>(_listDelayEdit);

            pictureBitmap.Cursor = Cursors.Default;
            btnHideListFrames_Click(null, null);
            panelEdit.Visible = false;
            ShowHideButtons(false);

            this.Text = Resources.Title_Edit_PromptToSave;
            Save();

            GC.Collect();
        }

        /// <summary>
        /// Ignores all the alterations and hides this page.
        /// </summary>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            StopPreview();

            pictureBitmap.Cursor = Cursors.Default;
            btnHideListFrames_Click(null, null);
            pictureBitmap.Image = null;
            panelEdit.Visible = false;
            ShowHideButtons(false);

            Cancel();

            GC.Collect();
        }

        /// <summary>
        /// When the user slides the trackBar, the image updates.
        /// </summary>
        private void trackBar_ValueChanged(object sender, EventArgs e)
        {
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);
            pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();

            GC.Collect(2);

            DelayUpdate();
        }

        private void btnDeleteFrame_Click(object sender, EventArgs e)
        {
            StopPreview();

            if (_listFramesEdit.Count > 1) //If more than 1 image in the list
            {
                ResetUndoProp();

                File.Delete(_listFramesEdit[trackBar.Value]);
                _listFramesEdit.RemoveAt(trackBar.Value); //delete the selected frame
                _listDelayEdit.RemoveAt(trackBar.Value); //and delay.
                tvFrames.Nodes[0].Nodes.RemoveAt(trackBar.Value);

                trackBar.Maximum = _listFramesEdit.Count - 1;
                pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();

                this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

                DelayUpdate();
                GC.Collect();
            }
            else
            {
                MessageBox.Show(Resources.MsgBox_Message_CantDelete, Resources.MsgBox_Title_CantDelete, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void btnUndo_Click(object sender, EventArgs e)
        {
            StopPreview();

            int countDiff = _listFramesEdit.Count - _listFramesUndo.Count;

            #region Revert Alterations - This one is the oposite of ResetUndoProp()

            //Resets the list to a previous state
            _listFramesEdit.Clear();
            //_listFramesEdit = new List<string>(_listFramesUndo);

            foreach (var name in _listFramesUndo)
            {
                _listFramesEdit.Add(name.Replace("Undo", "Edit"));
                File.Copy(name, name.Replace("Undo", "Edit"), true);
            }

            //Resets the list to a previous state
            _listDelayEdit.Clear();
            _listDelayEdit = new List<int>(_listDelayUndo);

            #endregion

            trackBar.Maximum = _listFramesEdit.Count - 1;
            pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

            btnUndo.Enabled = false;

            ResizeFormToImage();

            #region Update TreeView

            if (countDiff > 0)
            {
                //If Undo is smaller, it means that we need to remove
                tvFrames.Remove(countDiff);
            }
            else if (countDiff < 0)
            {
                //If Undo is greater, it means that we need to add
                tvFrames.Add(Math.Abs(countDiff));
            }

            #endregion

            DelayUpdate();
            GC.Collect();
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            StopPreview(false);
            btnUndo.Enabled = true;

            int countDiff = _listFramesEdit.Count - _listFrames.Count;

            #region Resets the list of frames

            _listFramesUndo.Clear();

            foreach (var name in _listFramesEdit)
            {
                _listFramesUndo.Add(name.Replace("Edit", "Undo"));
                File.Copy(name, name.Replace("Edit", "Undo"), true);
            }

            _listFramesEdit.Clear();

            int frameActual = 0;
            foreach (var frame in _listFrames)
            {
                File.Copy(frame, _pathTemp   String.Format(@"Edit\{0}.bmp", frameActual), true);
                _listFramesEdit.Add(_pathTemp   String.Format(@"Edit\{0}.bmp", frameActual));

                frameActual  ;
            }

            #endregion

            #region Resets the list of delays

            _listDelayUndo.Clear();
            _listDelayUndo = new List<int>(_listDelayEdit);

            _listDelayEdit.Clear();
            _listDelayEdit = new List<int>(_listDelay);

            #endregion

            trackBar.Maximum = _listFramesEdit.Count - 1;
            pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

            ResizeFormToImage();

            #region Update TreeView

            if (countDiff > 0)
            {
                //If Undo is smaller, it means that we need to remove
                tvFrames.Remove(countDiff);
            }
            else if (countDiff < 0)
            {
                //If Undo is greater, it means that we need to add
                tvFrames.Add(Math.Abs(countDiff));
            }

            #endregion

            DelayUpdate();
            GC.Collect();
        }

        /// <summary>
        /// Opens the filter context menu.
        /// </summary>
        private void btnFilters_Click(object sender, EventArgs e)
        {
            StopPreview();
            contextSmall.Show(btnFilters, 0, btnFilters.Height);
        }

        /// <summary>
        /// Opens the options context menu.
        /// </summary>
        private void btnOptions_Click(object sender, EventArgs e)
        {
            contextMenu.Show(btnOptions, 0, btnOptions.Height);
        }

        #region Context Menu Itens

        private void con_addText_Click(object sender, EventArgs e)
        {
            if (pictureBitmap.Cursor == Cursors.Cross)
            {
                pictureBitmap.Cursor = Cursors.Default;
                return;
            }

            StopPreview(true);
            ResetUndoProp();

            var tip = new ToolTip();
            tip.Show(Resources.Tooltip_SelectPoint,
                this, PointToClient(MousePosition), 5 * 1000);

            //Displays a Cross cursor, to indicate a point selection
            pictureBitmap.Cursor = Cursors.Cross;
        }

        private void con_addCaption_Click(object sender, EventArgs e)
        {
            if (!con_tbCaption.Text.Equals(String.Empty))
            {
                this.Cursor = Cursors.WaitCursor;

                ApplyActionToFrames("Caption", ActionEnum.Caption, 0, con_tbCaption.Text);

                this.Cursor = Cursors.Default;
            }
        }

        private void con_CaptionOptions_Click(object sender, EventArgs e)
        {
            var bitmapAux = new Bitmap(_listFramesEdit[trackBar.Value]);

            var capOptions = new CaptionOptions(bitmapAux.Height);
            capOptions.ShowDialog();

            bitmapAux.Dispose();
            capOptions.Dispose();
            GC.Collect();
        }

        private void con_deleteAfter_Click(object sender, EventArgs e)
        {
            if (_listFramesEdit.Count <= 1) return;

            ResetUndoProp();

            int countList = _listFramesEdit.Count - 1; //So we have a fixed value
            int removeCount = 0;

            for (int i = countList; i > trackBar.Value; i--) //from the end to the middle
            {
                File.Delete(_listFramesEdit[i]);
                _listFramesEdit.RemoveAt(i);
                _listDelayEdit.RemoveAt(i);
                removeCount  ;
            }

            trackBar.Maximum = _listFramesEdit.Count - 1;
            trackBar.Value = _listFramesEdit.Count - 1;

            pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

            tvFrames.Remove(removeCount);
            DelayUpdate();
            GC.Collect();
        }

        private void con_deleteBefore_Click(object sender, EventArgs e)
        {
            if (_listFramesEdit.Count <= 1) return;

            ResetUndoProp();

            int removeCount = 0;

            for (int i = trackBar.Value - 1; i >= 0; i--)
            {
                File.Delete(_listFramesEdit[i]);
                _listFramesEdit.RemoveAt(i); // I should use removeAt everywhere
                _listDelayEdit.RemoveAt(i);
                removeCount  ;
            }

            trackBar.Maximum = _listFramesEdit.Count - 1;
            trackBar.Value = 0;

            pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

            tvFrames.Remove(removeCount);
            DelayUpdate();
            GC.Collect();
        }

        private void con_exportFrame_Click(object sender, EventArgs e)
        {
            StopPreview();

            var sfdExport = new SaveFileDialog();
            sfdExport.DefaultExt = "png";
            sfdExport.Filter = "JPG Image (*.jpg)|*.jpg| PNG Image (*.png)|*.png";
            sfdExport.FileName = Resources.Msg_Frame.TrimEnd();//   trackBar.Value;

            if (sfdExport.ShowDialog() == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;

                if (sfdExport.FileName.EndsWith(".png"))
                {
                    ApplyActionToFrames(sfdExport.FileName.Replace(".jpg", "").Replace(".png", ""), ActionEnum.Export, 0F, ImageFormat.Png);
                }
                else
                {
                    ApplyActionToFrames(sfdExport.FileName.Replace(".jpg", "").Replace(".png", ""), ActionEnum.Export, 0F, ImageFormat.Jpeg);
                }

                GC.Collect();

                this.Cursor = Cursors.Default;
            }

            sfdExport.Dispose();
            GC.Collect();
        }

        private void con_showGrid_CheckedChanged(object sender, EventArgs e)
        {
            //Change the background and the setting.
            RightSplit.Panel2.BackgroundImage =
                (Settings.Default.ShowGrid = con_showGrid.Checked) ? //If
                Resources.grid : null; //True-False
        }

        private void con_resizeAllFrames_Click(object sender, EventArgs e)
        {
            Bitmap bitmapResize = _listFramesEdit[trackBar.Value].From();

            var resize = new Resize(bitmapResize);

            if (resize.ShowDialog(this) == DialogResult.OK)
            {
                ResetUndoProp();

                Size resized = resize.GetSize();

                ImageUtil.ResizeBitmap(_listFramesEdit, resized.Width, resized.Height);

                pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();

                ResizeFormToImage();
            }

            resize.Dispose();
            GC.Collect();
        }

        private void con_cropAll_Click(object sender, EventArgs e)
        {
            var crop = new Crop(_listFramesEdit[trackBar.Value].From());

            if (crop.ShowDialog(this) == DialogResult.OK)
            {
                ResetUndoProp();

                ImageUtil.Crop(_listFramesEdit, crop.Rectangle);
                pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();

                ResizeFormToImage();
            }

            crop.Dispose();
            GC.Collect();
        }

        private void con_flipRotate_Click(object sender, EventArgs e)
        {
            var context = sender as ToolStripMenuItem;

            if (context == null) return;

            this.Cursor = Cursors.WaitCursor;
            ResetUndoProp();

            switch (context.AccessibleDescription)
            {
                case "Vertical":
                    ApplyActionToFrames("FlipRotate", ActionEnum.FlipRotate, 0, RotateFlipType.RotateNoneFlipY);
                    break;
                case "Horizontal":
                    ApplyActionToFrames("FlipRotate", ActionEnum.FlipRotate, 0, RotateFlipType.RotateNoneFlipX);
                    break;
                case "90C":
                    tvFrames.CheckAll();
                    ApplyActionToFrames("FlipRotate", ActionEnum.FlipRotate, 0, RotateFlipType.Rotate90FlipNone);
                    break;
                case "90CC":
                    tvFrames.CheckAll();
                    ApplyActionToFrames("FlipRotate", ActionEnum.FlipRotate, 0, RotateFlipType.Rotate270FlipNone);
                    break;
                case "180":
                    ApplyActionToFrames("FlipRotate", ActionEnum.FlipRotate, 0, RotateFlipType.Rotate180FlipNone);
                    break;
            }

            GC.Collect();
            ResizeFormToImage();
            this.Cursor = Cursors.Default;
        }

        private void con_deleteSelectedFrame_Click(object sender, EventArgs e)
        {
            if (_listFramesEdit.Count > 1 && !tvFrames.IsAllChecked())
            {
                this.Cursor = Cursors.WaitCursor;

                ApplyActionToFrames("Delete", ActionEnum.Delete);
                tvFrames.UncheckAll();
                GC.Collect();

                this.Cursor = Cursors.Default;
            }
            else
            {
                MessageBox.Show(Resources.MsgBox_Message_CantDelete, Resources.MsgBox_Title_CantDelete, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        /// <summary>
        /// Insert one image to desired position in the list.
        /// </summary>
        private void con_image_Click(object sender, EventArgs e)
        {
            if (openImageDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            this.Cursor = Cursors.AppStarting;

            AddPictures(openImageDialog.FileName);
            GC.Collect();

            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// ListFramesInverted
        /// </summary>
        private void con_revertOrder_Click(object sender, EventArgs e)
        {
            if (_listFramesEdit.Count <= 1) return;

            this.Cursor = Cursors.AppStarting;

            ResetUndoProp();

            _listFramesEdit.Reverse();
            _listDelayEdit.Reverse();

            pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

            DelayUpdate();
            GC.Collect();

            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// Make a Yoyo with the frames (listFrames   listFramesInverted)
        /// </summary>
        private void con_yoyo_Click(object sender, EventArgs e)
        {
            if (_listFramesEdit.Count <= 1) return;

            this.Cursor = Cursors.AppStarting;

            ResetUndoProp();

            int countDiff = _listFramesEdit.Count;
            _listFramesEdit = ImageUtil.Yoyo(_listFramesEdit); //TODO
            _listDelayEdit = ImageUtil.Yoyo<int>(_listDelayEdit);
            countDiff -= _listFramesEdit.Count;

            trackBar.Maximum = _listFramesEdit.Count - 1;
            pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

            tvFrames.Add(Math.Abs(countDiff));
            DelayUpdate();
            GC.Collect();

            this.Cursor = Cursors.Default;
        }

        private void con_Progress_Click(object sender, EventArgs e)
        {
            var progress = new Progress();

            if (progress.ShowDialog(this) == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;

                ApplyActionToFrames("Progress", ActionEnum.Progress);

                this.Cursor = Cursors.Default;
            }

            progress.Dispose();

            GC.Collect();
        }

        private void con_Transitions_Click(object sender, EventArgs e)
        {
            #region Gets the Next Frame

            int indexLast = trackBar.Value == trackBar.Maximum ?
                0 : (trackBar.Value   1);

            string last = _listFramesEdit[indexLast];

            #endregion

            var transitions = new Transitions(_listFramesEdit[trackBar.Value].From(), last.From(), trackBar.Value, indexLast);

            if (transitions.ShowDialog() == DialogResult.OK)
            {
                #region If Ok

                ResetUndoProp();

                var listToAdd = new List<string>();
                int transitionCount = 0;

                foreach (Bitmap bitmap in transitions.ListToExport)
                {
                    string fileName = _listFramesEdit[trackBar.Value].
                        Replace(".bmp", String.Format("TR{0}.bmp", transitionCount));
                    bitmap.Save(fileName);
                    transitionCount  ;

                    listToAdd.Add(fileName);
                }

                _listFramesEdit.InsertRange(trackBar.Value   1, listToAdd);
                _listDelayEdit.InsertRange(trackBar.Value   1, transitions.ListDelayExport);

                tvFrames.Add(transitions.ListToExport.Count);
                trackBar.Maximum  = transitions.ListToExport.Count;

                #endregion
            }
        }

        /// <summary>
        /// Adds a border in all images. The border is painted in the image, the image don't increase in size.
        /// </summary>
        private void con_Border_Click(object sender, EventArgs e)
        {
            var borderOptions = new BorderOptions();

            if (borderOptions.ShowDialog(this) == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;

                ApplyActionToFrames("Border", ActionEnum.Border, Settings.Default.borderThickness, Settings.Default.borderColor);
                GC.Collect();

                this.Cursor = Cursors.Default;
            }
        }

        private void con_changeSpeed_Click(object sender, EventArgs e)
        {
            var valuePicker = new ValuePicker(Resources.MsgSelectSpeed, 500, 15, Resources.Label_Normal, 100);
            valuePicker.Lower = Resources.Label_Slower;
            valuePicker.Greater = Resources.Label_Faster;
            valuePicker.Normal = Resources.Label_Normal;

            if (valuePicker.ShowDialog(this) == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;

                if (valuePicker.Value != 0)
                {
                    float speed = 1;

                    //TODO: Remove range.
                    speed = valuePicker.Value / 100F;

                    ApplyActionToFrames("Slo-Motion", ActionEnum.Speed, speed);
                    GC.Collect();
                }

                this.Cursor = Cursors.Default;
            }
        }

        private void con_titleImage_Click(object sender, EventArgs e)
        {
            Size titleFrameSize = _listFramesEdit[trackBar.Value].From().Size;
            var titleBitmap = new Bitmap(titleFrameSize.Width, titleFrameSize.Height);
            var title = new TitleFrame(titleBitmap);

            if (title.ShowDialog() == DialogResult.OK)
            {
                #region If Ok

                ResetUndoProp();

                using (Graphics grp = Graphics.FromImage(titleBitmap))
                {
                    #region Create Title Image

                    if (title.Blured)
                    {
                        #region Blured

                        this.Cursor = Cursors.WaitCursor;
                        Bitmap blured;

                        if (_listFramesEdit.Count > (trackBar.Value - 1))
                        {
                            blured = _listFramesEdit[trackBar.Value   1].From();
                        }
                        else
                        {
                            blured = _listFramesEdit[0].From(); //If the users wants to place the Title Frame in the end, the logical next frame will be the first.
                        }

                        blured = ImageUtil.Blur(blured, new Rectangle(0, 0, pictureBitmap.Image.Width, pictureBitmap.Image.Height), 3);

                        Image bluredI = blured;
                        grp.DrawImage(bluredI, 0, 0);
                        this.Cursor = Cursors.Default;

                        blured.Dispose();
                        bluredI.Dispose();

                        #endregion
                    }
                    else
                    {
                        grp.FillRectangle(new SolidBrush(title.ColorBackground), 0, 0, titleBitmap.Width, titleBitmap.Height);
                    }

                    var strFormat = new StringFormat();
                    strFormat.Alignment = StringAlignment.Center;
                    strFormat.LineAlignment = StringAlignment.Center;

                    grp.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    grp.DrawString(title.Content, title.FontTitle, new SolidBrush(title.ColorForeground),
                        new RectangleF(0, 0, titleBitmap.Width, titleBitmap.Height), strFormat);

                    string fileName = _listFramesEdit[trackBar.Value].Replace(".bmp", "T.bmp");
                    titleBitmap.Save(fileName);
                    _listFramesEdit.Insert(trackBar.Value, fileName);

                    _listDelayEdit.Insert(trackBar.Value, 1000); //Inserts 1s delay.

                    trackBar.Maximum = _listFramesEdit.Count - 1;
                    pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
                    this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);

                    tvFrames.Add(1);
                    DelayUpdate();
                    GC.Collect();

                    #endregion
                }

                #endregion
            }
        }

        #region Filters

        #region Async Stuff

        private delegate void FilterDelegate(string actionLabel, ActionEnum actionType, float pickerValue = 0, string text = "");

        private FilterDelegate filterDel;

        private void CallBackFilter(IAsyncResult r)
        {
            filterDel.EndInvoke(r);

            this.Invoke((Action)delegate
            {
                pictureBitmap.Image = _listFramesEdit[trackBar.Value].From();
                panelEdit.Enabled = true;
                panelBottom.Enabled = true;
                GC.Collect();

                this.Cursor = Cursors.Default;
            });
        }

        #endregion

        /// <summary>
        /// Apply selected image to a grayscale filter
        /// </summary>
        private void Grayscale_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            ApplyActionToFrames("Grayscale filter", ActionEnum.Grayscale);
            GC.Collect();

            Cursor = Cursors.Default;
        }

        /// <summary>
        /// Apply selected image to a pixelated filter
        /// </summary>
        private void Pixelate_Click(object sender, EventArgs e)
        {
            const string filterLabel = "Pixelate filter";

            //User first need to choose the intensity of the pixelate
            var valuePicker = new ValuePicker(100, 2, Resources.Msg_PixelSize);

            if (valuePicker.ShowDialog() == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;
                panelEdit.Enabled = false;
                panelBottom.Enabled = false;

                filterDel = ApplyActionToFrames;
                filterDel.BeginInvoke(filterLabel, ActionEnum.Pixelate, valuePicker.Value, null, CallBackFilter, null);
            }

            valuePicker.Dispose();
        }

        /// <summary>
        /// Apply selected image to a blur filter
        /// </summary>
        private void Blur_Click(object sender, EventArgs e)
        {
            const string filterLabel = "Blur filter";

            var valuePicker = new ValuePicker(5, 1, Resources.Msg_BlurIntense);

            if (valuePicker.ShowDialog() == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;
                panelEdit.Enabled = false;
                panelBottom.Enabled = false;

                filterDel = ApplyActionToFrames;
                filterDel.BeginInvoke(filterLabel, ActionEnum.Blur, valuePicker.Value, null, CallBackFilter, null);
            }

            valuePicker.Dispose();
        }

        /// <summary>
        /// Convert selected image to negative filter
        /// </summary>
        private void Negative_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            ApplyActionToFrames("Negative filter", ActionEnum.Negative);
            GC.Collect();

            Cursor = Cursors.Default;
        }

        /// <summary>
        /// Convert selected image to SepiaTone filter
        /// </summary>
        private void SepiaTone_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            ApplyActionToFrames("Sepia filter", ActionEnum.Sepia);
            GC.Collect();

            Cursor = Cursors.Default;
        }

        /// <summary>
        /// Convert selected image to a color filter
        /// </summary>
        private void con_Color_Click(object sender, EventArgs e)
        {
            var colorFilter = new ColorFilter();

            if (colorFilter.ShowDialog() == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;

                ApplyActionToFrames("Color filter", ActionEnum.Color, 0F, Color.FromArgb(colorFilter.Alpha, colorFilter.Red, colorFilter.Green, colorFilter.Blue));
                GC.Collect();

                this.Cursor = Cursors.Default;
            }
        }

        #endregion

        #endregion

        #endregion

        #region Play Preview

        System.Windows.Forms.Timer _timerPlayPreview = new System.Windows.Forms.Timer();
        private int _actualFrame = 0;

        private void pictureBitmap_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //Cursor.Cross is for point selection.
            if (pictureBitmap.Cursor != Cursors.Cross)
            {
                // Play/Stop Animation.
                if (e.Button.Equals(MouseButtons.Left))
                    PlayPreview();

                return;
            }

            var bitmapAux = _listFramesEdit[trackBar.Value].From();

            //Calculates the exact position of the cursor over the image
            int crossY = e.Y - (pictureBitmap.Height - bitmapAux.Height) / 2;
            int crossX = e.X - (pictureBitmap.Width - bitmapAux.Width) / 2;

            //If position is out of bounds
            if ((crossX > bitmapAux.Width) || (crossY > bitmapAux.Height) ||
                crossX < 0 || crossY < 0)
            {
                toolTip.Show(Resources.Msg_WrongPosition, pictureBitmap, 0, pictureBitmap.Height, 2500);
                bitmapAux.Dispose();
                GC.Collect();
                return;
            }

            // Store point coordinates to insert text
            _pointTextPosition = new Point(crossX, crossY);

            // Initialize cursor for [pictureBitmap]
            pictureBitmap.Cursor = Cursors.Default;

            bitmapAux.Dispose();

            //Show TitleFrameSettings form as modal
            (new InsertText(false)).ShowDialog(this);

            GC.Collect();
        }

        private void PlayPreview()
        {
            if (_timerPlayPreview.Enabled)
            {
                _timerPlayPreview.Tick -= timerPlayPreview_Tick;
                _timerPlayPreview.Stop();

                lblDelay.Visible = true;
                trackBar.Value = _actualFrame;
                trackBar.Visible = true;
                this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);
                btnPreview.Text = Resources.Con_PlayPreview;
                btnPreview.Image = Resources.Play_17Green;

                DelayUpdate();
            }
            else
            {
                lblDelay.Visible = false;
                this.Text = String.Format("Screen To Gif - {0}", Resources.Title_PlayingAnimation);
                btnPreview.Text = Resources.Con_StopPreview;
                btnPreview.Image = Resources.Stop_17Red;
                _actualFrame = trackBar.Value;

                #region Starts playing the next frame

                if (_listFramesEdit.Count - 1 == _actualFrame)
                {
                    _actualFrame = 0;
                }
                else
                {
                    _actualFrame  ;
                }

                #endregion

                _timerPlayPreview.Tick  = timerPlayPreview_Tick;
                _timerPlayPreview.Start();

                trackBar.Visible = false;
            }
        }

        /// <summary>
        /// Stops the preview
        /// </summary>
        /// <param name="shouldSincronize">True if should update the value of the trackBar</param>
        private void StopPreview(bool shouldSincronize = true)
        {
            if (_timerPlayPreview.Enabled)
            {
                _timerPlayPreview.Tick -= timerPlayPreview_Tick;
                _timerPlayPreview.Stop();

                if (shouldSincronize)
                {
                    trackBar.Value = _actualFrame;
                }
            }

            this.Text = Resources.Title_EditorFrame   trackBar.Value   " - "   (_listFramesEdit.Count - 1);
            lblDelay.Visible = true;
            trackBar.Visible = true;
            btnPreview.Text = Resources.Con_PlayPreview;
            btnPreview.Image = Resources.Play_17Green;

            DelayUpdate();
        }

        private void timerPlayPreview_Tick(object sender, EventArgs e)
        {
            _timerPlayPreview.Tick -= timerPlayPreview_Tick;

            //Sets the interval for this frame. If this frame has 500ms, the next frame will take 500ms to show.
            _timerPlayPreview.Interval = _listDelayEdit[_actualFrame];

            pictureBitmap.Image = new Bitmap(_listFramesEdit[_actualFrame]);

            if (_listFramesEdit.Count - 1 == _actualFrame)
            {
                _actualFrame = 0;
            }
            else
            {
                _actualFrame  ;
            }

            _timerPlayPreview.Tick  = timerPlayPreview_Tick;

            GC.Collect(2);
        }

        private void contextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            StopPreview();
        }

        /// <summary>
        /// When the user slides the trackBar, the image updates.
        /// </summary>
        private void trackBar_Scroll(object sender, EventArgs e)
        {
            if (e == null) return; //To prevent loop.

            #region Select the node when user scrolls

            var parentNode = tvFrames.Nodes[_parentNodeLabel];
            if (!parentNode.IsExpanded)
            {
                parentNode.Expand();
                Application.DoEvents();
            }

            tvFrames.SelectedNode = parentNode.Nodes[trackBar.Value];
            tvFrames.Focus();
            //Application.DoEvents();

            #endregion
        }

        #endregion

        #region Frame Delay

        /// <summary>
        /// The last position of the mouse cursor.
        /// </summary>
        private Point _lastPosition;

        /// <summary>
        /// The amount of delay selected.
        /// </summary>
        private int _delay;

        /// <summary>
        /// Flag that tells when the user is clicking in the label or not.
        /// </summary>
        private bool _clicked;

        /// <summary>
        /// Updates the <see cref="_clicked"/> flag or opens the contextMenu.
        /// </summary>
        private void lblDelay_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _clicked = true;
                _lastPosition = e.Location; //not sure if this is needed here, there is another one in the EditFrames().
            }
            else
            {
                con_tbDelay.Text = _delay.ToString();
                contextDelay.Show(lblDelay, 0, lblDelay.Height);
            }
        }

        /// <summary>
        /// Gets if the user is draging to up or down and updates the values.
        /// </summary>
        private void lblDelay_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //If the user is not clicking, returns.
            if (!_clicked)
                return;

            if ((e.Y - _lastPosition.Y) < 0)
            {
                if (_delay < 1000)
                {
                    _delay  ;
                    lblDelay.Text = _delay   " ms";
                }

            }
            else if ((e.Y - _lastPosition.Y) > 0)
            {
                if (_delay > 10)
                {
                    _delay--;
                    lblDelay.Text = _delay   " ms";
                }

            }

            _lastPosition = e.Location;
        }

        /// <summary>
        /// Updates the flag <see cref="_clicked"/> to false and sets the delay value to the list.
        /// </summary>
        private void lblDelay_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            _clicked = false;

            //Only sets the delay value when user finishes selecting.
            _listDelayEdit[trackBar.Value] = _delay;
        }

        /// <summary>
        /// Called after the user changes the text of the toolstrip of the delay.
        /// </summary>
        private void con_tbDelay_TextChanged(object sender, EventArgs e)
        {
            if (con_tbDelay.Text.Equals(""))
                con_tbDelay.Text = "0";

            _delay = Convert.ToInt32(con_tbDelay.Text);

            if (_delay > 2500)
            {
                _listDelayEdit[trackBar.Value] = _delay = 2500;
            }
            else if (_delay < 10)
            {
                _listDelayEdit[trackBar.Value] = _delay = 10;
            }
            else
            {
                _listDelayEdit[trackBar.Value] = _delay;
            }

            lblDelay.Text = _delay   " ms";
        }

        /// <summary>
        /// Called when the user hits the key "Enter" while focused in the con_tbDelay text box. It closes the context menu.
        /// </summary>
        private void con_tbDelay_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == (char)Keys.Enter)
            {
                contextDelay.Close(ToolStripDropDownCloseReason.Keyboard);
                e.SuppressKeyPress = true;
            }
        }

        /// <summary>
        /// Updates the label that shows the delay of the current frame
        /// </summary>
        private void DelayUpdate()
        {
            #region Delay Display

            _delay = _listDelayEdit[trackBar.Value];
            lblDelay.Text = _delay   " ms";

            #endregion
        }

        #endregion

        #region Treeview of Frames

        private void btnShowListFrames_Click(object sender, EventArgs e)
        {
            #region Show tvFrames

            MainSplit.Panel1Collapsed = false;
            RightSplit.Panel1Collapsed = true;

            #endregion
        }

        private void btnHideListFrames_Click(object sender, EventArgs e)
        {
            #region Hide tvFrames

            MainSplit.Panel1Collapsed = true;
            RightSplit.Panel1Collapsed = false;

            #endregion
        }

        private void tvFrames_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                #region If Known Action

                //(Un)check all nodes
                if (e.Node.Name == _parentNodeLabel)
                {
                    foreach (TreeNode node in e.Node.Nodes)
                        node.Checked = e.Node.Checked;
                }
                else
                {
                    //TODO: Make to unselect as well.
                    if (tvFrames.Shift && tvFrames.First != -1) // last != -1 &&
                    {
                        #region If Shift-clicking and first frame selected

                        if (tvFrames.Last == -1)
                        {
                            tvFrames.Last = e.Node.Index;
                        }

                        //Remove the AfterCheck to prevent conflict
                        tvFrames.AfterCheck -= tvFrames_AfterCheck;

                        #region Check all

                        if (tvFrames.First < tvFrames.Last)
                        {
                            for (int i = tvFrames.First; i < tvFrames.Last; i  )
                            {
                                tvFrames.Nodes[0].Nodes[i].Checked = true;
                            }
                        }
                        else
                        {
                            for (int i = tvFrames.First; i > tvFrames.Last; i--)
                            {
                                tvFrames.Nodes[0].Nodes[i].Checked = true;
                            }
                        }

                        #endregion

                        tvFrames.First = e.Node.Index;
                        tvFrames.Last = -1;

                        tvFrames.Shift = false;
                        tvFrames.AfterCheck  = tvFrames_AfterCheck;

                        #endregion
                    }
                    else if (!tvFrames.Shift)
                    {
                        tvFrames.First = e.Node.Index;
                        tvFrames.Last = -1;
                    }

                    //Or display the (un)checked frame
                    SelectFrame(e.Node.Index);
                }


                //Select current node
                tvFrames.SelectedNode = e.Node;

                #endregion
            }
        }

        private void tvFrames_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // Display selected frame 
            if (e.Action != TreeViewAction.Unknown && e.Node != tvFrames.Nodes[0])
                SelectFrame(e.Node.Index);
        }

        #region Context Menu

        private void tvFrames_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            StopPreview();

            if (e.Button == MouseButtons.Right)
            {
                tvFrames.SelectedNode = e.Node;

                if (e.Node != tvFrames.Nodes[0])
                    SelectFrame(e.Node.Index);
            }
        }

        private void contextMenuTreeview_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            StopPreview();

            if (tvFrames.SelectedNode != tvFrames.Nodes[0])
            {
                con_MoveUpwards.Enabled = tvFrames.SelectedNode.Index != 0;
                con_MoveDownwards.Enabled = tvFrames.SelectedNode.Index != tvFrames.Nodes[0].Nodes.Count - 1;

                contextMenuTreeview.Show();
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void con_MakeACopy_Click(object sender, EventArgs e)
        {
            StopPreview();

            if (tvFrames.SelectedNode == null) return;
            //If != 0 means that is the Main Node.
            if (tvFrames.SelectedNode.GetNodeCount(false) != 0) return;

            string fileName = _listFramesEdit[trackBar.Value].Replace(".bmp", "C.bmp");
            File.Copy(_listFramesEdit[trackBar.Value], fileName);

            _listFramesEdit.Insert(trackBar.Value   1, fileName);
            _listDelayEdit.Insert(trackBar.Value   1, _listDelayEdit[trackBar.Value]);

            trackBar.Maximum = _listDelayEdit.Count - 1;

            tvFrames.Nodes[0].Nodes.Insert(trackBar.Value   1, tvFrames.SelectedNode.Text   Resources.Tree_Copy);

            DelayUpdate();
            GC.Collect();
        }

        private void con_MoveUpwards_Click(object sender, EventArgs e)
        {
            StopPreview();

            //A frame need to be selected.
            if (tvFrames.SelectedNode == null) return;
            //If != 0 means that is the Main Node.
            if (tvFrames.SelectedNode.GetNodeCount(false) != 0) return;
            //This action can't be applied to the top frame.
            if (tvFrames.SelectedNode.Index == 0) return;

            //Copy, RemoveAt, Insert;
            var aux = _listFramesEdit[trackBar.Value];
            var auxDelay = _listDelayEdit[trackBar.Value];
            var auxNode = tvFrames.Nodes[0].Nodes[trackBar.Value];

            _listFramesEdit.RemoveAt(trackBar.Value);
            _listDelayEdit.RemoveAt(trackBar.Value);
            tvFrames.Nodes[0].Nodes.RemoveAt(trackBar.Value);

            _listFramesEdit.Insert(trackBar.Value - 1, aux);
            _listDelayEdit.Insert(trackBar.Value - 1, auxDelay);
            tvFrames.Nodes[0].Nodes.Insert(trackBar.Value - 1, auxNode);

            tvFrames.SelectedNode = tvFrames.Nodes[0].Nodes[trackBar.Value - 1];
            SelectFrame(trackBar.Value - 1);

            DelayUpdate();
            GC.Collect();
        }

        private void con_MoveDownwards_Click(object sender, EventArgs e)
        {
            StopPreview();

            //A frame need to be selected.
            if (tvFrames.SelectedNode == null) return;
            //If != 0 means that is the Main Node.
            if (tvFrames.SelectedNode.GetNodeCount(false) != 0) return;
            //This action can't be applied to the bottom frame.
            if (tvFrames.SelectedNode.Index == tvFrames.Nodes[0].Nodes.Count - 1) return;

            //Copy, RemoveAt, Insert;
            var aux = _listFramesEdit[trackBar.Value];
            var auxDelay = _listDelayEdit[trackBar.Value];
            var auxNode = tvFrames.Nodes[0].Nodes[trackBar.Value];

            _listFramesEdit.RemoveAt(trackBar.Value);
            _listDelayEdit.RemoveAt(trackBar.Value);
            tvFrames.Nodes[0].Nodes.RemoveAt(trackBar.Value);

            _listFramesEdit.Insert(trackBar.Value   1, aux);
            _listDelayEdit.Insert(trackBar.Value   1, auxDelay);
            tvFrames.Nodes[0].Nodes.Insert(trackBar.Value   1, auxNode);

            tvFrames.SelectedNode = tvFrames.Nodes[0].Nodes[trackBar.Value   1];
            SelectFrame(trackBar.Value   1);

            DelayUpdate();
            GC.Collect();
        }

        private void con_RenameFrame_Click(object sender, EventArgs e)
        {
            StopPreview();

            //A frame need to be selected.
            if (tvFrames.SelectedNode == null) return;
            //If != 0 means that is the Main Node.
            if (tvFrames.SelectedNode.GetNodeCount(false) != 0) return;

            tvFrames.SelectedNode.BeginEdit();
        }

        #endregion

        #endregion

        #region Drag And Drop Events

        private void pictureBitmap_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop)
                ? DragDropEffects.Copy
                : DragDropEffects.None;
        }

        private void pictureBitmap_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
        {
            var fileNames = e.Data.GetData(DataFormats.FileDrop) as string[];

            if (null != fileNames)
            {
                foreach (string fileName in fileNames)
                {
                    AddPictures(fileName);
                }
            }
        }

        #endregion

        #region Other Events

        #region Context_Record

        private void con_Fullscreen_CheckedChanged(object sender, EventArgs e)
        {
            Settings.Default.fullscreen = con_Fullscreen.Checked;
        }

        private void con_Snapshot_CheckedChanged(object sender, EventArgs e)
        {
            Settings.Default.snapshot = con_Snapshot.Checked;
        }

        private void contextRecord_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            btnRecordPause.BackColor = Color.DodgerBlue;

            con_Snapshot.Enabled = con_Fullscreen.Enabled = _stage == Stage.Stopped;
        }

        private void contextRecord_Closing(object sender, ToolStripDropDownClosingEventArgs e)
        {
            btnRecordPause.BackColor = Color.FromArgb(239, 239, 242);
        }

        #endregion

        private void con_tbCaption_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                con_addCaption_Click(null, null);
                contextMenu.Close(ToolStripDropDownCloseReason.ItemClicked);
            }
        }

        #endregion
    }
}


标签: gif 录制 工具 屏幕

实例下载地址

<赞>GIF屏幕录制工具源码下载

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 zengjwmail 发表于: 2017-04-13 10:35 23
1111111

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有1条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警