Create Full Featured Screen Capturing App - C#
Screen Capturing SDK sample in C# demonstrating ‘Create Full Featured Screen Capturing App’
CapturingThread.cs
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;
                Marshal.ReleaseComObject(capturer);
                return;
            }
            try
            {
                Thread.Sleep(Timeout.Infinite);
            }
            catch (ThreadInterruptedException)
            {
                capturer.Stop();
                data.Result = 0;
            }
            catch (Exception ex)
            {
                data.ErrorText = ex.Message;
                data.Result = 1;
            }
            finally
            {
                Marshal.ReleaseComObject(capturer);
            }
        }
    }
}
ColorControl.cs
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
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", 1024); } set { Options["OutputWidth"] = value; } }
        public int OutputHeight { get { return Get<int>("OutputHeight", 600); } 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
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;
		}
	}
}
CustomMessageBox.designer.cs
��n a m e s p a c e   S c r e e n C a p t u r i n g 
 
 { 
 
 	 p a r t i a l   c l a s s   C u s t o m M e s s a g e B o x 
 
 	 { 
 
 	 	 / / /   <