Full Featured Capturing AppByteScout Screen Capturing SDK

Full Featured Capturing App for ByteScout Screen Capturing SDK

Program.cs:

C#
using System;
using System.Windows.Forms;

namespace ScreenCapturing
{
    static class Program
    {
        public static Config Cfg = null;

        public static string RegistryKey = "Software\\Screen Capturing";
        public static string PostCommand = String.Empty;

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Cfg = new Config();

            MainForm mainForm = new MainForm();

            Application.Run(mainForm);
        }
    }
}

CapturingThread.cs:

C#
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using BytescoutScreenCapturingLib;

// NOTE: if you are getting error like "invalid image" related to loading the SDK's dll then 
// try to do the following:
// 1) remove the reference to the SDK by View - Solution Explorer
// then click on References, select Bytescout... reference name and right-click it and select Remove
// 2) To re-add click on the menu: Project - Add Reference
// 3) In "Add Reference" dialog switch to "COM" tab and find Bytescout...
// 4) Select it and click "Add" 
// 5) Recompile the application 
// Note: if you need to run on both x64 and x86 then please make sure you have set "Embed Interop Types" to True for this reference

namespace ScreenCapturing
{
    public class CapturingThreadData
    {
        public CaptureAreaType CaptureType;
        public String TempFile;
        public Rectangle CaptureRectangle;
        public bool ShowWebCamStream;

        public int Result = 0; // 0 - success; 1 - error
        public string ErrorText;
    }

    public class CapturingThread
    {
        public static void ThreadProc(Object obj)
        {
            Capturer capturer = new Capturer(); // create new screen capturer object

            CapturingThreadData data = (CapturingThreadData) obj;

            if (Program.Cfg.WriteLog)
                capturer.SetLogFile(Path.GetTempPath() + Application.ProductName + " log.txt");

            capturer.RegistrationName = "demo";
            capturer.RegistrationKey = "demo";

            if (Program.Cfg.AudioDevice != "")
            {
                capturer.CurrentAudioDeviceName = Program.Cfg.AudioDevice;
            }

            if (Program.Cfg.AudioLine != "")
            {
                capturer.CurrentAudioDeviceLineName = Program.Cfg.AudioLine;
            }

            if (Program.Cfg.SelectedVideoCodecTab == 0)
            {
                capturer.CurrentWMVAudioCodecName = Program.Cfg.WmvAudioCodec;
                capturer.CurrentWMVAudioFormat = Program.Cfg.WmvAudioFormat;
                capturer.CurrentWMVVideoCodecName = Program.Cfg.WmvVideoCodec;

                Program.Cfg.WmvAudioCodec = capturer.CurrentWMVAudioCodecName;
                Program.Cfg.WmvAudioFormat = capturer.CurrentWMVAudioFormat;
                Program.Cfg.WmvVideoCodec = capturer.CurrentWMVVideoCodecName;
            }
            else
            {
                capturer.CurrentAudioCodecName = Program.Cfg.AviAudioCodec;
                capturer.CurrentVideoCodecName = Program.Cfg.AviVideoCodec;
            }

            capturer.AudioEnabled = Program.Cfg.EnableAudio;
            // this option tells to use captured area dimensions as output video width/height
            // or use user defined video dimensions
            capturer.MatchOutputSizeToTheSourceSize = !Program.Cfg.ResizeOutputVideo;
            capturer.FPS = Program.Cfg.FPS;

            capturer.ShowMouseHotSpot = Program.Cfg.ShowMouseHotSpot;
            capturer.CaptureMouseCursor = Program.Cfg.CaptureMouseCursor;
            capturer.AnimateMouseClicks = Program.Cfg.AnimateMouseClicks;
            capturer.AnimateMouseButtons = Program.Cfg.AnimateMouseButtons;
            capturer.MouseAnimationDuration = Program.Cfg.MouseAnimationDuration;
            capturer.MouseSpotRadius = Program.Cfg.MouseSpotRadius;
            capturer.MouseHotSpotColor = (uint) ColorTranslator.ToOle(Program.Cfg.MouseHotSpotColor);
            capturer.MouseCursorLeftClickAnimationColor = (uint) ColorTranslator.ToOle(Program.Cfg.MouseCursorLeftClickAnimationColor);
            capturer.MouseCursorRightClickAnimationColor = (uint) ColorTranslator.ToOle(Program.Cfg.MouseCursorRightClickAnimationColor);                     

            capturer.CaptureRectLeft = data.CaptureRectangle.Left;
            capturer.CaptureRectTop = data.CaptureRectangle.Top;
            capturer.CaptureRectWidth = data.CaptureRectangle.Width;
            capturer.CaptureRectHeight = data.CaptureRectangle.Height;

            capturer.KeepAspectRatio = Program.Cfg.KeepAspectRatio;

            // show recording time stamp
            capturer.OverlayingRedTextCaption = "Recording: {RUNNINGMIN}:{RUNNINGSEC}:{RUNNINGMSEC} on {CURRENTYEAR}-{CURRENTMONTH}-{CURRENTDAY} at {CURRENTHOUR}:{CURRENTMIN}:{CURRENTSEC}:{CURRENTMSEC}";

            capturer.OutputWidth = Program.Cfg.OutputWidth;
            capturer.OutputHeight = Program.Cfg.OutputHeight;

            if ((capturer.WebCamCount > 0) && (data.ShowWebCamStream))
            {
                capturer.AddWebCamVideo = true;

                if (!String.IsNullOrEmpty(Program.Cfg.WebCameraDevice))
                {
                    capturer.CurrentWebCamName = Program.Cfg.WebCameraDevice;
                }

                capturer.SetWebCamVideoRectangle(Program.Cfg.WebCameraWindowX, Program.Cfg.WebCameraWindowY, Program.Cfg.WebCameraWindowWidth, Program.Cfg.WebCameraWindowHeight);
            }

            data.TempFile = Path.GetTempFileName();
            data.TempFile = Path.ChangeExtension(data.TempFile, (Program.Cfg.SelectedVideoCodecTab == 0) ? ".wmv" : ".avi");
            capturer.OutputFileName = data.TempFile;
            capturer.CapturingType = data.CaptureType;

            // set border around captured area if we are not capturing entire screen
            if (capturer.CapturingType != CaptureAreaType.catScreen &&
                capturer.CapturingType != CaptureAreaType.catWebcamFullScreen)
            {
                // set border style
                capturer.CaptureAreaBorderType = Program.Cfg.CaptureAreaBorderType;
                capturer.CaptureAreaBorderColor = (uint) ColorTranslator.ToOle(Program.Cfg.CaptureAreaBorderColor);
                capturer.CaptureAreaBorderWidth = Program.Cfg.CaptureAreaBorderWidth;
            }


            try
            {
                capturer.Run();

    // IMPORTANT: if you want to check for some code if need to stop the recording then make sure you are 
    // using Thread.Sleep(1) inside the checking loop, so you have the loop like
    // Do 
    // Thread.Sleep(1) 
    // While StopButtonNotClicked

            }
            catch (COMException ex)
            {
                data.ErrorText = ex.Message;
                data.Result = 1;
                return;
            }

            try
            {
                Thread.Sleep(Timeout.Infinite);
            }
            catch (ThreadInterruptedException)
            {
                capturer.Stop();
                data.Result = 0;
            }
            catch (Exception ex)
            {
                data.ErrorText = ex.Message;
                data.Result = 1;
            }
        }
    }
}

ColorControl.cs:

C#
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace ScreenCapturing
{
    public enum CustomBorderStyle { None, Dashed, Dotted, Bump, Etched, Flat, Raised, Sunken };

    public class ColorControl : Control
    {
        private CustomBorderStyle _borderStyle = CustomBorderStyle.None;

        private ToolTip _toolTip;
        private IContainer components;

        [DefaultValue(CustomBorderStyle.None)]
        public CustomBorderStyle BorderStyle
        {
            get { return _borderStyle; }
            set 
            { 
                _borderStyle = value;
                Refresh();
            }
        }

        public ColorControl()
        {
            InitializeComponent();

            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            UpdateStyles();

            AutoSize = false;
        }

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

            e.Graphics.FillRectangle(new SolidBrush(ForeColor), ClientRectangle);

            if (BorderStyle == CustomBorderStyle.Dotted)
            {
                ControlPaint.DrawBorder(e.Graphics, ClientRectangle, SystemColors.ControlDarkDark, ButtonBorderStyle.Dotted);
            }
            else if (BorderStyle == CustomBorderStyle.Dashed)
            {
                ControlPaint.DrawBorder(e.Graphics, ClientRectangle, SystemColors.ControlDarkDark, ButtonBorderStyle.Dashed);
            }
            else if (BorderStyle != CustomBorderStyle.None)
            {
                Border3DStyle style;

                switch (BorderStyle)
                {
                    case CustomBorderStyle.Bump: style = Border3DStyle.Bump; break;
                    case CustomBorderStyle.Etched: style = Border3DStyle.Etched; break;
                    case CustomBorderStyle.Raised: style = Border3DStyle.Raised; break;
                    case CustomBorderStyle.Sunken: style = Border3DStyle.Sunken; break;
                    default: style = Border3DStyle.Flat; break;
                }

                ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, style);
            }

            if (Focused)
            {
                Rectangle focusRect = new Rectangle(ClientRectangle.X + 2, ClientRectangle.Y + 2, ClientRectangle.Width - 4, ClientRectangle.Height - 4);
                ControlPaint.DrawFocusRectangle(e.Graphics, focusRect);
            }
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);

            Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);

            Invalidate();
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);

            Focus();

            if (e.Button == MouseButtons.Left)
            {
                using (ColorDialog fd = new ColorDialog())
                {
                    fd.AnyColor = true;
                    fd.FullOpen = true;
                    fd.Color = Color.FromArgb(255, ForeColor);

                    int[] customColors = Program.Cfg.CustomColors;

                    if (customColors != null && customColors.Length > 0)
                    {
                        fd.CustomColors = customColors;
                    }

                    if (fd.ShowDialog() == DialogResult.OK)
                    {
                        ForeColor = fd.Color;
                        Program.Cfg.CustomColors = fd.CustomColors;
                    }
                }
            }
            else if (e.Button == MouseButtons.Right)
            {
                ContextMenu menu = new ContextMenu();
                menu.MenuItems.Add(new MenuItem("Select Transparent Color", menu_Click));

                menu.Show(this, e.Location);
            }
        }

        void menu_Click(object sender, EventArgs e)
        {
            ForeColor = Color.Transparent;
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            using (ColorDialog fd = new ColorDialog())
            {
                fd.AnyColor = true;
                fd.FullOpen = true;
                fd.Color = ForeColor;

                int[] customColors = Program.Cfg.CustomColors;

                if (customColors != null && customColors.Length > 0)
                {
                    fd.CustomColors = customColors;
                }

                if (fd.ShowDialog() == DialogResult.OK)
                {
                    ForeColor = fd.Color;
                    Program.Cfg.CustomColors = fd.CustomColors;
                }
            }

            base.OnKeyDown(e);
        }

        protected override void OnForeColorChanged(EventArgs e)
        {
            String colorName = String.Empty, rgb, tooltip;

            if (ForeColor.ToKnownColor() != 0)
            {
                colorName = ForeColor.ToKnownColor().ToString();
            }
            else if (ForeColor.IsNamedColor)
            {
                colorName = ForeColor.ToString();
            }

            rgb = String.Format("R={0}; G={1}; B={2}", ForeColor.R, ForeColor.G, ForeColor.B);

            if (colorName.Length > 0)
            {
                tooltip = String.Format("{0} ({1})", colorName, rgb);
            }
            else
            {
                tooltip = rgb;
            }

            _toolTip.SetToolTip(this, tooltip);

            base.OnForeColorChanged(e);
        }

        private void InitializeComponent()
        {
            components = new Container();
            _toolTip = new ToolTip(components);
            SuspendLayout();
            // 
            // ColorControl
            // 
            _toolTip.SetToolTip(this, "Color");
            ResumeLayout(false);

        }
    }
}

Config.cs:

C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using Microsoft.Win32;
using BytescoutScreenCapturingLib;

// NOTE: if you are getting error like "invalid image" related to loading the SDK's dll then 
// try to do the following:
// 1) remove the reference to the SDK by View - Solution Explorer
// then click on References, select Bytescout... reference name and right-click it and select Remove
// 2) To re-add click on the menu: Project - Add Reference
// 3) In "Add Reference" dialog switch to "COM" tab and find Bytescout...
// 4) Select it and click "Add" 
// 5) Recompile the application 
// Note: if you need to run on both x64 and x86 then please make sure you have set "Embed Interop Types" to True for this reference


namespace ScreenCapturing
{
    public class Config
    {
        public int[] CustomColors { get { return Get<int[]>("CustomColors", null); } set { Options["CustomColors"] = value; } }
        public Point WindowLocation { get { return Get<Point>("WindowLocation", Point.Empty); } set { Options["WindowLocation"] = value; } }
        public string AudioDevice { get { return Get<string>("AudioDevice", ""); } set { Options["AudioDevice"] = value; } }
        public string AudioLine { get { return Get<string>("AudioLine", ""); } set { Options["AudioLine"] = value; } }
        public string AviAudioCodec { get { return Get<string>("AviAudioCodec", "PCM"); } set { Options["AviAudioCodec"] = value; } }
        public string AviVideoCodec { get { return Get<string>("AviVideoCodec", "Bytescout Lossless Video Codec"); } set { Options["AviVideoCodec"] = value; } }
        public string WmvAudioCodec { get { return Get<string>("WmvAudioCodec", "Windows Media Audio 9"); } set { Options["WmvAudioCodec"] = value; } }
        public int WmvAudioFormat { get { return Get<int>("WmvAudioFormat", 28); } set { Options["WmvAudioFormat"] = value; } } // 28 is 128 kbps audio format for WMV
        public string WmvVideoCodec { get { return Get<string>("WmvVideoCodec", "Windows Media Video 9"); } set { Options["WmvVideoCodec"] = value; } }
        public bool EnableAudio { get { return Get<bool>("EnableAudio", false); } set { Options["EnableAudio"] = value; } }
        public bool ResizeOutputVideo { get { return Get<bool>("ResizeOutputVideo", true); } set { Options["ResizeOutputVideo"] = value; } }
        public int OutputWidth { get { return Get<int>("OutputWidth", 640); } set { Options["OutputWidth"] = value; } }
        public int OutputHeight { get { return Get<int>("OutputHeight", 480); } set { Options["OutputHeight"] = value; } }
        public bool KeepAspectRatio { get { return Get<bool>("KeepAspectRatio", true); } set { Options["KeepAspectRatio"] = value; } }
        public float FPS { get { return Get<float>("FPS", 14.985f); } set { Options["FPS"] = value; } }
        public bool WriteLog { get { return Get<bool>("WriteLog", false); } set { Options["WriteLog"] = value; } }
        public bool DoNotShowMessage1 { get { return Get<bool>("DoNotShowMessage1", false); } set { Options["DoNotShowMessage1"] = value; } }
        public string LastUsedFolder { get { return Get<string>("LastUsedFolder", ""); } set { Options["LastUsedFolder"] = value; } }
        public int SelectedVideoCodecTab { get { return Get<int>("SelectedVideoCodecTab", 0); } set { Options["SelectedVideoCodecTab"] = value; } }
        public string WebCameraDevice { get { return Get<string>("WebCameraDevice", ""); } set { Options["WebCameraDevice"] = value; } }
        public int WebCameraWindowX { get { return Get<int>("WebCameraWindowX", 10); } set { Options["WebCameraWindowX"] = value; } }
        public int WebCameraWindowY { get { return Get<int>("WebCameraWindowY", 10); } set { Options["WebCameraWindowY"] = value; } }
        public int WebCameraWindowWidth { get { return Get<int>("WebCameraWindowWidth", 160); } set { Options["WebCameraWindowWidth"] = value; } }
        public int WebCameraWindowHeight { get { return Get<int>("WebCameraWindowHeight", 120); } set { Options["WebCameraWindowHeight"] = value; } }
        public bool ShowMouseHotSpot { get { return Get<bool>("ShowMouseHotSpot", true); } set { Options["ShowMouseHotSpot"] = value; } }
        public bool CaptureMouseCursor { get { return Get<bool>("CaptureMouseCursor", true); } set { Options["CaptureMouseCursor"] = value; } }
        public bool AnimateMouseClicks { get { return Get<bool>("AnimateMouseClicks", true); } set { Options["AnimateMouseClicks"] = value; } }
        public bool AnimateMouseButtons { get { return Get<bool>("AnimateMouseButtons", false); } set { Options["AnimateMouseButtons"] = value; } }
        public int MouseAnimationDuration { get { return Get<int>("MouseAnimationDuration", 600); } set { Options["MouseAnimationDuration"] = value; } }
        public int MouseSpotRadius { get { return Get<int>("MouseSpotRadius", 60); } set { Options["MouseSpotRadius"] = value; } }
        public Color MouseHotSpotColor { get { return Get<Color>("MouseHotSpotColor", Color.FromArgb(255, 255, 0)); } set { Options["MouseHotSpotColor"] = value; } }
        public Color MouseCursorLeftClickAnimationColor { get { return Get<Color>("MouseCursorLeftClickAnimationColor", Color.FromArgb(0, 0, 255)); } set { Options["MouseCursorLeftClickAnimationColor"] = value; } }
        public Color MouseCursorRightClickAnimationColor { get { return Get<Color>("MouseCursorRightClickAnimationColor", Color.FromArgb(0, 255, 0)); } set { Options["MouseCursorRightClickAnimationColor"] = value; } }
        public CaptureAreaBorderType CaptureAreaBorderType { get { return Get<CaptureAreaBorderType>("CaptureAreaBorderType", CaptureAreaBorderType.cabtSolid); } set { Options["CaptureAreaBorderType"] = value; } }
        public Color CaptureAreaBorderColor { get { return Get<Color>("CaptureAreaBorderColor", Color.Red); } set { Options["CaptureAreaBorderColor"] = value; } }
        public int CaptureAreaBorderWidth { get { return Get<int>("CaptureAreaBorderWidth", 2); } set { Options["CaptureAreaBorderWidth"] = value; } }

        private readonly String _strKey;
        public Dictionary<string, object> Options = new Dictionary<string, object>();
        public bool Subsection;

        public Config()
        {
            _strKey = Program.RegistryKey;
        }

        public Config(String section)
        {
            Debug.Assert(!String.IsNullOrEmpty(section));

            Subsection = true;
            _strKey = Program.RegistryKey + "\\" + section;
        }

        public T Get<T>(String optionName, Object defaultValue)
        {
            Debug.Assert(!String.IsNullOrEmpty(optionName));

            object value;

            if (Options.TryGetValue(optionName, out value))
            {
                return (T) value;
            }
            else
            {
                String s = (String) Registry.GetValue("HKEY_CURRENT_USER\\" + _strKey, optionName, null);

                if (s == null)
                {
                    return (T) defaultValue;
                }
                else
                {
                    TypeConverter tc;

                    if (typeof(T) == typeof(int[]))
                    {
                        tc = new IntegerArrayConverter();
                    }
                    else
                    {
                        tc = TypeDescriptor.GetConverter(typeof(T));
                    }

                    try
                    {
                        value = tc.ConvertFromString(s);
                    }
                    catch (Exception)
                    {
                        value = defaultValue;
                    }

                    Options.Add(optionName, value);

                    return (T) value;
                }
            }
        }

        public void Set(String optionName, Object value)
        {
            Debug.Assert(!String.IsNullOrEmpty(optionName));

            Options[optionName] = value;
        }

        public void Save()
        {
            RegistryKey key = Registry.CurrentUser.CreateSubKey(_strKey);

            if (key != null)
            {
                foreach (KeyValuePair<string, object> de in Options)
                {
                    TypeConverter tc;
                    String s;

                    if (de.Value == null)
                    {
                        s = "";
                    }
                    else
                    {
                        if (de.Value is int[])
                        {
                            tc = new IntegerArrayConverter();
                        }
                        else
                        {
                            tc = TypeDescriptor.GetConverter(de.Value);
                        }

                        s = tc.ConvertToString(de.Value);
                    }

                    key.SetValue(de.Key, s);
                }

                key.Flush();
            }
        }
    }

    public class IntegerArrayConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }

            return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                string[] ss = ((string) value).Split(new char[] { ';' });
                List<int> list = new List<int>();

                foreach (string s in ss)
                {
                    if (!String.IsNullOrEmpty(s))
                    {
                        list.Add(Int32.Parse(s));
                    }
                }

                return list.ToArray();
            }

            return base.ConvertFrom(context, culture, value);
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                return true;
            }

            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string) && value is int[])
            {
                StringBuilder sb = new StringBuilder();

                foreach (int x in (int[]) value)
                {
                    if (sb.Length > 0)
                    {
                        sb.Append(";");
                    }

                    sb.Append(x.ToString());
                }

                return sb.ToString();
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }
}

CustomMessageBox.cs:

C#
using System;
using System.Windows.Forms;

namespace ScreenCapturing
{
    public partial class CustomMessageBox : Form
    {
        public bool DoNotShow = false;

        public CustomMessageBox(string title, string text)
        {
            InitializeComponent();

            base.Text = title;
            label1.Text = text;
        }

        private void cbDoNotAsk_CheckedChanged(object sender, EventArgs e)
        {
            DoNotShow = cbDoNotShow.Checked;
        }
    }
}

MainForm.cs:

C#
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using ScreenCapturing.Properties;
using BytescoutScreenCapturingLib;


// NOTE: if you are getting error like "invalid image" related to loading the SDK's dll then 
// try to do the following:
// 1) remove the reference to the SDK by View - Solution Explorer
// then click on References, select Bytescout... reference name and right-click it and select Remove
// 2) To re-add click on the menu: Project - Add Reference
// 3) In "Add Reference" dialog switch to "COM" tab and find Bytescout...
// 4) Select it and click "Add" 
// 5) Recompile the application 
// Note: if you need to run on both x64 and x86 then please make sure you have set "Embed Interop Types" to True for this reference


namespace ScreenCapturing
{
    public sealed partial class MainForm : Form
    {
        private bool _recording;
        private ToolStripDropDown _dropDownItems;
        private Rectangle _recordingRegion = Rectangle.Empty;
        private Thread _capturingThread;
        private CapturingThreadData _capturingThreadData;
        private string _lastRecordedFile;

        private const int MYKEYID = 0;
        private const int WM_HOTKEY = 0x0312;
        private const int WM_MOUSEMOVE = 0x0200;
        private const int MOD_ALT = 1;
        private const int MOD_CONTROL = 2;
        private const int MOD_SHIFT = 4;

        [DllImport("user32.dll")]
        private static extern int RegisterHotKey(IntPtr hWnd, int id, int modifier, Keys vk);
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        public MainForm()
        {
            InitializeComponent();

            Point location = Program.Cfg.WindowLocation;

            if (location.IsEmpty)
            {
                StartPosition = FormStartPosition.CenterScreen;
            }
            else
            {
                Location = location;
            }

            Text = Application.ProductName + " " + Application.ProductVersion;
        }

        private void tsmiFullScreen_Click(object sender, EventArgs e)
        {
            _recordingRegion = Screen.PrimaryScreen.Bounds;

            StartRecording(CaptureAreaType.catScreen, sender == tsmiFullScreen);
        }

        private void tsmiMouseRegion_Click(object sender, EventArgs e)
        {
            _recordingRegion.Width = Program.Cfg.OutputWidth;
            _recordingRegion.Height = Program.Cfg.OutputHeight;

            StartRecording(CaptureAreaType.catMouse, sender == tsmiMouseRegion);
        }

        private void tsbRecord_Click(object sender, EventArgs e)
        {
            if (_recording)
            {
                StopRecording();
            }
        }

        private void tsbPlay_Click(object sender, EventArgs e)
        {
            Process prc = new Process();
            prc.StartInfo.FileName = _lastRecordedFile;
            prc.StartInfo.UseShellExecute = true;

            try
            {
                prc.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName);
            }
        }

        private void tsbSettings_Click(object sender, EventArgs e)
        {
            using (SettingsForm f = new SettingsForm())
            {
                f.ShowDialog();
            }
        }

        private void StartRecording(CaptureAreaType captureType, bool withCam)
        {
            _recording = true;

            if (withCam)
            {
                _dropDownItems = tsbRecordWithCam.DropDown;
                tsbRecord.Enabled = false;
                tsbRecordWithCam.ShowDropDownArrow = false;
                tsbRecordWithCam.DropDown = null;
                tsbRecordWithCam.Image = Resources.stop;
                tsbRecordWithCam.Text = "Stop";
            }
            else
            {
                _dropDownItems = tsbRecord.DropDown;
                tsbRecordWithCam.Enabled = false;
                tsbRecord.ShowDropDownArrow = false;
                tsbRecord.DropDown = null;
                tsbRecord.Image = Resources.stop;
                tsbRecord.Text = "Stop";
            }           

            statusBar.Items[0].Text = "Recording started";
            tsbPlay.Enabled = false;

            if (!Program.Cfg.DoNotShowMessage1)
            {
                CustomMessageBox mb = new CustomMessageBox(Application.ProductName, "Press CTRL-SHIFT-F12 to stop recording.");
                mb.StartPosition = FormStartPosition.CenterScreen;
                mb.ShowDialog();
                Program.Cfg.DoNotShowMessage1 = mb.DoNotShow;
            }

            RegisterHotKey(Handle, MYKEYID, MOD_CONTROL + MOD_SHIFT, Keys.F12);

            _capturingThreadData = new CapturingThreadData();

            _capturingThreadData.CaptureType = captureType;
            _capturingThreadData.CaptureRectangle = _recordingRegion;
            _capturingThreadData.ShowWebCamStream = withCam;

            _capturingThread = new Thread(CapturingThread.ThreadProc);
            _capturingThread.Start(_capturingThreadData);

            WindowState = FormWindowState.Minimized;
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == MYKEYID)
            {
                if (_recording)
                {
                    StopRecording();
                }
            }

            base.WndProc(ref m);
        }

        private void StopRecording()
        {
            Cursor = Cursors.WaitCursor;

            try
            {
                _capturingThread.Interrupt();
                _capturingThread.Join();
            }
            finally
            {
                Cursor = Cursors.Default;
            }

            _recording = false;

            if (!tsbRecord.Enabled)
            {
                tsbRecordWithCam.ShowDropDownArrow = true;
                tsbRecordWithCam.DropDown = _dropDownItems;
                tsbRecordWithCam.Image = Resources.record_cam;
                tsbRecordWithCam.Text = "Record with webcam";
                _dropDownItems = null;
                tsbRecord.Enabled = true;
            }
            else
            {
                tsbRecord.ShowDropDownArrow = true;
                tsbRecord.DropDown = _dropDownItems;
                tsbRecord.Image = Resources.record;
                tsbRecord.Text = "Record";
                _dropDownItems = null;
                tsbRecordWithCam.Enabled = true;
            }

            UnregisterHotKey(Handle, MYKEYID);
            WindowState = FormWindowState.Normal;
            SetForegroundWindow(Handle);

            if (_capturingThreadData.Result != 0)
            {
                statusBar.Items[0].Text = "Recording failed";
                MessageBox.Show("Capturing failed.\n\nError: " + _capturingThreadData.ErrorText);
            }
            else
            {
                SaveFileDialog dlg = new SaveFileDialog();

                if (Program.Cfg.SelectedVideoCodecTab == 0)
                {
                    dlg.DefaultExt = "*.wmv";
                    dlg.Filter = "WMV files (*.wmv)|*.wmv|All files (*.*)|*.*";
                }
                else
                {
                    dlg.DefaultExt = "*.avi";
                    dlg.Filter = "AVI files (*.avi)|*.avi|All files (*.*)|*.*";
                }

                dlg.FileName = "Screencast" + DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
                dlg.Title = "Save captured video as";
                dlg.InitialDirectory = Program.Cfg.LastUsedFolder;

                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    File.Copy(_capturingThreadData.TempFile, dlg.FileName, true);

                    _lastRecordedFile = dlg.FileName;
                    statusBar.Items[0].Text = "Successfully recorded \"" + Path.GetFileName(dlg.FileName) + "\"";
                    tsbPlay.Enabled = File.Exists(_lastRecordedFile);
                    Program.Cfg.LastUsedFolder = Path.GetDirectoryName(dlg.FileName);

                    // open saved video file in the default media player
                    Process.Start(dlg.FileName);
                }
                else
                {
                    statusBar.Items[0].Text = "Canceled";
                }

                try
                {
                    File.Delete(_capturingThreadData.TempFile);
                }
                catch
                {
                }
            }
        }

        protected override void OnLocationChanged(EventArgs e)
        {
            Program.Cfg.WindowLocation = Location;
            base.OnLocationChanged(e);
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (_recording)
            {
                StopRecording();
            }

            Program.Cfg.Save();
            base.OnClosing(e);
        }

        private void tsmiRectangularRegion_Click(object sender, EventArgs e)
        {
            RegionSelector rs = new RegionSelector();

            if (rs.ShowDialog() != DialogResult.Abort)
            {
                _recordingRegion = rs.SelectedRectangle;
                StartRecording(CaptureAreaType.catRegion, sender == tsmiRectangularRegion);
            }
        }
    }
}

MouseHook.cs:

C#
using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.ComponentModel;
using System.Windows.Forms;

namespace ScreenCapturing
{
    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;

        public POINT(int x, int y)
        {
            X = x;
            Y = y;
        }

        public static implicit operator System.Drawing.Point(POINT p)
        {
            return new System.Drawing.Point(p.X, p.Y);
        }

        public static implicit operator POINT(System.Drawing.Point p)
        {
            return new POINT(p.X, p.Y);
        }
    }

    public class MouseHook
    {
        private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
        private static HookProc MouseHookProcedure;
        public event MouseEventHandler MouseActivity;
        private int hMouseHook = 0;

        private const int WM_LBUTTONDOWN = 0x201;
        private const int WM_RBUTTONDOWN = 0x204;
        private const int WM_MOUSEWHEEL = 0x020A;
        private const int WM_LBUTTONDBLCLK = 0x203;
        private const int WM_RBUTTONDBLCLK = 0x206;

        private const int WH_MOUSE = 7;
        private const int WH_MOUSE_LL = 14;

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int UnhookWindowsHookEx(int idHook);

        [StructLayout(LayoutKind.Sequential)]
        private class MouseLLHookStruct
        {
            public POINT pt;
            public int mouseData;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        private class MouseHookStruct
        {
            public POINT pt;
            public int  hwnd;
            public int wHitTestCode;
            public int dwExtraInfo;
        }

        public void SetHook()
        {
            MouseHookProcedure = new HookProc(MouseHookProc);
            IntPtr modulehandle = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);

            hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookProcedure, modulehandle, 0);

            if (hMouseHook == 0)
            {
                int errorCode = Marshal.GetLastWin32Error();

                ReleaseHook(false);

                throw new Win32Exception(errorCode);
            }
        }

        public void ReleaseHook(bool throwExceptions)
        {
            if (hMouseHook != 0)
            {
                int retMouse = UnhookWindowsHookEx(hMouseHook);

                hMouseHook = 0;

                if (retMouse == 0 && throwExceptions)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
        }

        private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if ((nCode >= 0) && (MouseActivity != null))
            {
                MouseLLHookStruct mouseHookStruct = 
                    (MouseLLHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));

                MouseButtons button = MouseButtons.None;
                short mouseDelta = 0;

                switch (wParam)
                {
                    case WM_LBUTTONDOWN:
                        button = MouseButtons.Left;
                        break;
                    case WM_RBUTTONDOWN:
                        button = MouseButtons.Right;
                        break;
                    case WM_MOUSEWHEEL:
                        mouseDelta = (short) ((mouseHookStruct.mouseData >> 16) & 0xffff);
                        break;
                }

                int clickCount = 0;

                if (button != MouseButtons.None)
                    if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2;
                    else clickCount = 1;

                MouseEventArgs e = new MouseEventArgs(button, clickCount, mouseHookStruct.pt.X, 
                    mouseHookStruct.pt.Y, mouseDelta);

                MouseActivity(this, e);
            }

            return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
        }
    }
}

RegionSelector.cs:

C#
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;

namespace ScreenCapturing
{
    public sealed class RegionSelector : Form
    {
        private Bitmap _bmpScreenshot;
        private Rectangle _selectedRectangle = Rectangle.Empty;
        private bool _selecting = false;
        private readonly Cursor _cursor1;
        private readonly Cursor _cursor2;

        public RegionSelector()
        {
            _cursor1 = new Cursor(Path.Combine(Application.StartupPath, "cursor1.cur"));
            _cursor2 = new Cursor(Path.Combine(Application.StartupPath, "cursor2.cur"));

            Cursor = _cursor1;

            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);

            ControlBox = false;
            FormBorderStyle = FormBorderStyle.None;
            Name = "Region Selector";
            StartPosition = FormStartPosition.Manual;
            Location = new Point(0, 0);
            Size = SystemInformation.PrimaryMonitorSize;
            TopMost = true;

            _bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, 
                Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

            using (Graphics g = Graphics.FromImage(_bmpScreenshot))
            {
                g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, 
                    Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            }
        }

        public Rectangle SelectedRectangle
        {
            get { return NormalizeRectangle(_selectedRectangle); }
            set { _selectedRectangle = value; }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.DrawImage(_bmpScreenshot, new Rectangle(0, 0, _bmpScreenshot.Width, _bmpScreenshot.Height));

            Region region = new Region(new Rectangle(0, 0, _bmpScreenshot.Width, _bmpScreenshot.Height));
            Rectangle rectangle = SelectedRectangle;

            region.Exclude(rectangle);

            using (Brush brush = new SolidBrush(Color.FromArgb(174, Color.White)))
            {
                e.Graphics.FillRegion(brush, region);
            }

            if (!rectangle.IsEmpty)
            {
                using (Pen pen = new Pen(Color.Red, 1))
                {
                    pen.Alignment = PenAlignment.Outset;
                    e.Graphics.DrawRectangle(pen, rectangle);
                }
            }
        }

        public static Rectangle NormalizeRectangle(Rectangle r)
        {
            Rectangle result = r;

            if (result.Left > result.Right)
            {
                int width = result.Left - result.Right;
                result.X = result.Right;
                result.Width = System.Math.Abs(width);
            }

            if (result.Top > result.Bottom)
            {
                int height = result.Top - result.Bottom;
                result.Y = result.Bottom;
                result.Height = System.Math.Abs(height);
            }

            return result;
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (_selecting)
            {
                _selectedRectangle.Width = e.X - _selectedRectangle.X;
                _selectedRectangle.Height = e.Y - _selectedRectangle.Y;

                Invalidate();
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (!_selecting)
            {
                _selecting = true;
                _selectedRectangle.Location = e.Location;
                Cursor = _cursor2;
            }
            else
            {
                _selecting = false;

                _selectedRectangle.Width = e.X - _selectedRectangle.X;
                _selectedRectangle.Height = e.Y - _selectedRectangle.Y;

                Close();
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                DialogResult = DialogResult.Abort;
            }

            Close();
        }
    }
}

SettingsForm.cs:

C#
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
using BytescoutScreenCapturingLib;

// NOTE: if you are getting error like "invalid image" related to loading the SDK's dll then 
// try to do the following:
// 1) remove the reference to the SDK by View - Solution Explorer
// then click on References, select Bytescout... reference name and right-click it and select Remove
// 2) To re-add click on the menu: Project - Add Reference
// 3) In "Add Reference" dialog switch to "COM" tab and find Bytescout...
// 4) Select it and click "Add" 
// 5) Recompile the application 
// Note: if you need to run on both x64 and x86 then please make sure you have set "Embed Interop Types" to True for this reference

namespace ScreenCapturing
{
    public partial class SettingsForm : Form
    {
        private readonly Capturer _tempCapturer;

        public SettingsForm()
        {
            InitializeComponent();

            lblProductName.Text = Application.ProductName;
            lblProductVersion.Text = "Version " + Application.ProductVersion;

            _tempCapturer = new Capturer();
            _tempCapturer.RegistrationName = "demo";
            _tempCapturer.RegistrationKey = "demo";

            cmbFPS.Items.AddRange(new object[] { 5f, 7.5f, 10f, 12f, 14.985f, 15f, 19.98f, 20f, 23.976f, 24f, 25f, 29.97f, 30f, 50f, 59.94f, 60 });

            for (int i = 0; i < _tempCapturer.AudioDeviceCount; i++)
            {
                string line = _tempCapturer.GetAudioDeviceName(i);
                cmbAudioDevices.Items.Add(line);
            }

            for (int i = 0; i < cmbAudioDevices.Items.Count; i++)
            {
                if (cmbAudioDevices.Items[i].ToString() == Program.Cfg.AudioDevice)
                {
                    cmbAudioDevices.SelectedIndex = i;
                    break;
                }
            }

            if (cmbAudioDevices.SelectedIndex == -1)
            {
                cmbAudioDevices.SelectedItem = _tempCapturer.CurrentAudioDeviceName;
                Program.Cfg.AudioDevice = _tempCapturer.CurrentAudioDeviceName;
            }

            for (int i = 0; i < _tempCapturer.AudioCodecsCount; i++)
            {
                string codec = _tempCapturer.GetAudioCodecName(i);
                cmbAviAudioCodecs.Items.Add(codec);
            }

            for (int i = 0; i < cmbAviAudioCodecs.Items.Count; i++)
            {
                if (cmbAviAudioCodecs.Items[i].ToString() == Program.Cfg.AviAudioCodec)
                {
                    cmbAviAudioCodecs.SelectedIndex = i;
                    break;
                }
            }

            if (cmbAviAudioCodecs.SelectedIndex == -1)
            {
                cmbAviAudioCodecs.SelectedItem = _tempCapturer.CurrentAudioCodecName;
                Program.Cfg.AviAudioCodec = _tempCapturer.CurrentAudioCodecName;
            }

            if (_tempCapturer.WebCamCount > 0)
            {

                for (int i = 0; i < _tempCapturer.WebCamCount; i++)
                {
                    string camera = _tempCapturer.GetWebCamName(i);
                    cmbWebCameras.Items.Add(camera);
                }

                for (int i = 0; i < cmbWebCameras.Items.Count; i++)
                {
                    if (cmbWebCameras.Items[i].ToString() == Program.Cfg.WebCameraDevice)
                    {
                        cmbWebCameras.SelectedIndex = i;
                        break;
                    }
                }

                if (cmbWebCameras.SelectedIndex == -1 && cmbWebCameras.Items.Count > 0)
                {
                    cmbWebCameras.SelectedIndex = _tempCapturer.CurrentWebCam;
                    Program.Cfg.WebCameraDevice = _tempCapturer.CurrentWebCamName;
                }
            }
            else 
            {
                cmbWebCameras.Enabled = false;
                tbWebCameraHeight.Enabled = false;
                tbWebCameraWidth.Enabled = false;
                tbWebCameraX.Enabled = false;
                tbWebCameraY.Enabled = false;
            }

            for (int i = 0; i < _tempCapturer.VideoCodecsCount; i++)
            {
                string codec = _tempCapturer.GetVideoCodecName(i);
                cmbAviVideoCodecs.Items.Add(codec);
            }

            for (int i = 0; i < cmbAviVideoCodecs.Items.Count; i++)
            {
                if (cmbAviVideoCodecs.Items[i].ToString() == Program.Cfg.AviVideoCodec)
                {
                    cmbAviVideoCodecs.SelectedIndex = i;
                    break;
                }
            }

            if (cmbAviVideoCodecs.SelectedIndex == -1)
            {
                cmbAviVideoCodecs.SelectedItem = _tempCapturer.CurrentVideoCodecName;
                Program.Cfg.AviVideoCodec = _tempCapturer.CurrentVideoCodecName;
            }

            for (int i = 0; i < _tempCapturer.WMVAudioCodecsCount; i++)
            {
                string codec = _tempCapturer.GetWMVAudioCodecName(i);
                cmbWmvAudioCodecs.Items.Add(codec);
            }

            for (int i = 0; i < cmbWmvAudioCodecs.Items.Count; i++)
            {
                if (cmbWmvAudioCodecs.Items[i].ToString() == Program.Cfg.WmvAudioCodec)
                {
                    cmbWmvAudioCodecs.SelectedIndex = i;
                    break;
                }
            }

            if (cmbWmvAudioCodecs.SelectedIndex == -1)
            {
                cmbWmvAudioCodecs.SelectedItem = _tempCapturer.CurrentWMVAudioCodecName;
                Program.Cfg.WmvAudioCodec = _tempCapturer.CurrentWMVAudioCodecName;
            }

            for (int i = 0; i < _tempCapturer.WMVVideoCodecsCount; i++)
            {
                string codec = _tempCapturer.GetWMVVideoCodecName(i);
                cmbWmvVideoCodecs.Items.Add(codec);
            }

            for (int i = 0; i < cmbWmvVideoCodecs.Items.Count; i++)
            {
                if (cmbWmvVideoCodecs.Items[i].ToString() == Program.Cfg.WmvVideoCodec)
                {
                    cmbWmvVideoCodecs.SelectedIndex = i;
                    break;
                }
            }

            if (cmbWmvVideoCodecs.SelectedIndex == -1)
            {
                cmbWmvVideoCodecs.SelectedItem = _tempCapturer.CurrentWMVVideoCodecName;
                Program.Cfg.WmvVideoCodec = _tempCapturer.CurrentWMVVideoCodecName;
            }

            cbEnableAudio.Checked = Program.Cfg.EnableAudio;
            cbResizeVideo.Checked = Program.Cfg.ResizeOutputVideo;
            tbWidth.Text = Program.Cfg.OutputWidth.ToString();
            tbHeight.Text = Program.Cfg.OutputHeight.ToString();
            cbKeepAspectRatio.Checked = Program.Cfg.KeepAspectRatio;
            cmbFPS.Text = Program.Cfg.FPS.ToString();
            cbLog.Checked = Program.Cfg.WriteLog;

            tbWebCameraX.Text = Program.Cfg.WebCameraWindowX.ToString();
            tbWebCameraY.Text = Program.Cfg.WebCameraWindowY.ToString();
            tbWebCameraWidth.Text = Program.Cfg.WebCameraWindowWidth.ToString();
            tbWebCameraHeight.Text = Program.Cfg.WebCameraWindowHeight.ToString();

            cmbAudioLines.Enabled = cbEnableAudio.Checked;
            tbWidth.Enabled = cbResizeVideo.Checked;
            tbHeight.Enabled = cbResizeVideo.Checked;
            cbKeepAspectRatio.Enabled = cbResizeVideo.Checked;

            tabControl2.SelectedIndex = Program.Cfg.SelectedVideoCodecTab;

            cbCaptureMouseCursor.Checked = Program.Cfg.CaptureMouseCursor;
            cbShowMouseHotSpot.Checked = Program.Cfg.ShowMouseHotSpot;
            tbMouseAnimationDuration.Text = Program.Cfg.MouseAnimationDuration.ToString(CultureInfo.InvariantCulture);
            tbHotSpotRadius.Text = Program.Cfg.MouseSpotRadius.ToString(CultureInfo.InvariantCulture);
            ccMouseHotSpotColor.ForeColor = Program.Cfg.MouseHotSpotColor;
            cbAnimateMouseClicks.Checked = Program.Cfg.AnimateMouseClicks;
            cbAnimateMouseButtons.Checked = Program.Cfg.AnimateMouseButtons;
            ccMouseCursorLeftClickAnimationColor.ForeColor = Program.Cfg.MouseCursorLeftClickAnimationColor;
            ccMouseCursorRightClickAnimationColor.ForeColor = Program.Cfg.MouseCursorRightClickAnimationColor;

            cmbFrameType.Items.Add("None");
            cmbFrameType.Items.Add("Solid");
            cmbFrameType.Items.Add("Dashed");
            cmbFrameType.Items.Add("Dotted");
            cmbFrameType.SelectedIndex = (int) Program.Cfg.CaptureAreaBorderType;
            ccFrameColor.ForeColor = Program.Cfg.CaptureAreaBorderColor;
            tbFrameWidth.Text = Program.Cfg.CaptureAreaBorderWidth.ToString(CultureInfo.InvariantCulture);
        }

        private void cbEnableAudio_CheckedChanged(object sender, EventArgs e)
        {
            cmbAudioLines.Enabled = cbEnableAudio.Checked;
        }

        private void cbResizeVideo_CheckedChanged(object sender, EventArgs e)
        {
            tbWidth.Enabled = cbResizeVideo.Checked;
            tbHeight.Enabled = cbResizeVideo.Checked;
            cbKeepAspectRatio.Enabled = cbResizeVideo.Checked;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {

            if (cmbWmvAudioFormats.SelectedIndex == -1)
            {
                MessageBox.Show("Please select WMV Audio Format", Application.ProductName);
                return;
            }

            try
            {
                Program.Cfg.SelectedVideoCodecTab = tabControl2.SelectedIndex;
                Program.Cfg.AudioDevice = cmbAudioDevices.SelectedItem.ToString();
                if (cmbAudioLines.SelectedItem != null)
                {
                    Program.Cfg.AudioLine = cmbAudioLines.SelectedItem.ToString();
                }
                Program.Cfg.EnableAudio = cbEnableAudio.Checked;
                Program.Cfg.AviAudioCodec = cmbAviAudioCodecs.SelectedItem.ToString();
                Program.Cfg.AviVideoCodec = cmbAviVideoCodecs.SelectedItem.ToString();
                Program.Cfg.WmvAudioCodec = cmbWmvAudioCodecs.SelectedItem.ToString();
                Program.Cfg.WmvAudioFormat = cmbWmvAudioFormats.SelectedIndex;
                Program.Cfg.WmvVideoCodec = cmbWmvVideoCodecs.SelectedItem.ToString();
                Program.Cfg.ResizeOutputVideo = cbResizeVideo.Checked;
                Program.Cfg.OutputWidth = Int32.Parse(tbWidth.Text);
                Program.Cfg.OutputHeight = Int32.Parse(tbHeight.Text);
                Program.Cfg.KeepAspectRatio = cbKeepAspectRatio.Checked;
                Program.Cfg.FPS = float.Parse(cmbFPS.Text);
                Program.Cfg.WriteLog = cbLog.Checked;
                if (cmbWebCameras.Enabled)
                {
                    Program.Cfg.WebCameraDevice = cmbWebCameras.SelectedItem.ToString();
                    Program.Cfg.WebCameraWindowX = Int32.Parse(tbWebCameraX.Text);
                    Program.Cfg.WebCameraWindowY = Int32.Parse(tbWebCameraY.Text);
                    Program.Cfg.WebCameraWindowWidth = Int32.Parse(tbWebCameraWidth.Text);
                    Program.Cfg.WebCameraWindowHeight = Int32.Parse(tbWebCameraHeight.Text);
                }
                Program.Cfg.CaptureMouseCursor = cbCaptureMouseCursor.Checked;
                Program.Cfg.ShowMouseHotSpot = cbShowMouseHotSpot.Checked;
                Program.Cfg.MouseAnimationDuration = Convert.ToInt32(tbMouseAnimationDuration.Text);
                Program.Cfg.MouseSpotRadius = Convert.ToInt32(tbHotSpotRadius.Text);
                Program.Cfg.MouseHotSpotColor = ccMouseHotSpotColor.ForeColor;
                Program.Cfg.AnimateMouseClicks = cbAnimateMouseClicks.Checked;
                Program.Cfg.AnimateMouseButtons = cbAnimateMouseButtons.Checked;
                Program.Cfg.MouseCursorLeftClickAnimationColor = ccMouseCursorLeftClickAnimationColor.ForeColor;
                Program.Cfg.MouseCursorRightClickAnimationColor = ccMouseCursorRightClickAnimationColor.ForeColor;
                Program.Cfg.CaptureAreaBorderType = (CaptureAreaBorderType) cmbFrameType.SelectedIndex;
                Program.Cfg.CaptureAreaBorderColor = ccFrameColor.ForeColor;
                Program.Cfg.CaptureAreaBorderWidth = Int32.Parse(tbFrameWidth.Text);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, Application.ProductName);
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Process prc = new Process();
            prc.StartInfo.FileName = "http://www.bytescout.com/";
            prc.StartInfo.UseShellExecute = true;

            try
            {
                prc.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName);
            }
        }

        private void btnVideoCodecProps_Click(object sender, EventArgs e)
        {
            Capturer tempCapturer = new Capturer();
            tempCapturer.RegistrationName = "demo";
            tempCapturer.RegistrationKey = "demo";

            tempCapturer.CurrentVideoCodecName = cmbAviVideoCodecs.SelectedItem.ToString();


            try
            {
                tempCapturer.ShowVideoCodecSettingsDialog(0);
            }
            catch (InvalidCastException)
            {
                MessageBox.Show("This codec has no properties dialog.", Application.ProductName);
            }
            catch (Exception exception)
            {
                MessageBox.Show("Failed to open the codec properties dialog.\n" + exception.Message, Application.ProductName);
            }
        }

        private void linkViewLog_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string logFile = Path.GetTempPath() + Application.ProductName + " log.txt";

            if (File.Exists(logFile))
            {
                Process prc = new Process();
                prc.StartInfo.FileName = logFile;
                prc.StartInfo.UseShellExecute = true;

                try
                {
                    prc.Start();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, Application.ProductName);
                }
            }
        }

        private void cmbAudioDevices_SelectedIndexChanged(object sender, EventArgs e)
        {
            _tempCapturer.CurrentAudioDeviceName = cmbAudioDevices.SelectedItem.ToString();

            cmbAudioLines.Items.Clear();

            for (int i = 0; i < _tempCapturer.CurrentAudioDeviceLineCount; i++)
            {
                string line = _tempCapturer.GetCurrentAudioDeviceLineName(i);
                cmbAudioLines.Items.Add(line);
            }

            for (int i = 0; i < cmbAudioLines.Items.Count; i++)
            {
                if (cmbAudioLines.Items[i].ToString() == Program.Cfg.AudioLine)
                {
                    cmbAudioLines.SelectedIndex = i;
                    break;
                }
            }

            if (cmbAudioLines.SelectedIndex == -1)
            {
                for (int j = 0; j < cmbAudioLines.Items.Count; j++ )
                {
                    string tmpS = cmbAudioLines.Items[j].ToString().ToUpper();
                    if (tmpS.IndexOf("MIC") > -1)
                    {
                        cmbAudioLines.SelectedIndex = j;
                    }
                }
            }

            if (cmbAudioLines.SelectedIndex == -1)
            {
                cmbAudioLines.SelectedItem = _tempCapturer.CurrentAudioDeviceLineName;
                Program.Cfg.AudioLine = _tempCapturer.CurrentAudioDeviceLineName;
            }
        }

        private void cmbWmvAudioCodecs_SelectedIndexChanged(object sender, EventArgs e)
        {
            _tempCapturer.CurrentWMVAudioCodecName = cmbWmvAudioCodecs.SelectedItem.ToString();

            cmbWmvAudioFormats.Items.Clear();

            // Get list of available WMV audio formats
            for (int i = 0; i < _tempCapturer.WMVAudioFormatCount; i++)
            {
                string codec = _tempCapturer.GetWMVAudioFormatDescription(i);
                cmbWmvAudioFormats.Items.Add(codec);
            }

            for (int i = 0; i < cmbWmvAudioFormats.Items.Count; i++)
            {
                if (i == Program.Cfg.WmvAudioFormat)
                {
                    cmbWmvAudioFormats.SelectedIndex = i;
                    break;
                }
            }

            if (cmbWmvAudioFormats.SelectedIndex == -1)
            {
                cmbWmvAudioFormats.SelectedIndex = _tempCapturer.CurrentWMVAudioFormat;
                Program.Cfg.WmvAudioFormat = _tempCapturer.CurrentWMVAudioFormat;
            }
        }
    }
}