Click here to Skip to main content
Click here to Skip to main content

Print Screen in C#

, 21 Aug 2009
Rate this:
Please Sign up or sign in to vote.
How to Capture the PrintScreen keypress and Save it to an Image

Introduction

I did some research and found a nice way to create a screen capture only to find that our employees continue to use the PrintScreen button. So, I needed a way to capture the PrintScreen keypress, which turned out to be trivial - after I learned the right functions to listen to.  

Background

Every time someone in our organization sends out an email with an embedded image, the server has to store that file for every user. If the email is replied to or forwarded, the embedded image is still sent unless the sender is thoughtful enough to remove it first. This results in a lot of storage space being used on the Mail Server, that is not necessary. 

Handling the PrintScreen button allows a developer to convert the screen capture to a file, which can then be attached to an email. The file format chosen for the image is typically smaller than the Microsoft Office embedded image, and attachments are not included in email replies. Hence, handling the PrintScreen keypress will result in the overall tax on the Mail Server to go down. 

Using the Code 

Two override routines must first be added to your main application:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (((Keys)(int)msg.WParam) == Keys.PrintScreen) {
    ScreenCapture(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
  }
  return base.ProcessCmdKey(ref msg, keyData);
}

protected override bool ProcessKeyEventArgs(ref Message msg) {
  if (((Keys)(int)msg.WParam) == Keys.PrintScreen) {
    ScreenCapture(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
  }
  return base.ProcessKeyEventArgs(ref msg);
}

Notice that the base process is not blocked! If I want to continue on to Microsoft Paint and manually paste my screen capture, I can still do that, too.  Also, notice that I specify the Desktop to be the default location for saving the files (because, sadly, most of our employees don't really know how to navigate the Windows file structure). 

To handle the Screen Capture, I have a very generic routine called ScreenCapture which I initially learned from TeboScreen. My version accepts an initial directory for saving the screen shot and uses a simple BackgroundWorker to create the image, then tries to display the image after it has completed:

public void ScreenCapture(string initialDirectory) {
  using (BackgroundWorker worker = new BackgroundWorker()) {
    Thread.Sleep(0);
    this.Refresh();
    worker.DoWork += delegate(object sender, DoWorkEventArgs e) {
      BackgroundWorker wkr = sender as BackgroundWorker;
      Rectangle bounds = new Rectangle(Location, Size);
      Thread.Sleep(300);
      Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
      using (Graphics g = Graphics.FromImage(bitmap)) {
        g.CopyFromScreen(Location, Point.Empty, bounds.Size);
      }
      e.Result = bitmap;
    };
    worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) {
      if (e.Error != null) {
        Exception err = e.Error;
        while (err.InnerException != null) {
          err = err.InnerException;
        }
        MessageBox.Show(err.Message, "Screen Capture", 
			MessageBoxButtons.OK, MessageBoxIcon.Stop);
      } else if (e.Cancelled == true) {
      } else if (e.Result != null) {
        if (e.Result is Bitmap) {
          Bitmap bitmap = (Bitmap)e.Result;
          using (SaveFileDialog dlg = new SaveFileDialog()) {
            dlg.Title = "Image Capture: Image Name, File Format, and Destination";
            dlg.FileName = "Screenshot";
            dlg.InitialDirectory = initialDirectory;
            dlg.DefaultExt = "jpg";
            dlg.AddExtension = true;
            dlg.Filter = "Jpeg Image 
	     (JPG)|*.jpg|PNG Image|*.png|GIF Image (GIF)|*.gif|Bitmap (BMP)|*.bmp" +
              "|EWM Image|*.emf|TIFF Image|*.tiff|Windows Metafile (WMF)|*.wmf|
	     Exchangable image file|*.exif";
            dlg.FilterIndex = 1;
            if (dlg.ShowDialog(this) == DialogResult.OK) {
              ImageFormat fmtStyle;
              switch (dlg.FilterIndex) {
                case 2: fmtStyle = ImageFormat.Jpeg; break;
                case 3: fmtStyle = ImageFormat.Gif; break;
                case 4: fmtStyle = ImageFormat.Bmp; break;
                case 5: fmtStyle = ImageFormat.Emf; break;
                case 6: fmtStyle = ImageFormat.Tiff; break;
                case 7: fmtStyle = ImageFormat.Wmf; break;
                case 8: fmtStyle = ImageFormat.Exif; break;
                default: fmtStyle = ImageFormat.Png; break;
              }
              bitmap.Save(dlg.FileName, fmtStyle);
              try {
                Process.Start(dlg.FileName);
              } catch (Exception) {
                try { // try IE
                  Process.Start("iexplore.exe", dlg.FileName);
                } catch (Exception) { }
              }
            }
          }
        }
      }
    };
    worker.RunWorkerAsync();
  }
}

History

This is my current, only version.

License

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

About the Author

jp2code
Software Developer Martin Resource Management
United States United States
Looking to become a powerful developer one of these days.
Follow on   Twitter   Google+

Comments and Discussions

 
QuestionCustom application or third party solution? Pinmemberarc207210-Mar-11 13:12 
AnswerRe: Custom application or third party solution? Pinmemberjp2code11-Mar-11 3:03 
QuestionKey capture PinmemberDavid6131-Aug-09 16:19 
AnswerRe: Key capture Pinmemberjp2code31-Aug-09 17:16 
GeneralRe: Key capture PinmemberDavid619-Sep-09 11:14 
GeneralGraphics.CopyFromScreen PinmemberThe_Mega_ZZTer21-Aug-09 11:23 
GeneralRe: Graphics.CopyFromScreen Pinmemberjp2code21-Aug-09 11:32 
Thanks!
 
I was worried that my first question was going to be, "Can you show me how to do this in VB?"
 
Now, their question is solved - more or less.
 
Regards,
~Joe Pool
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    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 | Mobile
Web02 | 2.8.140721.1 | Last Updated 21 Aug 2009
Article Copyright 2009 by jp2code
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid