Re: [VB6] Write MP3 Album Art and other tags using the Windows Property System
Here's a barebones routine to read PKEY_Title and PKEY_Music_AlbumTitle like you're doing.
This will be about as fast as gets before you have to start going for extremes (you can look at my ucShellBrowse project... it will open a folder of thousands of mp3s with titles/albums displayed in a second; but loads album/title on demand instead of all at once.
Code:
Private Sub Command1_Click()
Dim siPath As IShellItem
Dim siChild As IShellItem, si2 As IShellItem2
Dim sTitle As String
Dim sAlbum As String
Dim sFile As String
Dim sOut As String
Dim pEnum As IEnumShellItems
Dim pc As Long
Dim vpv As Variant, vbv As Variant
Dim pps As IPropertyStore
Dim tPK() As PROPERTYKEY
ReDim tPK(2)
oleexp.SHCreateItemFromParsingName StrPtr(Text1.Text), Nothing, IID_IShellItem, siPath
If (siPath Is Nothing) Then
Debug.Print "Invalid path."
Exit Sub
End If
tPK(0) = PKEY_FileName
tPK(1) = PKEY_Title
tPK(2) = PKEY_Music_AlbumTitle
siPath.BindToHandler 0&, BHID_EnumItems, IID_IEnumShellItems, pEnum
Do While pEnum.Next(1&, siChild, pc) = S_OK
If (siChild Is Nothing) = False Then
Set si2 = siChild
si2.GetPropertyStoreForKeys tPK(0), UBound(tPK) + 1&, GPS_OPENSLOWITEM Or GPS_BESTEFFORT, IID_IPropertyStore, pps
If (pps Is Nothing) = False Then
pps.GetValue PKEY_Title, vpv
PropVariantToVariant vpv, vbv
sTitle = CStr(vbv)
pps.GetValue PKEY_Music_AlbumTitle, vpv
PropVariantToVariant vpv, vbv
sAlbum = CStr(vbv)
pps.GetValue PKEY_FileName, vpv
PropVariantToVariant vpv, vbv
sFile = CStr(vbv)
sOut = sFile & " Title=" & sTitle & ",Album=" & sAlbum
List1.AddItem sOut
End If
End If
Set si2 = Nothing
Set siChild = Nothing
Loop
End Sub
As you can see, it uses the GetPropertyStoreForKeys method to get a limited-purpose PropertyStore with only the items we're interested, instead a store were you can access any property.
If you want to add another tag to read, add the PROPERTYKEY to tPK. The keys have to actual PROPERTYKEY structures though, not strings. See Module1.bas in the project. If you never want to have to worry about defining Property Keys, oleexp.tlb comes with a module called mPKEY.bas with all general purpose keys-- you can add the module, and only what you use will be compiled into your project, not the whole thing.
Using the PROPERTYKEY type:
Code:
Public Sub DEFINE_PROPERTYKEY(Name As PROPERTYKEY, L As Long, w1 As Integer, w2 As Integer, B0 As Byte, b1 As Byte, b2 As Byte, B3 As Byte, b4 As Byte, b5 As Byte, b6 As Byte, b7 As Byte, pid As Long)
With Name.fmtid
.Data1 = L: .Data2 = w1: .Data3 = w2
.Data4(0) = B0: .Data4(1) = b1: .Data4(2) = b2: .Data4(3) = B3: .Data4(4) = b4: .Data4(5) = b5: .Data4(6) = b6: .Data4(7) = b7
End With
Name.pid = pid
End Sub
Public Function PKEY_Music_AlbumTitle() As PROPERTYKEY
Static pkk As PROPERTYKEY
If (pkk.fmtid.Data1 = 0&) Then Call DEFINE_PROPERTYKEY(pkk, &H56A3372E, &HCE9C, &H11D2, &H9F, &HE, &H0, &H60, &H97, &HC6, &H86, &HF6, 4)
PKEY_Music_AlbumTitle = pkk
End Function
and they go on like that in module, with something similar for IID_ values.
Saves you from having to convert string to GUID then GUID+PID to PROPERTYKEY.
Regarding PKEY_ThumbnailStream... that's the cover image, JPG or PNG... you really don't want to pre-load 7,500 of these... you can't display that many at once unless you've got like a giant video wall, and might have memory issues. Load them on demand.
Last edited by fafalone; Apr 23rd, 2021 at 01:51 AM.