[RESOLVED] Simulate drag and drop image from clipboard
I'm trying to 'Drop' an image file at the current mouse location, FileType Image (BMP,JPG,PNG).
i've written code to grab an image from the clipboard and save it. But now i want to grab this image and drop it at mousepos when a hotkey is pressed.
The hotkey is working without my app having the focus ( as intended ) but now im stuck at actually dropping this file when the hotkey is pressed.
My form:
Code:
Option Explicit
Private Sub Command1_Click()
Dim ImageName$
Picture1.Picture = Clipboard.GetData
Clipboard.Clear
ImageName$ = InputBox("Provide filename")
FileName$ = ImageName$
Text1.Text = FileName$
End Sub
Sub On_Event_CtrlShiftV(FileName$)
Dim FilePath$, MouseX&, MouseY&
FilePath$ = "c:\AnyLocation\"
SavePicture Picture1.Image, FilePath$ & FileName$ & ".png"
Call GetCursorPos(Mpos)
MouseX = Mpos.x
MouseY = Mpos.y
'drop the saved image at cursorposition as if it was dragged and dropped.
End Sub
Private Sub Timer1_Timer()
If Picture1.Picture Then
If GetAsyncKeyState(vbKeyF9) Then
'Hotkey pressed,do dragdrop at mousepos
Call On_Event_CtrlShiftV(Text1.Text)
End If
End If
End Sub
Module:
Code:
Option Explicit
Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Public Const VK_RSHIFT = &HA1
Public Const VK_RCONTROL = &HA3
Public Type POINTAPI
x As Long
y As Long
End Type
Public Mpos As POINTAPI
Public FileName$
Im just not sure how to begin the dropping of the file that is created.
Last edited by rikdol; Feb 6th, 2020 at 10:49 AM.
Reason: change to: FileType Image (BMP,JPG,PNG)
Im afraid the question is not as hard as it may seem but my phrasing is off..
In short: I'm trying to drop an image loaded from either a picturebox or file, as if it was dragged and dropped like you do in windows explorer. While my app is in the background.
The last thing i tried was use the following:
Code:
ssfDESKTOP = 0
FILE = FileName$
With CreateObject("Shell.Application").NameSpace(ssfDESKTOP)
With .ParseName(FILE)
.InvokeVerb "copy" 'This is a canonical verb and should work for any
'regional and language settings.
End With
End With
But it only seems like the 'Paste' button in the top toolbar of an explorer window lights up. and it's not pasting..
How should i approach the last step, or does it require a different step before it.
Drop it where? If it's in your app why wouldn't you just pass the image directly to whatever processes it after you read the data from a dropped object?
I could not work out what you were requesting.
Why not attach a project, and place a comment(s) at appropriate spot in the code, so we know what you are attempting to do ?
Drop it where? If it's in your app why wouldn't you just pass the image directly to whatever processes it after you read the data from a dropped object?
Drop it onto google chrome, while i have a wordpress (gutenberg) editor open there. This is important since it's the only way the image will be saved to the server with it's appropriate filename.
You can already paste images from clipboard to the editor, but filenames will be randomized.
Originally Posted by Bobbles
I could not work out what you were requesting.
Why not attach a project, and place a comment(s) at appropriate spot in the code, so we know what you are attempting to do ?
i chose to upload the project. but also reviewed my question, and with new insight i rephrased my question. I couldn't change the thread title accordingly though.
It's actually not far from this question i think (old thread 2005)
And my search also came up with the proper description for what i am trying to do: 'Programmatically drag and drop an image file' But i can't change my thread title accordingly.
Difference is that i want to start the Drag action with a hotkey (grabbing a file by it's full path), and use the mouse to drop it anywhere that accepts dropping files.
Last edited by rikdol; Jan 27th, 2020 at 03:50 PM.
Reason: Additional info..
Paste doesn't work in alot of programs, where drag and drop does work. Specifically, i need to paste it into the wordpress gutenberg editor, pasting from clipboard will result in a random filename. Dragging and dropping however will upload the media with the filename it came with.
So my program allows to snip an image, and name it. Once it's saved (preferably as a file) i need a hotkey to 'drop' it at the mouse location.
Update, since it feels i am getting closer to the solution.
At this moment i can successfully press my hotkey, and pass the imagefile to OLEStartDrag.
I can also drop this file in a folder. but only when i started the OLEStartDrag when my app has the focus (for a reason i can't explain) and only when: Data.SetData , vbCFFiles
3 problems i've noticed so far:
1-It seems the DataObject will only contain 'imagedata' if i call: Image1.OLEDragwhile my app has focus.
2-It seems to only work when SetData is: Data.SetData ,vbCFFiles (' vbCFDIB and ' vbCFBitmap don't work )
3-The mouse cursor is not showing a different icon when i move the mouse outside the form. not when i drag over an explorer window and neither when i hover above chrome. (this might be caused by the getfeedback event that i'm not doing anything with atm..)
But for some reason, with all of the above, it's not the same action as when i would physically drag and drop the image myself.
This is the code i added :
Code:
Sub On_Event_Keypress(FileName$)
'When the F9 key is pressed
Dim FilePath$, MouseX&, MouseY&
FilePath$ = App.Path + "\" 'Save the image to the current App.Path root
SavePicture Image1.Picture, FilePath$ & FileName$ & ".jpg" 'Save picture to Disk
FullFilePath$ = FilePath$ & FileName$ & ".jpg"
Call PasteIt(FullFilePath$) 'Load image from Imagelocation and DragAndDrop it where mouse currently is.
End Sub
Public Sub PasteIt(ByVal FileName As String)
Image1.DragMode = vbManual
Image1.OLEDrag 'Drag vbBeginDrag 'Begin dragging by calling the OLEDrag method.OLEDrag
End Sub
Private Sub Image1_OLEStartDrag(Data As DataObject, AllowedEffects As Long)
Debug.Print FullFilePath$
Data.Clear
Data.SetData , vbCFFiles 'vbCFDIB ' vbCFBitmap '
Data.Files.Add FullFilePath$
AllowedEffects = vbDropEffectCopy
Debug.Print "Image1_OLEStartDrag"
End Sub
I was wondering, since there was no followup, if there is something i missed. Or should i stop figuring out how to make it work? Dropping a file programmatically
If you want to drag CF_PNG format as per your original post to an external app (just vbCFFFiles, which is CF_HDROP, isn't good enough as Post #9 suggests), you're going to have to use API drag/drop instead of the native VB way, see here.
An error in the main sample or the test class later on in the thread? If it's the main demo definitely post about it so I can fix it.
The projects do different things; the one you linked to is for receiving dropped files, not dragging them. There's no support for initiating a drag from your app to another. And the newer one won't put CF_HDROP in (you could, but there's no code for it in that demo: You'd fill a DROPFILES structure with double-null terminated full paths and copy it into memory like the other formats.).
But that will not add the CF_PNG format either unless you add code to modify the IDataObject from the newer project; I don't know if your target will support item ids so if you do still need CF_HDROP you'd need to add that as well like described above).
If you want to add CF_HDROP to an IDataObject in either project, here's a sub for that with Unicode support (the version in the 'API File Drag' thread doesn't support Unicode):
Code:
Public Sub IDO_AddHDROPW(ido As oleexp.IDataObject, sFiles() As String)
Dim i As Long
Dim fmt As FORMATETC
Dim stg As STGMEDIUM
Dim s As String
Dim df As oleexp.DROPFILES
Dim hGlobal As Long
Dim lpGlobal As Long
Dim hr As Long
For i = 0 To UBound(sFiles)
s = s & sFiles(i) & vbNullChar
Next
s = s & vbNullChar
hGlobal = GlobalAlloc(GHND, Len(df) + LenB(s))
If hGlobal Then
lpGlobal = GlobalLock(hGlobal)
df.pFiles = LenB(df)
df.fWide = 1
Call CopyMemory(ByVal lpGlobal, df, LenB(df))
Call CopyMemory(ByVal (lpGlobal + LenB(df)), ByVal StrPtr(s), LenB(s))
Call GlobalUnlock(hGlobal)
fmt.cfFormat = CF_HDROP
fmt.dwAspect = DVASPECT_CONTENT
fmt.lindex = -1
fmt.pDVTARGETDEVICE = 0
fmt.TYMED = TYMED_HGLOBAL
stg.TYMED = TYMED_HGLOBAL
stg.Data = lpGlobal
ido.SetData fmt, stg, 1
End If
End Sub
Use this version even if you don't need Unicode; it produces a byte-for-byte equivalent entry to when you drag/copy from Explorer, so guaranteed to work.
Last edited by fafalone; Jan 30th, 2020 at 01:49 PM.
I've changed the way it works for me now, and a second form will popup at my mouseposition, with a button, to be able to start the drag action on the mousedown event.
After this i noticed a problem with the fileformat. i used dilettante's SavePicture class to make sure a proper png/jpg was saved.
And i am now able to grab a file and drop it, using a drag action from the commandbutton.
What it does is the following:
It checks the clipboard for a bitmap (which is the format the windows 10 snippingtool uses)
if there is one it will start to listen for 2 hotkeys. hotkey1 will show an inputbox for filename input, hotkey 2 will show form2 with the drag button at mousepos.
From there, the previously saved file can be dragged anywhere, where 'dropping' is supported. In my case, into the wordpress editor so it keeps it's filename.
The program was a bit too quick at first. It tried to read the clipboard whilst win10 was still writing to it, resulting in an Error 521: Can't Open Clipboard". Which was fixed with a simple Sleep before accessing the clipboard.
Also some 'doevents' were necessary, or the form or image control wouldn't update. w
The only thing that i noticed was that the inputbox has a bug where it seems to miss the first character entered, as if pressing a button gives a Windows 'ping' and then has the proper focus to continue input.
Many thanks to everyone able to shine some light on the matter.
An error in the main sample or the test class later on in the thread? If it's the main demo definitely post about it so I can fix it.
This seemed to be an error on another machine that didn't show up on my own desktop. Nothing to report here.
I've attached it here so it might help someone as VBForums has helped me. I'm still learning so any and all feedback/criticism is welcome.
Re: [RESOLVED] Simulate drag and drop image from clipboard
There is a small 'bug' with the inputbox that i don't know the reason for.
Once it comes up by pressing F10 ( and an image is on the clipboard) it seems to ignore the first character typed. and an error sound produced as if it didnt have the focus.