Working with the Clipboard in VB.NET and C#
Introduction
Through the years. Access to the Clipboard object has become easier and easier. You might find it strange to have an entire article dedicated to the Clipboard object but the sad fact of the matter is it's obvious properties and methods got lost in translation. Better said, people still do not know what the Clipboard object is, how to differentiate between copied information, and how to use it. I hope with this article I will demonstrate its proper use, and eliminate confusion.
Logic
With the advent of .NET, accessing the Clipboard from text fields has become so easy. Many a programmer does not realize this, especially if they come from a VB 6 background. The Textboxes come with built in Clipboard methods (Copy, Cut, Paste ) built in. We will make use of these methods, as well as make use of the Clipboard object to do the text manipulation.
With Pictureboxes we will make use of the Clipboard methods, as well as the BitBlt API. The reason for this is so that you can see which one of these two methods are better. The BitBlt API is much more capable of handling various picture types, as well as transparancy.
Design
Fire up Visual Studio 2012 and create a Windows Forms project with either VB.NET or C#. Give your form an appropriate name, or use mine, and add the following controls to it:
| Control | Property | Setting |
| Form1 | Name | frmEasyClipBoard |
| Size | 474, 311 | |
| Text | Copying Cutting & Pasting | |
| TextBox | Name | txtSource |
| Location | 0, 0 | |
| TextBox | Name | txtDest |
| Location | 0, 58 | |
| Button | Name | btnCopyTXT |
| Location | 126, 0 | |
| Text | Copy With Textbox | |
| Button | Name | btnCutTXT |
| Location | 126, 29 | |
| Text | Cut With Textbox | |
| Button | Name | btnPasteTXT |
| Location | 126, 58 | |
| Text | Paste With TextBox | |
| Button | Name | btnClear |
| Location | 244, 29 | |
| Text | Clear | |
| Button | Name | btnClipCopy |
| Location | 304, 0 | |
| Text | Clipboard Copy | |
| Button | Name | btnClipCut |
| Location | 304, 29 | |
| Text | Clipboard Cut | |
| Button | Name | btnClipPaste |
| Location | 304, 58 | |
| Text | Clipboard Paste | |
| PictureBox | Name | picSource |
| Image | Any picture, or use mine which is supplied in the download | |
| Location | 34, 107 | |
| PictureBox | Name | picDest |
| Location | 226, 87 | |
| Button | Name | btnClipCopyPic |
| Location | 12, 242 | |
| Text | Clipboard Copy | |
| Button | Name | btnClipPastePic |
| Location | 120, 242 | |
| Text | Clipboard Paste | |
| Button | Name | btnBBCopy |
| Location | 235, 242 | |
| Text | BitBlt Copy | |
| Button | Name | btnBBPaste |
| Location | 316, 242 | |
| Text | BitBlt Paste |
Coding
Text
As usual, let us start with the Modular declarations.
VB.NET
Private strSelectedText As String 'Selected text
C#
This will keep the Selected text inside the textbox(es) that we want to copy. Now, let us Copy, Cut and Paste via the TextBoxes' built-in methods. Add the following code.
VB.NET
Private Sub btnCopyTXT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCopyTXT.Click
If txtSource.Text <> "" Then 'If something typed in box
If txtSource.SelectionLength > 0 Then 'if something selected
strSelectedText = txtSource.SelectedText 'store selection
txtSource.Copy() 'copy
Else
txtSource.SelectAll() 'nothing selected, take everything
txtSource.Copy() 'copy
End If
End If
End Sub
Private Sub btnCutTXT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCutTXT.Click
If txtSource.Text <> "" Then
If txtSource.SelectionLength > 0 Then
strSelectedText = txtSource.SelectedText
txtSource.Cut()
Else
txtSource.SelectAll()
txtSource.Cut()
End If
End If
End Sub
Private Sub btnPasteTXT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPasteTXT.Click
Dim OldText As String 'previous text in textbox
OldText = txtDest.Text 'store previous text
txtDest.SelectionStart = OldText.Length ' set cursor at end to paste at back of text
txtDest.Paste() 'paste
End Sub
C#
private void btnCopyTXT_Click(object sender, EventArgs e)
{
//If something typed in box
if (!string.IsNullOrEmpty(txtSource.Text))
{
//if something selected
if (txtSource.SelectionLength > 0)
{
strSelectedText = txtSource.SelectedText;
//store selection
txtSource.Copy();
//copy
}
else
{
txtSource.SelectAll();
//nothing selected, take everything
txtSource.Copy();
//copy
}
}
}
private void btnCutTXT_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtSource.Text))
{
if (txtSource.SelectionLength > 0)
{
strSelectedText = txtSource.SelectedText;
txtSource.Cut();
}
else
{
txtSource.SelectAll();
txtSource.Cut();
}
}
}
private void btnPasteTXT_Click(object sender, EventArgs e)
{
string OldText = null;
//previous text in textbox
OldText = txtDest.Text;
//store previous text
txtDest.SelectionStart = OldText.Length;
// set cursor at end to paste at back of text
//paste
txtDest.Paste();
}
This is quite straightforward, as you probably expected. See how simple it is to use the TextBox properties for copy and paste operations?
Now, let us have a look at how it is done through the Clipboard object alone. Add the next code.
VB.NET
Private Sub btnClipCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClipCopy.Click
If txtSource.Text <> "" Then
If txtSource.SelectionLength > 0 Then
strSelectedText = txtSource.SelectedText
Clipboard.SetText(strSelectedText) 'put selection on clipboard
Else
txtSource.SelectAll()
Clipboard.SetText(txtSource.Text) 'put all text on clipboard
End If
End If
End Sub
Private Sub btnClipCut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClipCut.Click
If txtSource.Text <> "" Then
If txtSource.SelectionLength > 0 Then
strSelectedText = txtSource.SelectedText
Clipboard.SetText(strSelectedText)
txtSource.SelectedText = "" 'clear text, for cutting - otherwise it's same as copy
Else
txtSource.SelectAll()
Clipboard.SetText(txtSource.Text)
txtSource.Text = ""
End If
End If
End Sub
Private Sub btnClipPaste_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClipPaste.Click
Dim ClipText As String 'store text from clipboard
Dim OldText As String 'previous text in textbox
OldText = txtDest.Text 'store previous text
ClipText = Clipboard.GetText 'get the clipboard contents
txtDest.Text = OldText & ClipText 'to paste at back of text, otherwise just say textbox2.text = cliptext
End Sub
C#
private void btnClipCopy_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtSource.Text))
{
if (txtSource.SelectionLength > 0)
{
strSelectedText = txtSource.SelectedText;
Clipboard.SetText(strSelectedText);
//put selection on clipboard
}
else
{
txtSource.SelectAll();
Clipboard.SetText(txtSource.Text);
//put all text on clipboard
}
}
}
private void btnClipCut_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtSource.Text))
{
if (txtSource.SelectionLength > 0)
{
strSelectedText = txtSource.SelectedText;
Clipboard.SetText(strSelectedText);
txtSource.SelectedText = "";
//clear text, for cutting - otherwise it's same as copy
}
else
{
txtSource.SelectAll();
Clipboard.SetText(txtSource.Text);
txtSource.Text = "";
}
}
}
private void btnClipPaste_Click(object sender, EventArgs e)
{
string ClipText = null;
//store text from clipboard
string OldText = null;
//previous text in textbox
OldText = txtDest.Text;
//store previous text
ClipText = Clipboard.GetText();
//get the clipboard contents
//to paste at back of text, otherwise just say textbox2.text = cliptext
txtDest.Text = OldText + ClipText;
}
As you can see, using only the Clipboard to copy and paste items is a bit more code, but the gist of the logic remains the same.
Now, for the fun part.
Pictures
Copying pictures is also quite straightforward. The Pictureboxes do not have clipboard methods built in, but we still have two options for copying and pasting. Option 1 is to use the Clipboard object, and option 2 is to use the BitBlt API. Let us have a look at how the Clipboard handles Image content.
VB.NET
Private Sub btnClipCopyPic_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClipCopyPic.Click
Clipboard.SetImage(picSource.Image) 'copy picture onto clipboard
End Sub
Private Sub btnClipPastePic_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClipPastePic.Click
picDest.Image = Clipboard.GetImage() 'paste the image
End Sub
C#:
private void btnClipCopyPic_Click(object sender, EventArgs e)
{
//copy picture onto clipboard
Clipboard.SetImage(picSource.Image);
}
private void btnClipCutPic_Click(object sender, EventArgs e)
{
picDest.Image = Clipboard.GetImage(); //paste the image
}
As easy easy as that! You might have noticed after pasting the picture (if you have used my picture that I have supplied - snake.gif ) that there was some sort of greyish area surrounding our picture. That area is actually transparent, so there should be no shading whatsoever. How do we fix this? The answer is BitBlt.
BitBlt
Bit Block Image Transfer copies pixels from a source rectangle to a destination rectangle object based on the Raster Operation Code.
Whoa! That is a mouthful! What it does in laymans terms is to copy a whole picture or a part of a picture to a destination. This destination can be an empty picturebox, or a picturebox with an image. The sky is the limit. We need to add this functionality to our program.
Add a new class to your project and name it EC_BitBlt.
Add the following namespace to the EC_BitBlt class to handle API calls.
VB.NET
Imports System.Runtime.InteropServices
C#
using System.Runtime.InteropServices;
Add the BitBlt API :
VB.NET
<DllImport("gdi32.dll", EntryPoint:="BitBlt", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function BitBlt( _
ByVal hdcDest As IntPtr, _
ByVal nXDest As Integer, _
ByVal nYDest As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Integer, _
ByVal nYSrc As Integer, _
ByVal dwRop As Int32) As Boolean
End Function
C#
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, Int32 dwRop);
Add the following fields to the class.
VB.NET
Private grpMem As Graphics 'Memory Graphic
Private iptMem As IntPtr 'Pointer Handle
Private szLastSize As Size 'get previous size
Private blnCopied As Boolean 'copied?
Const SRCCOPY As Integer = &HCC0020 'to copy, also get SRCINVERT to invert the colours as well
C#
//Memory Graphic
private Graphics grpMem;
//Pointer Handle
private IntPtr iptMem;
//get previous size
private Size szLastSize;
//copied?
private bool blnCopied;
//to copy, also get SRCINVERT to invert the colours as well
const int SRCCOPY = 0xcc0020;
Add the next code to copy the picture into memory.
VB.NET
Public Sub EC_Copy(ByVal grpSource As Graphics, ByVal szSize As Size)
szLastSize = szSize 'Store size
'Copied already?
If blnCopied Then DisposeObjects() 'Dispose old objects
'Create temp Bitmap to create objects from
Dim srcBmp As New Bitmap(szSize.Width, szSize.Height, grpSource)
grpMem = Graphics.FromImage(srcBmp) 'Create Graphics object
iptMem = grpMem.GetHdc 'Get Device Context
'Get the picture
DoBitBlt(grpSource, iptMem, szSize.Width, szSize.Height)
'Dispose
srcBmp.Dispose()
blnCopied = True 'We have copied
End Sub
C#
public void EC_Copy(Graphics grpSource, Size szSize)
{
szLastSize = szSize; //Store size
if (blnCopied)
DisposeObjects(); //Dispose old objects
Bitmap srcBmp = new Bitmap(szSize.Width, szSize.Height, grpSource); //Create temp Bitmap to create objects from
grpMem = Graphics.FromImage(srcBmp); //Create Graphics object
iptMem = grpMem.GetHdc(); //Get Device Context
DoBitBlt(grpSource, iptMem, szSize.Width, szSize.Height); //Get the picture
srcBmp.Dispose(); //Dispose
blnCopied = true; //We have copied
}
Add the code to paste the picture(s).
VB.NET
Public Sub EC_Paste(ByVal grpDest As Graphics, ByVal intX As Integer, ByVal intY As Integer)
Dim TargetHdc As IntPtr = grpDest.GetHdc 'Get target object
DoBitBlt(iptMem, TargetHdc, szLastSize.Width, szLastSize.Height, intX, intY) 'Source, Dest, Width, Height, X, Y
grpDest.ReleaseHdc(TargetHdc) 'Release memory reference
End Sub
C#
public void EC_Paste(Graphics grpDest, int intX, int intY)
{
IntPtr TargetHdc = grpDest.GetHdc(); //Get target object
DoBitBlt(iptMem, TargetHdc, szLastSize.Width, szLastSize.Height, intX, intY); //Source, Dest, Width, Height, X, Y
grpDest.ReleaseHdc(TargetHdc); //Release memory reference
}
You will have noticed that we made reference to the DoBitBlt functions inside both copy and paste. Why? Well, we first have to copy the source into memory, then copy the memory graphic into the picturebox. The two steps are necessary because we might want to do other manipulation to the in-memory graphic before pasting. Let us add the DoBitBlt functions. One is for copying the image into memory, and the other one is for copying the picture from memory into a destination.
VB.NET
Private Sub DoBitBlt(ByVal grpSource As Graphics, ByVal iptDest As IntPtr, ByVal intWidth As Integer, ByVal intHeight As Integer)
'Create DeviceContext to capture from
Dim SourceHDC As IntPtr = grpSource.GetHdc
' Blit (Copy) the data
BitBlt(iptDest, 0, 0, intWidth, intHeight, SourceHDC, 0, 0, SRCCOPY)
' Release Device context
grpSource.ReleaseHdc(SourceHDC)
End Sub
Private Sub DoBitBlt(ByVal iptSource As IntPtr, ByVal iptDest As IntPtr, ByVal intWidth As Integer, ByVal intHeight As Integer, ByVal intXPos As Integer, ByVal intYPos As Integer)
' Copy data to a specific position on target Device Context
BitBlt(iptDest, intXPos, intYPos, intWidth, intHeight, iptSource, 0, 0, SRCCOPY)
End Sub
C#
private void DoBitBlt(Graphics grpSource, IntPtr iptDest, int intWidth, int intHeight)
{
//Create DeviceContext to capture from
IntPtr SourceHDC = grpSource.GetHdc();
// Blit (Copy) the data
BitBlt(iptDest, 0, 0, intWidth, intHeight, SourceHDC, 0, 0, SRCCOPY);
// Release Device context
grpSource.ReleaseHdc(SourceHDC);
}
private void DoBitBlt(IntPtr iptSource, IntPtr iptDest, int intWidth, int intHeight, int intXPos, int intYPos)
{
// Copy data to a specific position on target Device Context
BitBlt(iptDest, intXPos, intYPos, intWidth, intHeight, iptSource, 0, 0, SRCCOPY);
}
All we need to do now is to make sure all objects have been Disposed properly out of memory. Add the next procedures.
VB.NET
Protected Overrides Sub Finalize()
DisposeObjects() 'make sure all memory is released
MyBase.Finalize()
End Sub
Private Sub DisposeObjects()
grpMem.ReleaseHdc(iptMem) ' Release Device Context
grpMem.Dispose() ' Disposing of Graphics object
End Sub
C#
private void DisposeObjects()
{
grpMem.ReleaseHdc(iptMem);
// Release Device Context
grpMem.Dispose();
// Disposing of Graphics object
}
Add the next code to your frmEasyClipboard class to access the EC_BitBlt class' methods
VB.NET
Private Sub btnBBCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBBCopy.Click
' Create a Graphics object to work with
Dim SourceGrp As Graphics = picSource.CreateGraphics
' Copy the surface
BBBlits.EC_Copy(SourceGrp, New Size(picSource.Width, picSource.Height))
' Dispose of the Graphics object
SourceGrp.Dispose()
End Sub
Private Sub btnBBPaste_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBBPaste.Click
'Create a Graphics object to paste to
Dim targetGrp As Graphics = picDest.CreateGraphics
' BitBlt
BBBlits.EC_Paste(targetGrp, 0, 0)
targetGrp.Dispose()
End Sub
C#
private void btnBBCopy_Click(object sender, EventArgs e)
{
Graphics SourceGrp = picSource.CreateGraphics();
// Copy the surface
BBBlits.EC_Copy(SourceGrp, new Size(picSource.Width, picSource.Height));
// Dispose of the Graphics object
SourceGrp.Dispose();
}
private void btnBBPaste_Click(object sender, EventArgs e)
{
Graphics targetGrp = picDest.CreateGraphics();
// BitBlt
BBBlits.EC_Paste(targetGrp, 0, 0);
targetGrp.Dispose();
}
}
Not too complicated now is it?
The source files are included with this article, so in case you have missed a step or two, you could have a look in there.
Conclusion
I hope you have enjoyed this article and that you have benefited from it. Until next time! Cheers!

Comments
shed roofs and frame
Posted by martellawintek on 12/04/2012 01:01pmhello again gary if your still hanging around here is the link and some info , there very helpfull ,just say miss m wintek told you to ring him
Reply