Solved

Put image in picturebox to clipboard

Posted on 2004-09-13
31
843 Views
Last Modified: 2009-07-29
I can't seem to find a way to do this.  I have a picturebox/imagebox that displays photos.  I want to click a button which will place the current image on the clipboard so that it can be pasted in other applications (ie. Word, Outlook, etc).

So far all I've found is API code - but its for strings.. and the DoCmd.RunCommand accmdCopy command requires the control to have the focus (and I can't set focus on the picturebox) ...

Any other ideas?
0
Comment
Question by:Plamodo
  • 15
  • 8
  • 5
  • +2
31 Comments
 
LVL 41

Expert Comment

by:shanesuebsahakarn
Comment Utility
Here's some code to do it:

Option Compare Database
Option Explicit

Public Const GHND = &H42
Public Const CF_TEXT = 1
Private Const CF_ANSIONLY = &H400&
Private Const CF_APPLY = &H200&
Private Const CF_BITMAP = 2
Private Const CF_DIB = 8
Private Const CF_DIF = 5
Private Const CF_DSPBITMAP = &H82
Private Const CF_DSPENHMETAFILE = &H8E
Private Const CF_DSPMETAFILEPICT = &H83
Private Const CF_DSPTEXT = &H81
Private Const CF_EFFECTS = &H100&
Private Const CF_ENABLEHOOK = &H8&
Private Const CF_ENABLETEMPLATE = &H10&
Private Const CF_ENABLETEMPLATEHANDLE = &H20&
Private Const CF_ENHMETAFILE = 14
Private Const CF_FIXEDPITCHONLY = &H4000&
Private Const CF_FORCEFONTEXIST = &H10000
Private Const CF_GDIOBJFIRST = &H300
Private Const CF_GDIOBJLAST = &H3FF
Private Const CF_HDROP = 15
Private Const CF_INITTOLOGFONTSTRUCT = &H40&
Private Const CF_LIMITSIZE = &H2000&
Private Const CF_LOCALE = 16
Private Const CF_MAX = 17
Private Const CF_METAFILEPICT = 3
Private Const CF_NOFACESEL = &H80000
Private Const CF_NOSCRIPTSEL = &H800000
Private Const CF_NOSIMULATIONS = &H1000&
Private Const CF_NOSIZESEL = &H200000
Private Const CF_NOSTYLESEL = &H100000
Private Const CF_NOVECTORFONTS = &H800&
Private Const CF_NOOEMFONTS = CF_NOVECTORFONTS
Private Const CF_NOVERTFONTS = &H1000000
Private Const CF_OEMTEXT = 7
Private Const CF_OWNERDISPLAY = &H80
Private Const CF_PALETTE = 9
Private Const CF_PENDATA = 10
Private Const CF_PRINTERFONTS = &H2
Private Const CF_PRIVATEFIRST = &H200
Private Const CF_PRIVATELAST = &H2FF
Private Const CF_RIFF = 11
Private Const CF_SCALABLEONLY = &H20000
Private Const CF_SCREENFONTS = &H1
Private Const CF_BOTH = (CF_SCREENFONTS Or CF_PRINTERFONTS)
Private Const CF_SCRIPTSONLY = CF_ANSIONLY
Private Const CF_SELECTSCRIPT = &H400000
Private Const CF_SHOWHELP = &H4&
Private Const CF_SYLK = 4
Private Const CF_TIFF = 6
Private Const CF_TTONLY = &H40000
Private Const CF_UNICODETEXT = 13
Private Const CF_USESTYLE = &H80&
Private Const CF_WAVE = 12
Private Const CF_WYSIWYG = &H8000

Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags&, ByVal _
  dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) _
  As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) _
  As Long
Private Declare Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, _
  ByVal lpString2 As Any) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" _
  (ByVal lpString As String) As Long

Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) _
  As Long

Private Declare Function OpenClipboard Lib "user32" (ByVal Hwnd As Long) _
  As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As _
  Long) As Long
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Declare Function SetClipboardData Lib "user32" (ByVal wFormat _
  As Long, ByVal hMem As Long) As Long

Function ClipBoard_SetText(strCopyString As String) As Boolean
  Dim hGlobalMemory As Long
  Dim lpGlobalMemory As Long
  Dim hClipMemory As Long

  ' Allocate moveable global memory.
  '-------------------------------------------
  hGlobalMemory = GlobalAlloc(GHND, Len(strCopyString) + 1)

  ' Lock the block to get a far pointer
  ' to this memory.
  lpGlobalMemory = GlobalLock(hGlobalMemory)

  ' Copy the string to this global memory.
  lpGlobalMemory = lstrcpy(lpGlobalMemory, strCopyString)

  ' Unlock the memory and then copy to the clipboard
  If GlobalUnlock(hGlobalMemory) = 0 Then
    If OpenClipboard(0&) <> 0 Then
      Call EmptyClipboard
      hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory)
      ClipBoard_SetText = CBool(CloseClipboard)
    End If
  End If
End Function

Function ClipBoard_GetText() As String
  Dim hClipMemory As Long
  Dim lpClipMemory As Long
  Dim strCBText As String
  Dim RetVal As Long
  Dim lngSize As Long
  If OpenClipboard(0&) <> 0 Then
    ' Obtain the handle to the global memory
    ' block that is referencing the text.
    hClipMemory = GetClipboardData(CF_TEXT)
    If hClipMemory <> 0 Then
      ' Lock Clipboard memory so we can reference
      ' the actual data string.
      lpClipMemory = GlobalLock(hClipMemory)
      If lpClipMemory <> 0 Then
        lngSize = GlobalSize(lpClipMemory)
        strCBText = Space$(lngSize)
        RetVal = lstrcpy(strCBText, lpClipMemory)
        RetVal = GlobalUnlock(hClipMemory)
        ' Peel off the null terminating character.
        strCBText = Left(strCBText, InStr(1, strCBText, Chr$(0), 0) - 1)
      Else
        MsgBox "Could not lock memory to copy string from."
      End If
    End If
    Call CloseClipboard
  End If
  ClipBoard_GetText = strCBText
End Function

Function CopyOlePiccy(Piccy As Object)
  Dim hGlobalMemory As Long, lpGlobalMemory As Long
  Dim hClipMemory As Long, x As Long

  ' Allocate moveable global memory.
  '-------------------------------------------
  hGlobalMemory = GlobalAlloc(GHND, Len(Piccy) + 1)

  ' Lock the block to get a far pointer
  ' to this memory.
  lpGlobalMemory = GlobalLock(hGlobalMemory)


  'Need to copy the object to the memory here

  lpGlobalMemory = lstrcpy(lpGlobalMemory, Piccy)

  ' Unlock the memory.
  If GlobalUnlock(hGlobalMemory) <> 0 Then
    MsgBox "Could not unlock memory location. Copy aborted."
    GoTo OutOfHere2
  End If

  ' Open the Clipboard to copy data to.
  If OpenClipboard(0&) = 0 Then
    MsgBox "Could not open the Clipboard. Copy aborted."
    Exit Function
  End If

  ' Clear the Clipboard.
  x = EmptyClipboard()

  ' Copy the data to the Clipboard.
  hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory)

OutOfHere2:
  If CloseClipboard() = 0 Then
    MsgBox "Could not close Clipboard."
  End If
End Function
'*********  Code End   ************

This includes code to copy strings. Use the CopyOlePiccy function to copy an OLE image object to the clipboard.
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
Hmmm... I can't get the code to work.  Maybe I'm using it wrong..

Call CopyOlePiccy(imgPhoto)

It crashes at the len(piccy) command - I guess you can't get the the length of a picture (??)

0
 
LVL 41

Expert Comment

by:shanesuebsahakarn
Comment Utility
Ah - the image you're trying to copy is an Image control rather than an OLE field, right?
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
Yeah..
0
 
LVL 41

Expert Comment

by:shanesuebsahakarn
Comment Utility
Is the image's picture embedded or linked?
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
Linked
0
 
LVL 41

Expert Comment

by:shanesuebsahakarn
Comment Utility
OK, try this. Insert an unbound OLE frame into your form. You can hide it if you need. Then try:

Set Me!MyUnboundOLE.Picture=LoadPicture(Me!MyImageControl.Picture)
CopyOLEPiccy Me!MyUnboundOLE.Picture

Does that do it?
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
I'm getting an error on this line: "Set Me!OLEUnbound3.Picture = LoadPicture(Me!Image0.Picture)"
"Object doesn't support this property or method"

Does this work for you?
0
 
LVL 41

Expert Comment

by:shanesuebsahakarn
Comment Utility
Hmm, seems not. Let me get back to you on this once I test a few things out.
0
 
LVL 2

Expert Comment

by:ApK
Comment Utility
In image control's picture property is the path to the file, not the binary data.

Try the PictureData property instead:

CopyOLEPiccy imgPhoto.PictureData

I thought there was an easier way too, using the DataObject class - but that's apparently not available in Access (but I migh try a google hunt to see).

Regards,
Andrew.
0
 
LVL 34

Assisted Solution

by:flavo
flavo earned 20 total points
Comment Utility
why cant you use accmdcopy??

i just tested with an ole and a form and it all worked ok..

Example:

Dim oWord As Object
Me.pic.SetFocus
DoCmd.RunCommand acCmdCopy
Set oWord = CreateObject("word.application")
oWord.Documents.Add
oWord.Selection.Paste
oWord.Visible = True


Dave
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
I have a moronic question - what is an OLE control?  And where do I get it from?  I've been playing around with Unbound Object Frames.. and it just occured to me, its probably not what I'm supposed to be doing.

0
 
LVL 41

Expert Comment

by:shanesuebsahakarn
Comment Utility
Bound and Unbound Object Frames are both OLE controls (they're actually the same control). I haven't found a reliable way to do this yet as I'm not really familiar with the ins and outs of the clipboard when working with non-text data.
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
In that case, I don't know how to set the focus on an Unbound Object Frame without getting an error.

Flavo - exactly what control did you use for your last comment?.. because unfortunately it doesn't seem to work for me.
The "Docmd.runcommand accmdcopy" seems like the simplest, most logical way to do things - and looks like the only Access built-in clipboard function .. but the focus dealio is creating some big headaches.

0
 
LVL 41

Expert Comment

by:shanesuebsahakarn
Comment Utility
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 6

Author Comment

by:Plamodo
Comment Utility
Wow.. its been a few months since my last comment.  Sorry about that.  I've had a small problem with my EE alerts going into my bulk folder...

Shane, your link is the closest yet, BUT unfortunately it didn't copy the picture properly.  The picture was copied, but when I pasted, the actual image was shrunk to about 10% and the other 90% was black space.  Have you tried this with any success, Shane?

______________________________________

I did find an interesting work-around though... although it still doesn't completely fit my needs.  If I use a web browser control to display the image, I can right-click it and copy and paste it perfectly.  This also handles a problem I was having with image resolution displaying text very poorly in the image control.  HOWEVER, very very unfortunately, the web browser cannot be resized.  I have a feature set up for my photos to be able to zoom-in and zoom-out... and to do so, the control needs to be resized on the fly.  Go figure, eh?

That said.. since the web browser control offered different features and allows very easy copying - does it remind anyone of any other controls that might also serve as a work-around in a similar fashion?
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
I have thought of another work around.  Take the linked photo that is in the image control and place it in a temporary Word document, and then copy the embedded image in the word document to the clipboard.  Problem is, if I close the word document before I try to paste, the clipboard no longer contains the image.  If I paste before I click "OK" in the messagebox in the code below, it works just as planned.

Is there a way to be able to copy from the Word document and retain the image on the clipboard *after* the word document has been closed?

    Dim strFile As String
    Dim wrdObject As Object
    strFile = Image0.Picture
    Set wrdObject = CreateObject("Word.Application")
    wrdObject.Documents.Open "G:\apddb\templates\PhotoHolder.doc", ReadOnly:=True
    wrdObject.activedocument.bookmarks("Photo").Select
    wrdObject.selection.InlineShapes.AddPicture strFile
   
    wrdObject.activedocument.InlineShapes.Item(1).Select
    'wrdObject.selection.InlineShapes(1).ConvertToShape.Select
    wrdObject.selection.Copy
    MsgBox "Photo copied.", vbInformation
    wrdObject.Quit SaveChanges:=0 'wdDoNotSaveChanges
    Set wrdObject = Nothing
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
Increased points to 500
0
 
LVL 119

Assisted Solution

by:Rey Obrero
Rey Obrero earned 20 total points
Comment Utility
hope this links help

How to Send Information to the Clipboard
http://support.microsoft.com/?kbid=210216

How to Retrieve Information from the Clipboard
http://support.microsoft.com/?kbid=210213

0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
Thanks capricorn.. but those links only cover sending text to the clipboard... images are a different deal all together.
0
 
LVL 2

Expert Comment

by:ApK
Comment Utility
You seem to keep changing between an OLE control and an Image control. Which one are you using, or are you happy to use either?
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
I'm using an Image control.. but I'm cool to use anything that allows the following:

1)  Copying the image in the control to the clipboard
2)  Resizing the control on the fly to create a zoom-in, zoom-out effect.

The webbrowser control lets me do 1), but not 2)
The image control lets me do 2), but not 1)

And a workaround I found was to embed the image (because at run-time I know the file name and location), into a word document with word automation, and copy the object to the clipboard.  This works, UNTIL the document is closed... which seems unavoidable...
0
 
LVL 2

Expert Comment

by:ApK
Comment Utility
The CopyOLEPiccy code that Shane posted should work except for a few things:

1. The Piccy argument is being passed in as an object, but then treated as raw data. You should pass in the Image object, but then reference it's .PictureData property (in the two places it's used), OR, change the Piccy argument to type Byte() (i.e. Byte array) and pass in the Image.PictureData property.

2. It calls SetClipboardData() with the CF_TEXT argument - I think it should be CF_ENHMETAFILE, but I haven't tried it (you are copying an image, not text).

Try 1 first, then try 2 if it doesn't work.

Note you could also resize an img in a web control. But it depends on how you are pointing the webcontrol at the image - either as a direct path (as in: WebControl.Navigate(myImgPath) ) - or as a HTML document with an IMG tag. If it's the latter, you could do the following to resize it programmatically:
webcontrol.Document.All("myImageName").Width = x
webcontrol.Document.All("myImageName").Height = y

Andrew.
0
 
LVL 41

Assisted Solution

by:shanesuebsahakarn
shanesuebsahakarn earned 20 total points
Comment Utility
What about using an OLE object, setting the focus to the control and then using RunCommand acCmdCopy?

Can't remember if someone suggested that already....
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
apk - I'm trying your suggestions... I'll return with my results in a bit.. and yes, I'm using the webcontrol.navigate format of the webbrowser control, so I guess your suggestion wouldn't apply.

Shane - Yeah.. I've tried the OLE object with acCmdCopy.. but I get errors when I try to set the focus on the OLE.
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
apk - actually.. can you specify where to use the .picturedata property.. After weeding throught the code, I realized I don't know what I'm doing :)

I remember the last time I tried this, it crashed at the len(piccy) statement.
0
 
LVL 2

Expert Comment

by:ApK
Comment Utility
Change:
   hGlobalMemory = GlobalAlloc(GHND, Len(Piccy) + 1)
to:
   hGlobalMemory = GlobalAlloc(GHND, Len(Piccy.PictureData) + 1)
and change:
   lpGlobalMemory = lstrcpy(lpGlobalMemory, Piccy)
to:
   lpGlobalMemory = lstrcpy(lpGlobalMemory, Piccy.PictureData)

0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
Damn.. never got the notification about apk's last comment back in december.
For the record, apk, I just tried making the changes you indicated, but I get type mismatch error at:

lpGlobalMemory = lstrcpy(lpGlobalMemory, Piccy.PictureData)  '<--- on the picturedata property


Apk - have you actually gotten this to work?
0
 
LVL 2

Accepted Solution

by:
ApK earned 440 total points
Comment Utility
No I hadn't tried it.

I am not so familiar with what needs to be changed with the sample code (other than needing to use PictureData property, not the control), but I have done this before using sample code from the following page: http://www.lebans.com/imagecontroltoclipboard.htm.

Andrew.
0
 
LVL 6

Author Comment

by:Plamodo
Comment Utility
ApK - you nailed it.  Works fantastic. (the lebans solution, I mean)

You get the bulk of the points.  I'm gonna give out a few more for everyone else who tried to help me on this one.  What an epic.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Regardless of which version on MS Access you are using, one of the harder data-entry forms to create is one where most data from previous entries needs to be appended to new records, especially when there are numerous fields and records involved.  W…
Introduction The Visual Basic for Applications (VBA) language is at the heart of every application that you write. It is your key to taking Access beyond the world of wizards into a world where anything is possible. This article introduces you to…
Using Microsoft Access, learn some simple rules for how to construct tables in a relational database. Split up all multi-value fields into single values: Split up fields that belong to other things into separate tables: Make sure that all record…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now