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.