Nice one Terry. I did something similar a while back -- you might like to see how I've split off the cookies and history items from the actual cache files:
Code: Select all
; -----------------------------------------------------------------------------
; Internet Explorer cache file enumeration (with optional deletion)...
; -----------------------------------------------------------------------------
; james @ hi - toro . com
; -----------------------------------------------------------------------------
; BUG: Update listview column marker off when refreshed...
; Cache entry structure...
Structure INTERNET_CACHE_ENTRY_INFO
    dwStructSize.l
    lpszSourceUrlName.s
    lpszLocalFileName.s
    CacheEntryType.l
    dwUseCount.l
    dwHitRate.l
    dwSizeLow.l
    dwSizeHigh.l
    LastModifiedTime.FILETIME
    ExpireTime.FILETIME
    LastAccessTime.FILETIME
    LastSyncTime.FILETIME
    *lpHeaderInfo.l
    dwHeaderInfoSize.l
    lpszFileExtension.s
    StructureUnion
        dwReserved.l
        dwExemptDelta.l
    EndStructureUnion
EndStructure
#COOKIE_CACHE_ENTRY = $100000
#URLHISTORY_CACHE_ENTRY = $200000
                    
#NORMAL = 0
#COOKIE = 1
#HISTORY = 2
Structure CACHEITEM
    url.s
    cachetype.l
EndStructure
NewList urls.CACHEITEM ()
; Library number we'll use for wininet.dll...
#WININET = 9998
Procedure GetCacheEntries ()
    ClearList (urls ())
    
    ; Open wininet.dll...
    If OpenLibrary (#WININET, "wininet.dll")
        ; First call must fail in order to get size required for structure's buffer (fbuffsize)...
        
        enum = CallFunction (#WININET, "FindFirstUrlCacheEntryA", #NULL, @fail, @fbuffsize)
        
        If enum = #NULL
        
            ; Need larger buffer...
            
            If GetLastError_ () = #ERROR_INSUFFICIENT_BUFFER
            
                ; Allocate a buffer of the required size, with cache entry structure...
                    
                *ic.INTERNET_CACHE_ENTRY_INFO = AllocateMemory (fbuffsize)
                
                ; Try again with new size and buffer...
                
                enum = CallFunction (#WININET, "FindFirstUrlCacheEntryA", #NULL, *ic.INTERNET_CACHE_ENTRY_INFO, @fbuffsize)
                
                If enum <> #NULL
                
                    ; Got first cache entry!
                    AddElement (urls ())
                    urls ()\url = *ic\lpszSourceUrlName
                    
                    If *ic\CacheEntryType & #COOKIE_CACHE_ENTRY
                        urls ()\cachetype = #COOKIE
                    Else
                        If *ic\CacheEntryType & #URLHISTORY_CACHE_ENTRY
                            urls ()\cachetype = #HISTORY
                        Else
                            urls ()\cachetype = #NORMAL
                        EndIf
                    EndIf
                    
                    ; Release the buffer...
                    
                    FreeMemory (*ic)
                    ; Now iterate through the rest...
                    
                    *ic = #NULL ; Being a good citizen since I intend to use this pointer again...
                    
                    Repeat
                        ; *ic is #NULL on the first call, and nbuffsize is 0 (it will be given correct value if there is an entry)...
                        
                        result = CallFunction (#WININET, "FindNextUrlCacheEntryA", enum, *ic.INTERNET_CACHE_ENTRY_INFO, @nbuffsize)
                        If result = #FALSE
                            ; Failed, so was it due to insufficient buffer, or end of cache entries?
                            
                            error = GetLastError_ ()
                            Select error
                                Case #ERROR_NO_MORE_ITEMS
                                    ; End of cache entries -- 'done' variable is used to exit Repeat... Until loop...
                                    done = #TRUE
                                Case #ERROR_INSUFFICIENT_BUFFER
                                    ; nbuffsize was 0, so allocate buffer (FindNextUrlCacheEntryA gave nbuffsize the correct value)...
                                    
                                    *ic.INTERNET_CACHE_ENTRY_INFO = AllocateMemory (nbuffsize)
                                    ; (This will then hit 'Until' and go back to 'Repeat', calling the function with a buffer, plus correct nbuffsize.)
                                    
                            EndSelect
                        Else
                            ; FindNextUrlCacheEntryA returned #TRUE in 'result' variable...
                            AddElement (urls ())
                            urls ()\url = *ic\lpszSourceUrlName
                            If *ic\CacheEntryType & #COOKIE_CACHE_ENTRY
                                urls ()\cachetype = #COOKIE
                            Else
                                If *ic\CacheEntryType & #URLHISTORY_CACHE_ENTRY
                                    urls ()\cachetype = #HISTORY
                                Else
                                    urls ()\cachetype = #NORMAL
                                EndIf
                            EndIf
                            
                            ; Free this buffer now...
                            
                            FreeMemory (*ic)
                            
                            ; Reset nbuffsize to 0 so next FindNextUrlCacheEntryA will fail and allocate buffer as before...
                            
                            nbuffsize = 0
                        EndIf
                    Until done
                    
                    ; Release cache enumeration handle...
                    CallFunction (#WININET, "FindCloseUrlCache", enum)
                    
                EndIf
                
            EndIf
            
        EndIf
        ; Close wininet.dll...
        
        CloseLibrary (#WININET)
        
    EndIf
EndProcedure
Global url, hist, cook
Procedure ResizeGadgets ()
        
            wheight = WindowHeight () - (MenuHeight () + 3)
            ResizeGadget (0, 0, 0, WindowWidth (), (wheight - 25) / 3)
            ResizeGadget (1, 0, (wheight - 25) / 3, WindowWidth (), (wheight - 25) / 3)
            ResizeGadget (2, 0, ((wheight - 25) / 3) * 2, WindowWidth (), (wheight - 25) / 3)
            If SendMessage_ (url, #LVM_GETCOUNTPERPAGE, 0, 0) <= SendMessage_ (url, #LVM_GETITEMCOUNT, 0, 0)
                colwidth = GadgetWidth (0) - (GetSystemMetrics_ (#SM_CXVSCROLL) + GetSystemMetrics_ (#SM_CXSIZEFRAME))
            Else
                colwidth = GadgetWidth (0) - GetSystemMetrics_ (#SM_CXSIZEFRAME)
            EndIf
            SendMessage_ (url, #LVM_SETCOLUMNWIDTH, 0, colwidth)
            If SendMessage_ (hist, #LVM_GETCOUNTPERPAGE, 0, 0) < SendMessage_ (hist, #LVM_GETITEMCOUNT, 0, 0)
                colwidth = GadgetWidth (1) - (GetSystemMetrics_ (#SM_CXVSCROLL) + GetSystemMetrics_ (#SM_CXSIZEFRAME))
            Else
                colwidth = GadgetWidth (1) - GetSystemMetrics_ (#SM_CXSIZEFRAME)
            EndIf
            SendMessage_ (hist, #LVM_SETCOLUMNWIDTH, 0, colwidth)
            If SendMessage_ (cook, #LVM_GETCOUNTPERPAGE, 0, 0) < SendMessage_ (cook, #LVM_GETITEMCOUNT, 0, 0)
                colwidth = GadgetWidth (2) - (GetSystemMetrics_ (#SM_CXVSCROLL) + GetSystemMetrics_ (#SM_CXSIZEFRAME))
            Else
                colwidth = GadgetWidth (2) - GetSystemMetrics_ (#SM_CXSIZEFRAME)
            EndIf
            SendMessage_ (cook, #LVM_SETCOLUMNWIDTH, 0, colwidth)
            ResizeGadget (3, 0, wheight - 23, WindowWidth () / 4, 25)
            ResizeGadget (4, WindowWidth () / 4, wheight - 23, WindowWidth () / 4, 25)
            ResizeGadget (5, (WindowWidth () / 4) * 2, wheight - 23, WindowWidth () / 4, 25)
            ResizeGadget (6, ((WindowWidth () / 4) * 3) + 32, wheight - 23, (WindowWidth () / 4) - 32, 25)
EndProcedure
Procedure WindowHook (WindowID, Message, wParam, lParam) 
    result = #PB_ProcessPureBasicEvents
    
    Select Message
    
        Case #WM_SIZE
            ResizeGadgets ()
            
    EndSelect
    
    ProcedureReturn result
    
EndProcedure 
Procedure FillCacheList ()
    GetCacheEntries ()
    ClearGadgetItemList (0)
    ClearGadgetItemList (1)
    ClearGadgetItemList (2)
    
    ResetList (urls ())
    While NextElement (urls ())
        Select urls ()\cachetype
            Case #COOKIE
                AddGadgetItem (2, -1, Right (urls ()\url, Len (urls ()\url) - 7))
                SetGadgetItemState (2, -1, #PB_ListIcon_Checked)
            Case #HISTORY
                AddGadgetItem (1, -1, Right (urls ()\url, Len (urls ()\url) - 9))
                SetGadgetItemState (1, -1, #PB_ListIcon_Checked)
            Default
                AddGadgetItem (0, -1, urls ()\url)
                SetGadgetItemState (0, -1, #PB_ListIcon_Checked)
        EndSelect
    Wend
    
    SendMessage_ (url, #LVM_SORTITEMS, 0, 0)
    SendMessage_ (hist, #LVM_SORTITEMS, 0, 0)
    SendMessage_ (cook, #LVM_SORTITEMS, 0, 0)
EndProcedure
; The cache items are prefixed by "Visited: " for history items, and "Cookie: " for cookies, but these prefixes
; are in different languages on non-English versions of Windows. This should get the correct prefix from the
; Registry...
#HISTORY_PREFIX = 1
#COOKIE_PREFIX = 2
Procedure.s GetCachePrefix (prefix)
    If prefix = #HISTORY_PREFIX
        subkey$ = "Software\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\Cache\History"
    Else
        If prefix = #COOKIE_PREFIX
            subkey$ = "Software\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\Cache\Cookies"
        EndIf
    EndIf
    result = RegOpenKeyEx_ (#HKEY_CURRENT_USER, subkey$, 0, #KEY_ALL_ACCESS, @handle)
    If result = #ERROR_SUCCESS
        buffer$ = Space (255)
        size.l = 255
        RegQueryValueEx_ (handle, "CachePrefix", #NULL, @type, @buffer$, @size)
        RegCloseKey_ (handle)
    EndIf
    ProcedureReturn buffer$
EndProcedure
If ReadFile (0, "window.dat")
    x = Val (ReadString ())
    y = Val (ReadString ())
    width = Val (ReadString ())
    height = Val (ReadString ())
    CloseFile (0)
Else
    x = 0
    y = 0
    width = 600
    height = 360
    center = #PB_Window_ScreenCentered
EndIf
Procedure SaveWindow ()
    If CreateFile (0, "window.dat")
        WriteStringN (Str (WindowX ()))
        WriteStringN (Str (WindowY ()))
        WriteStringN (Str (WindowWidth ()))
        WriteStringN (Str (WindowHeight ()))
        CloseFile (0)
    EndIf
EndProcedure
If OpenWindow (0, x, y, width, height, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_Invisible | center, "Johnny Cache")
    CreateMenu (0, WindowID ())
    MenuTitle ("&File")
    MenuItem (0, "About...")
    MenuBar ()
    MenuItem (1, "E&xit")
    
    SetWindowCallback (@ WindowHook ())
    
    If CreateGadgetList (WindowID ())
    
        wheight = WindowHeight () - (MenuHeight () + 3)
        url = ListIconGadget (0, 0, 0, WindowWidth (), (wheight - 25) / 3, "URLs", WindowWidth () - GetSystemMetrics_ (#SM_CXSIZEFRAME), #PB_ListIcon_CheckBoxes | #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
        hist = ListIconGadget (1, 0, (wheight- 25) / 3, WindowWidth (), (wheight - 25) / 3, "History", WindowWidth () - GetSystemMetrics_ (#SM_CXSIZEFRAME), #PB_ListIcon_CheckBoxes | #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
        cook = ListIconGadget (2, 0, ((wheight - 25) / 3) * 2, WindowWidth (), (wheight - 25) / 3, "Cookies", WindowWidth () - GetSystemMetrics_ (#SM_CXSIZEFRAME), #PB_ListIcon_CheckBoxes | #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
        
        SendMessage_ (url, #LVM_SETCOLUMNWIDTH, 0,  GadgetWidth (0) - (GetSystemMetrics_ (#SM_CXVSCROLL) + GetSystemMetrics_ (#SM_CXSIZEFRAME)))
        SendMessage_ (hist, #LVM_SETCOLUMNWIDTH, 0, GadgetWidth (0) - (GetSystemMetrics_ (#SM_CXVSCROLL) + GetSystemMetrics_ (#SM_CXSIZEFRAME)))
        SendMessage_ (cook, #LVM_SETCOLUMNWIDTH, 0, GadgetWidth (0) - (GetSystemMetrics_ (#SM_CXVSCROLL) + GetSystemMetrics_ (#SM_CXSIZEFRAME)))
        
        ButtonGadget (3, 0, wheight - 23, WindowWidth () / 4, 25, "Invert URLs")
        ButtonGadget (4, WindowWidth () / 4, wheight - 23, WindowWidth () / 4, 25, "Invert history")
        ButtonGadget (5, (WindowWidth () / 4) * 2, wheight - 23, WindowWidth () / 4, 25, "Invert cookies")
        
        ButtonGadget (6, ((WindowWidth () / 4) * 3) + 32, wheight - 23, (WindowWidth () / 4) - 32, 25, "Delete selected...")
        FillCacheList ()
                
        HideWindow (0, 0)
        
        Repeat
        
            Select WaitWindowEvent ()
            
                Case #PB_Event_Menu
                
                    Select EventMenuID ()
                        Case 0
                            MessageRequester ("Johnny Cache", "Johnny Cache, a public domain cache manager for Internet Explorer 4+ by Hi-Toro 2003.", #MB_ICONINFORMATION)
                        Case 1
                            SaveWindow ()
                            End
                    EndSelect
                    
                Case #PB_Event_CloseWindow
                    SaveWindow ()
                    End
                    
                Case #PB_Event_Gadget
                
                    Select EventGadgetID ()
                        
                        Case 3
                            For item = 0 To SendMessage_ (url, #LVM_GETITEMCOUNT, 0, 0) - 1
                                If GetGadgetItemState (0, item) = #PB_ListIcon_Checked
                                    SetGadgetItemState (0, item, 0)
                                Else
                                    SetGadgetItemState (0, item, #PB_ListIcon_Checked)
                                EndIf
                            Next
                        Case 4
                        
                            For item = 0 To SendMessage_ (hist, #LVM_GETITEMCOUNT, 0, 0) - 1
                                If GetGadgetItemState (1, item) = #PB_ListIcon_Checked
                                    SetGadgetItemState (1, item, 0)
                                Else
                                    SetGadgetItemState (1, item, #PB_ListIcon_Checked)
                                EndIf
                            Next
                        Case 5
                        
                            For item = 0 To SendMessage_ (cook, #LVM_GETITEMCOUNT, 0, 0) - 1
                                If GetGadgetItemState (2, item) = #PB_ListIcon_Checked
                                    SetGadgetItemState (2, item, 0)
                                Else
                                    SetGadgetItemState (2, item, #PB_ListIcon_Checked)
                                EndIf
                            Next
                        
                        Case 6
                            count = 0
                            
                            For item = 0 To SendMessage_ (url, #LVM_GETITEMCOUNT, 0, 0) - 1
                                If GetGadgetItemState (0, item) = #PB_ListIcon_Checked
                                    count = count + 1
                                EndIf
                            Next
                            For item = 0 To SendMessage_ (hist, #LVM_GETITEMCOUNT, 0, 0) - 1
                                If GetGadgetItemState (1, item) = #PB_ListIcon_Checked
                                    count = count + 1
                                EndIf
                            Next
                            For item = 0 To SendMessage_ (cook, #LVM_GETITEMCOUNT, 0, 0) - 1
                                If GetGadgetItemState (2, item) = #PB_ListIcon_Checked
                                    count = count + 1
                                EndIf
                            Next
                        
                            If count
                            
                                If MessageRequester ("Johnny Cache", "Do you really want to delete the selected cache items?", #MB_ICONWARNING | #PB_MessageRequester_YesNo) = #IDYES
                                    If OpenLibrary (#WININET, "wininet.dll")
                                    
                                        For item = 0 To SendMessage_ (url, #LVM_GETITEMCOUNT, 0, 0) - 1
                                            If GetGadgetItemState (0, item) = #PB_ListIcon_Checked
                                                CallFunction (#WININET, "DeleteUrlCacheEntry", GetGadgetItemText (0, item, 0))
                                            EndIf
                                        Next
                                        For item = 0 To SendMessage_ (hist, #LVM_GETITEMCOUNT, 0, 0) - 1
                                            If GetGadgetItemState (1, item) = #PB_ListIcon_Checked
                                                If CallFunction (#WININET, "DeleteUrlCacheEntry", GetCachePrefix (#HISTORY_PREFIX) + " " + GetGadgetItemText (1, item, 0)) = 0
                                                    CallFunction (#WININET, "DeleteUrlCacheEntry", GetCachePrefix (#HISTORY_PREFIX) + " " + GetGadgetItemText (1, item, 0))
                                                EndIf
                                            EndIf
                                        Next
                                        For item = 0 To SendMessage_ (cook, #LVM_GETITEMCOUNT, 0, 0) - 1
                                            If GetGadgetItemState (2, item) = #PB_ListIcon_Checked
                                                If CallFunction (#WININET, "DeleteUrlCacheEntry", GetCachePrefix (#COOKIE_PREFIX) + " " + GetGadgetItemText (2, item, 0)) = 0
                                                    CallFunction (#WININET, "DeleteUrlCacheEntry", GetCachePrefix (#COOKIE_PREFIX) + " " + GetGadgetItemText (2, item, 0))
                                                EndIf
                                            EndIf
                                        Next
                                    
                                        CloseLibrary (#WININET)
                                        FillCacheList ()
                                        
                                        ResizeGadgets ()
                                        
                                    EndIf
                                EndIf
                            Else
                                 MessageRequester ("Johnny Cache", "No cache items selected!", #MB_ICONINFORMATION)
                                                                
                            EndIf
                                                        
                    EndSelect
                    
            EndSelect
            
        ForEver
    EndIf
Else
    MessageRequester ("Johnny Cache", "Error opening window. Deleting window config -- try running again!", #MB_ICONWARNING)
    DeleteFile ("window.dat")
EndIf
Yours looks way nicer, but mine does have a much better name...