Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

OneNote Style Screen Capture Utility - with Preview and Auto Save Options

0.00/5 (No votes)
2 Dec 2011 1  
A utility to capture and crop the screen just like OneNote (Office 2010)
Preview_Media_updated.png

Introduction

Most of you who work with 'OneNote' might have experienced the screen capturing future added to the Office 2010 package. Unlike the conventional print screen feature, this facility provides an option to freeze the screen and crop the image on the active desktop.

I found this really helpful when creating Office 2010 like Ribbon for our application to get the minute details of the Office 2010 visuals. Here is a utility that gives you the same experience to capture the screen and crop.

Background

Here is how it works:

  • The main app runs in the background and listens to the HOT KEY (Win Key + S) to capture the screen.
  • As soon as the Main app receives the WM_HOTKEY message, the main app captures the desktop and passes it onto an adorner window.
  • The adorner window presents the opaque image on top of all the other windows for you to crop with the mouse.
  • The cropped image is then made to the clipboard and that's it!

Using the Code

Listening to the HOTKEY

HOTKEY is the option the users can bring this application alive. To make this work, this application user native pinvokes to register and unregister HOTKEY.

RegisterHotKey

This function requires a handle to the calling window to which the WM_HOTKEY message will be posted when the key combination is pressed, and an ID as a reference to the HOTKEY, (there exists a range for this value, take a look at the Remarks section of the documentation) and a modifier value specifying the modifier key with which the key parameter is to be registered.

Win key along with 'S' is used as a HOTKEY for this application and the code for function is as in the following code block.

// Definition of Native Method.
[DllImport("user32.dll", SetLastError = true)]
private static extern int RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);

//Param : A handle to the window, an id for the hotkey ,id of modifer key and the key.
RegisterHotKey(this.Handle, hotKeyId,/*MOD_WIN*/0x0008, Keys.S);

UnregisterHotKey

Un-registering a HOTKEY is relatively simple, it requires a handle to the calling window and the id used while registering the HOTKEY.

// A handle to the calling window and the id used while registering.
UnregisterHotKey(this.Handle, hotKeyId);

The next big thing is to get the bitmap of the desktop window, there exists a native function GetDesktopWindow to get the desktop handle with which you can copy the graphics context to a bitmap. Alternatively, this can be done with the Graphics.CopyFromScreen method as follows later this bitmap is projected as a opaque image, providing a frozen desktop appearance.

public static Bitmap GenerateScreenBitmap()
{
    Rectangle scrBounds = Screen.PrimaryScreen.Bounds;
    Bitmap bmp = new Bitmap(scrBounds.Width, scrBounds.Height);
    Graphics g = Graphics.FromImage(bmp);

    g.CopyFromScreen(Point.Empty, Point.Empty, 
	scrBounds.Size, CopyPixelOperation.SourceCopy);

    bitmapCache = bmp;

    return bmp;
}

The resultant bitmap image is set as the background of an adorner window and the window is shown, this adorner window overrides its OnPaint method to fill the region with a alpha blend to give an opaque look. he adorner processes the mouse events to determine the cropped region. dragStart dragStop determines the upper left and bottom right points of the cropped image.

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

    Region clip = e.Graphics.Clip;

    if (mousePressed && dragStart!= Point.Empty && dragStart != dragStop)
    {
        Rectangle rect = Rectangle.FromLTRB
		(dragStart.X, dragStart.Y, dragStop.X, dragStop.Y);

        using (Pen pen = new Pen(Color.Black))
        {
            e.Graphics.DrawRectangle(pen, Rectangle.Inflate(rect,-1,-1));
        }

        // Excludes the cropped region and paints the remaining surface.
        e.Graphics.SetClip(rect, CombineMode.Exclude);
    }

    using (Brush brush = new SolidBrush(Color.FromArgb(210,Color.WhiteSmoke)))
    {
        e.Graphics.FillRectangle(brush, this.ClientRectangle);
    }

    e.Graphics.SetClip(clip, CombineMode.Replace);
}

The adorner will be closed when a mouse button is pressed or when a key is pressed, and the dragStart and dragStop points are passed to the main window, which copies the target cropped image to the clipboard.

Rectangle rect = Rectangle.FromLTRB(adornerWindow.DragStart.X, 
	adornerWindow.DragStart.Y, adornerWindow.DragStop.X, adornerWindow.DragStop.Y);

Bitmap result = new Bitmap(rect.Width, rect.Height);
Graphics g = Graphics.FromImage(result);

g.DrawImage(bitmapCache,new Rectangle(Point.Empty,result.Size), rect, GraphicsUnit.Pixel);

Clipboard.SetImage(result);

And that's it, the image is now copied to the clipboard, you can paste it wherever required.

Points of Interest

This utility provides an option to start this application when windows starts and here is how you can make it, it just requires to place the application start up path and application name in a registry key at the following location:

string RegKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

RegistryKey startUpKey = Registry.CurrentUser.OpenSubKey(RegKey, true);
                
ToolStripMenuItem menuItem = (sender as ToolStripMenuItem);
menuItem.Checked = !menuItem.Checked;

if (menuItem.Checked)
    startUpKey.SetValue(APP_NAME, Application.ExecutablePath);
else
    startUpKey.DeleteValue(APP_NAME, false);

Hope this helps in your day to day work. Leave your valuable comments and suggestions. Happy coding!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here