Results 1 to 8 of 8

Thread: How to get the info from the shell about the headers in "Detailed" view

Threaded View

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2023
    Posts
    976

    How to get the info from the shell about the headers in "Detailed" view

    The information is the caption for every header item in "detailed" view with 0-based index.
    For example: 0 = Name, 1 = Size, 2 = Type, 3 = Date etc etc.

    You need any type lib that can handle IShellFolder, IShellfolder2 and IShellItem.

    Code:
    Public Function GetShellColumns(ByVal pidl As Long, ByVal iColumn As Long, ByRef lpzColText As Long, Optional ByRef nColFormat As Long)
      Dim hr As Long
      Dim pISI As IShellItem
      Dim pISF As IShellFolder
      Dim pISF2 As IShellFolder2
      Dim lpSD As SHELLDETAILS
      
      'If pidl is zero there is nothing to do...so just exit the function
      If pidl = 0 Then Exit Function
      
      'Get the shellitem from pidl
      hr = SHCreateItemFromIDList(pidl, IID_IShellItem, pISI)
     
      'if hr <> S_OK can depend on following...
      'If the pidl couldn't give us a shellitem, just exit the function BUT (Desktop pidl DOESN'T expose a shellitem so check if this is the Desktop pidl or not!)
      'If is this the desktop we need to fix it. This about the desktop is a bit tricky because you have a given pidl but it's empty = zero - then it's the desktop pidl.
      If ShIsDeskTopPidl(pidl) = True Then
        Set pISF = m_cShell32.GetDesktopFolder
      Else
        'It's not the the desktop pidl so just proceed as normal...
        hr = SHCreateItemFromIDList(pidl, IID_IShellItem, pISI)
        'It's not the Desktop and the pidl still not want to expose any shellitem we must asume there is an error so just quit the function.
        If hr <> S_OK Then Exit Function
      End If
      
      'We can assume the Shellfolder still not set (if it's not the desktop) so let's set it
      If pISF Is Nothing Then
        'Bind it to the ishellitem - YOU MUST BIND THE ISHELLFOLDER BECAUSE ISHELLITEM DOES NOT PROVIDE THIS INFORMATION!!
        hr = pISI.BindToHandler(0, BHID_SFObject, IID__IShellFolder, pISF)
        If hr <> S_OK Then Exit Function
        'IShellFolder2 got expanded features needed for this so just set it - See MSDN for further info.
        Set pISF2 = pISF
        hr = pISF2.GetDetailsOf(pidl, iColumn, lpSD)
        'If there was any error just quit the function
        If hr <> S_OK Then Exit Function
        'Return the info from the column (format and text)
        nColFormat = lpSD.fmt
        'I have to assumed we use 64 bit UNICODE - If not switch to the StrRetToStrA version
        'Since we not use pOleStr (this member is deleted) we use Cstr member ONLY.
        StrRetToStrW lpSD.Str, pidl, lpzColText
      Else
        'It was the desktop
        Set pISF2 = pISF
        hr = pISF2.GetDetailsOf(pidl, iColumn, lpSD)
        'If there was any error just quit the function
        If hr <> S_OK Then Exit Function
        'Return the info from the column (format and text)
        nColFormat = lpSD.fmt
        'I have assumed we use 64 bit or UNICODE - If not switch to the StrRetToStrA version
        'Since we not use use pOleStr (this member is deleted) we use Cstr member and therefore STRRET_WSTR also deleted.
        'Process the string pointer
        StrRetToStrW lpSD.Str, pidl, lpzColText
      End If
      'No need to free up on string pointers here because they are by Byref = outgoing
    
      'Free up pidl and zero the ref counts on involved interfaces
      CoTaskMemFree pidl
      Set pISF = Nothing
      Set pISF2 = Nothing
      Set pISI = Nothing
    End Function
    
    Public Function GetStrAFromStrPtrW(ByVal lpzStrPtr As Long) As String
      'If the pointer is 0 threr is nothing to do- exit function
      If lpzStrPtr = 0 Then Exit Function
      
      'Call the API that reallocates your string pointer and pass it as VarPtr and NOT StrPtr (there is a ceration difference in this)
      SysReAllocString VarPtr(GetStrAFromStrPtrW), lpzStrPtr
      'Clean up the memory of the outgoing pointer.
      Call CoTaskMemFree(lpzStrPtr)
    End Function
    
    Private Sub Command1_Click()
     Dim lpzText As Long
     Dim dwColFlags As Long
     Dim pidl As long
     
     pidl = ILCreateFromPathW(StrPtr("C:\"))
     
     'You can if you feel for it enum this function and set the max enum value to aprox 20 something (I'm not sure how many there is because it depends on the locals..you will realize it then the panels more than names is enumerated because they become blank)
     GetShellColumns pidl, 0, lpzText, dwColFlags
      
     MsgBox GetStrAFromStrPtrW(lpzText)
    
    End Sub
    Last edited by nebeln; Jan 13th, 2024 at 06:40 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width