1 Attachment(s)
[VB6] Clipboard/DataObject Extension Class
The attached class extends VB's Clipboard and Data objects. Change its extension from .txt to .cls after downloading.
1) Support for dragging and pasting virtual files. Virtual files exist in Windows compressed folders. They also can be transfered from any application that wishes to use the registered clipboard format. Outlook, for example, uses it when dragging emails & attachments. VB does not natively support this format
2) Support for unicode file names. The clipboard's & data object's Files collection is not unicode compatible. This class replicates the Files collection that is unicode compatible.
3) Adding custom formats and standard formats to the clipboard that VB does not support natively. This class offers two methods to add data to the clipboard and data object.
The attached class also includes, for convenience, all the methods of VB's clipboard and data objects. If you use this class, you should not need to call some methods from it and some methods from VB's objects. However, you are not prevented from using VB's methods for its objects.
Virtual files used here, do not refer to files dragged out of a WinZip file. WinZip extracts the file to a temporary folder and then provides the full path/file name of the file. The dragged data was unzipped and written to file and the file(s) are accessible to VB normally. Windows compressed folders do not do this when dropping on your form. However, if needed, see post #3 below for a workaround.
How does the class enable virtual file access? It uses a low-level API to communicate with VB's IDataObject. That object allows us to ask the source for specific information that VB doesn't expose. No existing APIs, that I'm aware of, expose that data either. With this IDataObject, we have full control for retrieval of anything pasted to the clipboard or dropped via OLE.
One more note about virtual files. As mentioned above, don't think of these as actual files. Think of them as simply blobs of data. The file names provided by the source application should be considered for information only. Do not consider those actual file names, they may not be. Could be an Outlook attachment name. Do not assume they do not contain invalid file name characters. To view or save these data blobs, the class includes methods for saving the blobs to file or array.
Examples of a few "file names" dragged out of a Windows compressed folder follows. Notice there is no qualified path. These are not traditional files, just blobs of data.
Code:
license.txt
readme.txt
inc\jpegdecoder.h << sub-folder items in compressed folder
inc\jpegdecoder.inl
inc\main.h
And here's an email dragged out of Outlook Express:
Code:
Welcome to Outlook Express 6.eml
Will update the class from time to time to repair errors and/or enhance.
The code is well commented. Take the time to read thru the comments at the top of the class and those comments provided with the public methods/properties.
Bug/typo found 29Nov2014. Until corrected, you should make this change after downloading the class. This statement will be removed when I've tested a couple of other things:
in the GetVirtualFileAttr function, remove NOT from If Not pvCallFunction_COM(...
Change History:
27 Nov 2014. Waiting on Turkey Dinner, so enhanced it a bit
- Added methods to enumerate & retrieve pasted/dropped clipboard/data formats
26 Nov 2014
- bug located where global memory during OLE Drag/Drop may not be released
- added option to save virtual file with the embedded folder structure it may have. See SaveVirtualFileAs for more
- added code to ensure Err.LastDLLError is set if some routines fail
Re: [VB6] Clipboard/DataObject Extension Class
Modified the class so that one can enumerate all the formats, i.e., vbCFText, vbCFBitmap, etc, that exist on the clipboard or data object
New methods
1) FormatCount: returns number of formats
2) GetFormatAttrs: returns the format's ID and Name as appropriate
- accepts an Index from 1 to FormatCount
- returned FormatID is usable for any class or VB method that requires a ClipBoardConstants value
- returned FormatName is the string used to register the format for custom clipboard formats. Standard formats return the windows constant used for that format
3) pvEnumFormats and pvAddFormat are helper functions
- pvEnumFormats shows low-level COM example of retrieving the IEnumFormatETC class & using it's virtual methods
Using ShellIDList To Get Compressed Folder Name
Just sample code on how to get the container of virtual files, if that container is provided. For files within a compressed folder, the container is the compressed folder path/name. As mentioned in 1st post above, this information is not provided to you via the pasted/dropped file names. So how do you get it? You look for another format on the clipboard/data object & get it from there:
1st the API declarations you'll need
Code:
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function SHGetPathFromIDListW Lib "shell32.dll" (ByVal pidl As Long, ByVal pszPath As Long) As Long
Next the sample code using the clipboard for pasted files. For drag/drop files, move code into the OLEDragDrop event and change Clipboard to Data
Code:
Dim c As New cDataObjectEx
Dim lID As Long, LB As Long, dData() As Byte
Dim lPIDLoffset As Long, sPath As String
Const MAX_PATH As Long = 260&
' Call this as needed, but obviously you should verify beforehand that c.GetFormat(vbCFFiles) = True
' NOTE: this not needed if c.VirtualFiles = False because path included with file name already
' Though you can still call it if you wish. Parsing path from file name is easier in that case
c.Attach Clipboard
lID = c.RegisterFormat("Shell IDList Array") ' see if this format exists
If lID <> 0 Then
If c.GetFormat(lID) = True Then ' successful with getting the data?
' Tip: If VB doesn't natively handle the format, it returns data as an array
dData() = c.GetData(lID)
' IMPORTANT: array coming from Clipboard is 0-bound, from Data object is 1-Bound
LB = LBound(dData)
If UBound(dData) > LB Then
CopyMemory lPIDLoffset, dData(LB + 4&), 4& ' get location in array for 1st ITEMLIST structure
sPath = String$(MAX_PATH, vbNullChar) ' retrieve path from that structure
If Not SHGetPathFromIDListW(VarPtr(dData(lPIDLoffset + LB)), StrPtr(sPath)) = 0& Then
sPath = Left$(sPath, InStr(sPath & vbNullChar, vbNullChar) - 1&)
Debug.Print sPath; "<<<<"
End If
End If
End If
End If
Re: [VB6] Clipboard/DataObject Extension Class
hi i used this class and then draged a simple unicode file name image but not worked,can u help me more,i want open and show draged image with unicode names in picture box and i hv this problem for common dialog too. i attaches sample image file in thread too.
my thread : ole drag drop and problem with unicode charachters or load image with unicode
Re: [VB6] Clipboard/DataObject Extension Class
I looked at your other thread. Unfortunately the screenshot is sized too small to see everything clearly. You are using a VB MsgBox to display the filename. It will never display the filename correctly if it contains unicode. You can use the unicode-compatible API MessageBox instead. Regarding saving your file. You cannot use VB's FileCopy, Open File, and other file functions with unicode filenames. Use unicode-compatible APIs or other tools like the FSO.
Re: [VB6] Clipboard/DataObject Extension Class
can u send a sample to can do that?
(1-) i need drag that file on form and show in a picture box on form.
2-i need a button to for show common dialog and after select file can show in a picutre box like (1-)
3-i need show name of file on a label or ...(i need just show name in some place on form)
if found this thread (www.vbforums.com/showthread.php?585762-VB6-Unicode-File-Open-Save-Dialog)
problem 2 can fix with that thread but problem 1 for drag drop and problem 3 for show name on label not fixed yet
Re: [VB6] Clipboard/DataObject Extension Class
Quote:
Originally Posted by
Black_Storm
can u send a sample to can do that?
No, I don't assist those who are creating commercial products, those sold/made for companies. I get paid for that ;)
Re: [VB6] Clipboard/DataObject Extension Class
i fixed problem 1 too with merg Clipboard/DataObject Extension Class like this :
Code:
Dim cDataObj As New cDataObjectEx
cDataObj.Attach Data
Dim hImage As Long, tmpPic As StdPicture
Dim hHandle As Long, imageData() As Byte, bytesRead As Long
On Error GoTo 0
hHandle = GetFileHandle(cDataObj.Files(1))
If hHandle <> INVALID_HANDLE_VALUE Then
If hHandle Then
bytesRead = GetFileSize(hHandle, ByVal 0&)
If bytesRead Then
ReDim imageData(0 To bytesRead - 1)
ReadFile hHandle, imageData(0), bytesRead, bytesRead, ByVal 0&
If bytesRead > UBound(imageData) Then
Set tmpPic = ArrayToPicture(imageData(), 0, bytesRead)
End If
End If
CloseHandle hHandle
End If
End If
Set Picture1.Picture = tmpPic
cDataObj.Detach
now porblem 3 just exist,how can show file name draged in a label or (a sample user control to can use for show unicode name)?
i created a unicode label support in this thread(#12),but this is complicated,can u help me for show a unicode charachters in a simple label(transparent is matter for me)