Is there a one button way to save a screenshot directly to a file in Windows?
This is a very important question as the 316K views shows as of 2021. Asked in 2008, SO closed this question around 2015 as being off-topic, probably because of the last question below.
In Windows XP, one can press Alt-PrintScreen to copy an image of the active window, or Ctrl-PrintScreen to copy an image of the full desktop.
This can then be pasted into applications that accept images: Photoshop, Microsoft Word, etc.
I'm wondering: Is there a way to save the screenshot directly to a file? Do I really have to open an image program, like Paint.net or Photoshop, simply to paste an image, then save it?
You can code something pretty simple that will hook the PrintScreen and save the capture in a file.
Here is something to start to capture and save to a file. You will just need to hook the key "Print screen".
using System;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
public class CaptureScreen
{
static public void Main(string[] args)
{
try
{
Bitmap capture = CaptureScreen.GetDesktopImage();
string file = Path.Combine(Environment.CurrentDirectory, "screen.gif");
ImageFormat format = ImageFormat.Gif;
capture.Save(file, format);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
public static Bitmap GetDesktopImage()
{
WIN32_API.SIZE size;
IntPtr hDC = WIN32_API.GetDC(WIN32_API.GetDesktopWindow());
IntPtr hMemDC = WIN32_API.CreateCompatibleDC(hDC);
size.cx = WIN32_API.GetSystemMetrics(WIN32_API.SM_CXSCREEN);
size.cy = WIN32_API.GetSystemMetrics(WIN32_API.SM_CYSCREEN);
m_HBitmap = WIN32_API.CreateCompatibleBitmap(hDC, size.cx, size.cy);
if (m_HBitmap!=IntPtr.Zero)
{
IntPtr hOld = (IntPtr) WIN32_API.SelectObject(hMemDC, m_HBitmap);
WIN32_API.BitBlt(hMemDC, 0, 0,size.cx,size.cy, hDC, 0, 0, WIN32_API.SRCCOPY);
WIN32_API.SelectObject(hMemDC, hOld);
WIN32_API.DeleteDC(hMemDC);
WIN32_API.ReleaseDC(WIN32_API.GetDesktopWindow(), hDC);
return System.Drawing.Image.FromHbitmap(m_HBitmap);
}
return null;
}
protected static IntPtr m_HBitmap;
}
public class WIN32_API
{
public struct SIZE
{
public int cx;
public int cy;
}
public const int SRCCOPY = 13369376;
public const int SM_CXSCREEN=0;
public const int SM_CYSCREEN=1;
[DllImport("gdi32.dll",EntryPoint="DeleteDC")]
public static extern IntPtr DeleteDC(IntPtr hDc);
[DllImport("gdi32.dll",EntryPoint="DeleteObject")]
public static extern IntPtr DeleteObject(IntPtr hDc);
[DllImport("gdi32.dll",EntryPoint="BitBlt")]
public static extern bool BitBlt(IntPtr hdcDest,int xDest,int yDest,int wDest,int hDest,IntPtr hdcSource,int xSrc,int ySrc,int RasterOp);
[DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport ("gdi32.dll",EntryPoint="SelectObject")]
public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp);
[DllImport("user32.dll", EntryPoint="GetDesktopWindow")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll",EntryPoint="GetDC")]
public static extern IntPtr GetDC(IntPtr ptr);
[DllImport("user32.dll",EntryPoint="GetSystemMetrics")]
public static extern int GetSystemMetrics(int abc);
[DllImport("user32.dll",EntryPoint="GetWindowDC")]
public static extern IntPtr GetWindowDC(Int32 ptr);
[DllImport("user32.dll",EntryPoint="ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc);
}
Update Here is the code to hook the PrintScreen (and other key) from C#: