Click here to Skip to main content
11,929,232 members (54,902 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


68 bookmarked

ScreenCap: C# Screen Capture Application (branched from TeboScreen by GuyThiebaut)

, 24 Feb 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
A C# screen capture application based on TeboScreen by GuyThiebaut


This application runs in the background and takes over the Print Screen button allowing for capture of the screen in two different ways:

  • Capture Screen: This does what is says; it basically captures the whole of the screen.
  • Capture Area: Holding down the left mouse button, users draw a rectangle specifying which part of the screen they wish to capture. The user can then select one of three methods to send the area behind the drawn rectangle (clipboard, printer, email). Once drawn, the rectangle can be resized and moved around the screen before sending the image to the desired destination.


My employer recently migrated from a legacy Telnet application, to a Windows application. The legacy app allowed users to hit the Print Screen button and send their session screen to a printer. Many of our users are not experienced Windows users and it was necessary for them to be able to easily capture a screen and send it to a printer without having to hack around the Windows environment.

After doing some searches on the internet for a good screen capture program to accomplish this, most of what we found was weak and costly. I knew this project shouldn't be much trouble for me to write; So, I set out to find some open source to help me accomplish the task quickly and came across the "TeboScreen" Application by GuyThiebaut here on Code Project: TeboScreen

Using the code

There were a few things I focused on to enhance the original TeboScreen:

  • Run in the background and become activated when the Print Screen button is pressed.
  • Support for dual monitors, regardless whether there is a size difference in monitors.
  • Automatically send screen capture to three devices: Clipboard, Printer, and EMail.
  • Ease of use for the end user.

With this in mind, I won't go into redundant details covered in the original project.

Running In Background

All we need to do is add a handler for the Shown event of the main form

private void ControlPanel_Shown(object sender, EventArgs e)


Handling Print Screen Button

This required writing an assembly, per this discussion KeyHook.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Reflection;

namespace KeyHook
    public class KeyHooker

        public static event EventHandler PrintScreenBtnEvent = null;

        public struct KBDLLHOOKSTRUCT
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;

            public int extraInfo;

        public delegate int HookProc(int nCode, int wParam, IntPtr ptrKBDLLHOOKSTRUCT);

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

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

        private static IntPtr kbh_Handle;
        private static HookProc kbh_HookProc;

        private const int VK_SNAPSHOT = 0x2C;
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_SYSKEYDOWN = 0x0104;
        private const int WH_KEYBOARD_LL = 13;

        private static int LowLevelKeyboardProc(int nCode, int wParam, IntPtr lParam)
            if (nCode < 0)
                CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
                return 0;

            if (wParam == WM_KEYDOWN)
                IntPtr kbdll = lParam;
                KBDLLHOOKSTRUCT kbdllstruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(kbdll, typeof(KBDLLHOOKSTRUCT));

                if (kbdllstruct.vkCode == VK_SNAPSHOT)
                    if (PrintScreenBtnEvent != null)
                        PrintScreenBtnEvent(null, new EventArgs());

                    return -1;


            return CallNextHookEx(kbh_Handle, nCode, wParam, lParam);

        public static void HookKeyboard()
                kbh_HookProc = LowLevelKeyboardProc;

                kbh_Handle = SetWindowsHookEx(WH_KEYBOARD_LL, kbh_HookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);

                if (kbh_Handle == IntPtr.Zero)
                    throw new Win32Exception(Marshal.GetLastWin32Error());
            catch (Exception ex)
                System.Diagnostics.Debug.WriteLine(String.Format("ERROR: {0}", ex.Message));

To implement this, I added a delegate to the KeyHooker class:

public static event EventHandler PrintScreenBtnEvent = null;

Dual Monitor Support

To do this, I had to look at the System.Windows.Forms.Screen class. Below is a snippet of code used to store the index of the main monitor. The main monitor is what the TeboScreen application is based on, so any code in this project for the main monitor will be the same. I had to make adjustments to the code if monitor being processed is not the main monitor.

private int GetPrimaryMonIdx()
    Screen[] sc;
        sc = Screen.AllScreens;
        int idx = 0;

        foreach (Screen s in sc)
            if (s.Bounds.Left == System.Windows.Forms.Screen.PrimaryScreen.Bounds.Left)

    return (idx <= sc.Length) ? idx : 0;

Exiting The Program

When the main screen (from the screen shot above) is showing and has focus hit Ctrl-Alt-S and then X.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Patrick Harris
Software Developer (Senior) Sukup Manufacturing Co.
United States United States
I've been a software developer for over 25 years. I've worked on commercial grade Point of Sale and Order Entry software applications. I've done extensive research in database development and have learned techniques which have enabled me to tackle database problems particularly in relation to optimizing slowness by thinking outside the box (the box being the database engine's query optimizer).

I've worked with Symbol Technology Handheld barcode scanners quite a bit. I've written Sqllite libraries that run on these devices which have greatly increased local storage capabilities.

Currently I have migrated away from local application development and am now developing client/server solutions in ASP.NET. I am, at the moment, learning MVC, MVP, and MVVM design patterns.

You may also be interested in...

Comments and Discussions

QuestionJust what I was looking for Pin
MarkNZed24-Sep-14 4:11
memberMarkNZed24-Sep-14 4:11 
AnswerRe: Just what I was looking for Pin
MarkNZed24-Sep-14 5:56
memberMarkNZed24-Sep-14 5:56 
SuggestionMessage Automatically Removed Pin
31-Aug-14 1:50
memberMember 1104824331-Aug-14 1:50 
QuestionVery useful, thank you. Pin
Edward Piccoli20-Mar-14 2:57
memberEdward Piccoli20-Mar-14 2:57 
AnswerRe: Very useful, thank you. Pin
Patrick Harris21-Mar-14 0:54
memberPatrick Harris21-Mar-14 0:54 
SuggestionScreen Shots Pin
Maimonides21-Jul-13 5:20
professionalMaimonides21-Jul-13 5:20 
GeneralMy vote of 5 Pin
Kanasz Robert27-Sep-12 11:48
mvpKanasz Robert27-Sep-12 11:48 
GeneralRe: My vote of 5 Pin
Patrick Harris30-Sep-12 15:35
memberPatrick Harris30-Sep-12 15:35 
QuestionResolution and exact position Pin
jvogt16-Aug-12 22:16
memberjvogt16-Aug-12 22:16 
AnswerRe: Resolution and exact position Pin
Patrick Harris17-Aug-12 8:12
memberPatrick Harris17-Aug-12 8:12 
GeneralMy vote of 5 Pin
@k@ ?28-Feb-12 5:53
member@k@ ?28-Feb-12 5:53 
GeneralRe: My vote of 5 Pin
Patrick Harris29-Feb-12 3:36
memberPatrick Harris29-Feb-12 3:36 
NewsAnother Update Pin
Patrick Harris24-Feb-12 13:45
memberPatrick Harris24-Feb-12 13:45 
QuestionNice tool Pin
GanesanSenthilvel19-Feb-12 15:56
memberGanesanSenthilvel19-Feb-12 15:56 
GeneralRe: Nice tool Pin
Patrick Harris19-Feb-12 16:22
memberPatrick Harris19-Feb-12 16:22 
NewsNew Feature Pin
Patrick Harris19-Feb-12 10:25
memberPatrick Harris19-Feb-12 10:25 
I just added a new feature for color inversion. I noticed that when I was on a black desktop I could not see my selection. Use "Z" on the keyboard now to invert the colors.
NewsLatest Bug Fix Pin
Patrick Harris19-Feb-12 6:22
memberPatrick Harris19-Feb-12 6:22 
NewsBugs Fixed Today Pin
Patrick Harris17-Feb-12 14:02
memberPatrick Harris17-Feb-12 14:02 
BugGreat tool Pin
lordofm17-Feb-12 0:19
memberlordofm17-Feb-12 0:19 
AnswerRe: Great tool Pin
Patrick Harris17-Feb-12 4:05
memberPatrick Harris17-Feb-12 4:05 
GeneralMy vote of 5 Pin
GuyThiebaut16-Feb-12 8:44
memberGuyThiebaut16-Feb-12 8:44 
GeneralRe: My vote of 5 Pin
Patrick Harris16-Feb-12 12:07
memberPatrick Harris16-Feb-12 12:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.151126.1 | Last Updated 24 Feb 2012
Article Copyright 2012 by Patrick Harris
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid