The new vbAccelerator Site - more VB and .NET Code and Controls

Copy the entire contents of a PictureBox to the clipboard

Author:

Steve McMahon(steve@vbaccelerator.com)

Keywords:

API,Clipboard,GDI,Graphics,Interprocess Comms

Updated:

18/08/99

Other Tips
All Tips
By Date
By Subject


API (33)
Bit
Manipulation (3)

Clipboard (3)
Combo
Box (5)

Desktop (3)
GDI (13)
Graphics (13)
Internet (2)
Interprocess
Comms (3)

Keyboard (2)
Mouse (1)
Shell (1)
Sprites (1)
Subclassing (3)
Text
Box (2)

Windows (11)
Windows
Controls (10)



Submit


VB does not allow you to copy the full picture of a Form, UserControl or PictureBox to the clipboard. If you use Clipboard.SetData, it only copies a bitmap loaded into these objects. You can get around this limitation and ensure the entire contents are copied, including any graphics you have drawn, by using API methods.

Start a new project in VB. Add a Command button and a PictureBox to the project's form. Make sure the Autoredraw property of the PictureBox is set to 1.

Then add a module and copy the following code into it.

' General functions:
Private Type RECT
&nbsp &nbsp Left As Long
&nbsp &nbsp Top As Long
&nbsp &nbsp Right As Long
&nbsp &nbsp Bottom As Long
End Type

' GDI functions:
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source
' Creates a memory DC
Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
' Creates a bitmap in memory:
Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
' Places a GDI Object into DC, returning the previous one:
Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
' Deletes a GDI Object:
Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

' Clipboard functions:
Private Declare Function OpenClipboard Lib "USER32" (ByVal hWnd As Long) As Long
Private Declare Function CloseClipboard Lib "USER32" () As Long
Private Declare Function SetClipboardData Lib "USER32" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function EmptyClipboard Lib "USER32" () As Long
Private Const CF_BITMAP = 2


Public Function CopyEntirePicture(ByRef objFrom As Object) As Boolean
Dim lhDC As Long
Dim lhBMP As Long
Dim lhBMPOld As Long
Dim lWidthPixels As Long
Dim lHeightPixels As Long

&nbsp &nbsp
' Create a DC compatible with the object we're copying
&nbsp &nbsp ' from:
&nbsp &nbsp lhDC = CreateCompatibleDC(objFrom.hDC)
&nbsp &nbsp If (lhDC 0) Then
&nbsp &nbsp &nbsp &nbsp
' Create a bitmap compatible with the object we're
&nbsp &nbsp &nbsp &nbsp ' copying from:
&nbsp &nbsp &nbsp &nbsp lWidthPixels = objFrom.ScaleX(objFrom.ScaleWidth, objFrom.ScaleMode, vbPixels)
&nbsp &nbsp &nbsp &nbsp lHeightPixels = objFrom.ScaleY(objFrom.ScaleHeight, objFrom.ScaleMode, vbPixels)
&nbsp &nbsp &nbsp &nbsp lhBMP = CreateCompatibleBitmap(objFrom.hDC, lWidthPixels, lHeightPixels)
&nbsp &nbsp &nbsp &nbsp If (lhBMP 0) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
' Select the bitmap into the DC we have created,
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' and store the old bitmap that was there:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp lhBMPOld = SelectObject(lhDC, lhBMP)
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
' Copy the contents of objFrom to the bitmap:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp BitBlt lhDC, 0, 0, lWidthPixels, lHeightPixels, objFrom.hDC, 0, 0, SRCCOPY
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
' Remove the bitmap from the DC:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp SelectObject lhDC, lhBMPOld
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
' Now set the clipboard to the bitmap:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp OpenClipboard 0
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp EmptyClipboard
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp SetClipboardData CF_BITMAP, lhBMP
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp CloseClipboard

&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
' We don't delete the Bitmap here - it is now owned
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' by the clipboard and Windows will delete it for us
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' when the clipboard changes or the program exits.
&nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp
' Clear up the device context we created:
&nbsp &nbsp &nbsp &nbsp DeleteObject lhDC
&nbsp &nbsp End If
End Function

To try out the method, add this code to the form:

Private Sub Command1_Click()
&nbsp &nbsp CopyEntirePicture Picture1
End Sub

Private Sub Form_Load()
&nbsp &nbsp Dim iAs Long
&nbsp &nbsp
' Draw something in the Picture box:
&nbsp &nbsp With Picture1.Font
&nbsp &nbsp &nbsp &nbsp .Name = "Arial"
&nbsp &nbsp &nbsp &nbsp .Bold = True
&nbsp &nbsp &nbsp &nbsp .Size = 24
&nbsp &nbsp End With
&nbsp &nbsp For i = 1 To 20
&nbsp &nbsp &nbsp &nbsp Picture1.ForeColor = QBColor(i Mod 15)
&nbsp &nbsp &nbsp &nbsp Picture1.Print "vbAccelerator"
&nbsp &nbsp Next i
End Sub

When the form loads, the picture box will have some text added to it. When you click the Command button, the entire picture box contents will be copied to the Clipboard, from where you can paste it into Paint, Word etc.


&nbsp

Related Tips and Articles:

&nbsp

AboutContributeSend FeedbackPrivacy

Copyright 1998-1999, Steve McMahon ( steve@vbaccelerator.com). All Rights Reserved.
Last updated: 18/08/99