Re: [VB6] Shell Video Thumbnail Images
What pain? Works fine for me:
Code:
Option Explicit
Private Shell As Shell32.Shell
Private Function GetFileVersion(ByVal FullName As String) As Variant
Dim ShellFolderItem As Shell32.ShellFolderItem
Set ShellFolderItem = Shell.NameSpace(ssfDESKTOP).ParseName(FullName)
GetFileVersion = ShellFolderItem.ExtendedProperty("System.FileVersion")
End Function
Private Sub PrintVersion(ByVal FileVersion As Variant)
If IsEmpty(FileVersion) Then
Print "No version information"
Else
Print FileVersion
End If
End Sub
Private Sub Form_Load()
Set Shell = New Shell32.Shell
PrintVersion GetFileVersion(App.Path & "\Project1.vbp")
PrintVersion GetFileVersion(App.Path & "\Project1.exe")
End Sub
You seem to be making this all far harder than it is.
Re: [VB6] Shell Video Thumbnail Images
I was referring to if you wanted to go deeper into the world of SCIDs and extended properties (the "extended property system" doesn't consist entirely of shell32.ExtendedProperty).
Say you wanted to write extended properties? List them? Get the raw value instead of the formatted value? Get their default column width? Get the actual property key structure for use with the rest of the system that isn't shell automation?
You seem to think there's nothing shell interfaces can do that shell32's automation object can't. It's a great simplification, but only for the specific scenario where its limited feature set covers everything you need.
Re: [VB6] Shell Video Thumbnail Images
dilettante, you wrote that you got nothing useful in Music folders? I just discovered today that Windows (7) gives you the APIC album art tag when you request SCID_THUMBNAILSTREAM (officially PKEY_ThumbnailStream) for mp3 files... is that maybe a codec specific to my system?
Wanted to ask what about reversing it and writing this property? I'm not that handy at graphics just was curious if you had ever created a write version of this before I head down that road...
Would just need the object in PROPVARIANT form; I already have lower-level code for writing to the property system directly through IPropertyStore.
Edit: Wow nevermind I actually got it. Didn't think it would go so smooth. Biggest obstacle was how to get a VT_STREAM PROPVARIANT, since leaving it as VT_UNKNOWN leads to a Type Mismatch error.
So here's how to save a thumbnail stream as an mp3 album art:
Code:
Dim hFile As Long, nFile As Long, lp As Long
Dim hBitmap As Long
Dim hImage As Long
Dim sBMP As String
Dim hGG As Long, lpGlobal As Long
sBMP = "C:\vb6\ucShellBrowse\DemoEx\test\sp.jpg"
hFile = CreateFileW(StrPtr(sBMP), FILE_READ_DATA, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, 0, 0)
If hFile Then
'read bitmap file into memory
nFile = GetFileSize(hFile, lp)
Debug.Print "high=" & nFile & ",low=" & lp
hGG = GlobalAlloc(GPTR, nFile)
lpGlobal = GlobalLock(hGG)
If lpGlobal Then
Dim oStrm As oleexp.IUnknown
Call ReadFile(hFile, ByVal lpGlobal, nFile, nFile, ByVal 0&)
Call GlobalUnlock(hGG)
Call CreateStreamOnHGlobal(hGG, 1, oStrm)
Dim vbr As Variant, vpr As Variant
Set vbr = oStrm
VariantToPropVariant vbr, vpr
'At this point since VARIANT doesn't support VT_STREAM, its type is VT_UNKNOWN
'So the PROPVARIANT is also VT_UNKNOWN. But that will give us a type mismatch.
'PropVariantChangeType seems to only support numbers, so we manually change the type
'to VT_STREAM, which is valid because our IUnknown object is an IStream.
'In the PROPVARIANT structure, the first two bytes are the VARENUM value indicating type
Dim vt As Integer
vt = VT_STREAM
CopyMemory ByVal VarPtr(vpr), ByVal VarPtr(vt), 2&
Dim si2 As IShellItem2
Dim pps As IPropertyStore
oleexp.SHCreateItemFromParsingName StrPtr("C:\vb6\ucShellBrowse\DemoEx\test\fyd.mp3"), Nothing, IID_IShellItem2, si2
si2.GetPropertyStore GPS_OPENSLOWITEM Or GPS_READWRITE, IID_IPropertyStore, pps
If (pps Is Nothing) = False Then
Dim hr As Long
hr = pps.SetValue(PKEY_ThumbnailStream, vpr)
DebugAppend "SetValue hr=0x" & Hex$(hr)
hr = 0
hr = pps.Commit()
DebugAppend "Commit hr=0x" & Hex$(hr)
End If
GlobalFree hGG
CloseHandle hFile
End If
End If
Edit 2: I made a demo. [VB6] Write MP3 Album Art and other tags using the Windows Property System
Edit 3: One more thought going back to the original project here... why does GdipCreateBitmapFromStream accept a PROPVARIANT with an IStream, but only if it's typed as VT_UNKNOWN(=vbDataObject) but not VT_STREAM? Out of curiousity, I applied the simply-change-the-.vt-struct-member technique I used, replacing the PropVariantToVariant call, and the project worked normally.