home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 6_2008-2009.ISO / data / zips / FYI__Impor2144142162009.psc / clsLstVwExportImport.cls < prev   
Text File  |  2009-02-15  |  65KB  |  1,435 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "clsLstVwExportImport"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' SUPPORTS V6 Common Controls only!!!
  17.  
  18. ' -----------------------------------------------------------------------------------------------------------------------------------------------------------------
  19. ' These two events are very important for Importing. Respond to them
  20. ' So, always declare this class WithEvents
  21.  
  22. Public Event ImportSummary(ByVal ColumnHeadersIncluded As Boolean, ByVal ImageListsNeeded As Long, ByVal ListItems As Boolean, ByRef Continue As Boolean)
  23.  
  24. ' This event is called to allow you to change any class properties and/or allow/prevent some things from being imported
  25.  
  26. ' ColumnHeadersIncluded: Indicates whether or not the import file includes column headers.
  27. '   :: Here you should either allow or prevent column headers from being imported if the parameter is True
  28. '   :: To Allow
  29. '       ::: Ensure the class' IncludeColumnHeaders property is True
  30. '       ::: As a side note, set the class' IncludeHeaderTags property as desired
  31. '   :: To Prevent
  32. '       ::: Ensure the class' IncludeColumnHeaders property is False
  33. '   :: note... If no headers are provided or you prevent them from being imported, you should manually add them
  34. '               if the listview's View property is Report; otherwise, you may not see the items even though they exist
  35.  
  36. ' ImageListsNeeded: If non-zero, ImageList(s) exist in the file and it is assumed that columnheaders and/or listitems use the imagelists
  37. '   :: Here you should either allow or prevent imagelists from being imported
  38. '   :: To Allow
  39. '       ::: Ensure the class' IncludeImageLists property is True
  40. '       ::: Reply to the SetImageList event and pass the ImportToImageList parameter when called
  41. '           -- At most, 3 image lists may be required. These can already exist or be created/destroyed dynamically
  42. '           -- Ensure any passed ImageList is not referenced by any other controls, else no images will be imported
  43. '           -- Images are never appended, the ImageList control is cleared and the exported images are uploaded
  44. '           -- The SetImageList event can be called up to 3 times
  45. '   :: To Prevent
  46. '       ::: Ensure the class' IncludeImageLists property is False
  47. '       ::: You may also reply to the SetImageList event and pass Nothing as the ImportToImageList parameter
  48. '       ::: If your ListView will be using an existing/populated imagelist control, ensure you set its references
  49.  
  50. ' ListItems: FYI only, indicates how many list items exist in the file
  51. '   :: Here you should decide whether to clear the listview or not.
  52. '   :: If not cleared, the listitems will be appended to the listview
  53. '       ::: As a side note, set the class' IncludeListItemTags & IncludeTextFormatting properties as desired
  54.  
  55. ' Continue: Passed as False. Set to True to allow import to continue else importing is aborted
  56.  
  57. Public Event SetImageList(ByVal ListViewSection As lvImportImageList, ByRef ImportToImageList As MSComctlLib.ImageList)
  58. ' Called only when these 2 cases are true
  59. '   1. The file to import contains ImageList(s)
  60. '   2. This class' IncludeImageLists property is True
  61. '   :: When called, it will only be called for each unique imagelist control required.
  62. '       -- If the SmallIcon and ColumnHeaderIcons ImageList references for the ListView are the same ImageList,
  63. '           then this is called only one time instead of twice
  64. '       -- This can be called from 1 to 3 times depending on how many unique ImageLists exist in the file to be imported
  65. '   :: If this event is not called (you prevented it from being called or there was no image list exported), you
  66. '       should manually set the listview's imagelist references if needed
  67.  
  68. ' :: When Exporting, these properties should be set as desired BEFORE calling the ExportToFile function
  69. ' IncludeControlFormatting: Exports the ListView control's physical appearance both client & non-client area
  70. ' IncludeTextFormatting: Exports list item text forecolor & boldness
  71. ' IncludeColumnHeaders: Exports column headers and all their properties
  72. ' IncludeHeaderTags: Exports the column header tags, if any
  73. ' IncludeImageLists: Exports each ImageList control used by the ListView
  74. ' IncludeListItemTags: Exports each ListView ListItem & SubItem tag, if any
  75.  
  76. ' Notes
  77. ' 1. The MsgBox calls in ImportFromFile & ExportToFile are more for debugging purposes. You may want to disable those lines & rely on the return function
  78. ' -----------------------------------------------------------------------------------------------------------------------------------------------------------------
  79.  
  80.  
  81.  
  82. ' Kernel32/User32 APIs for Unicode Filename Support
  83. Private Declare Function CreateFileW Lib "kernel32" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
  84. Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
  85. Private Declare Function SetFileAttributesW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal dwFileAttributes As Long) As Long
  86. Private Declare Function SetFileAttributes Lib "kernel32.dll" Alias "SetFileAttributesA" (ByVal lpFileName As String, ByVal dwFileAttributes As Long) As Long
  87. Private Declare Function GetFileAttributesW Lib "kernel32.dll" (ByVal lpFileName As Long) As Long
  88. Private Declare Function GetFileAttributes Lib "kernel32.dll" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
  89. Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
  90. Private Declare Function IsWindowUnicode Lib "user32.dll" (ByVal hWnd As Long) As Long
  91. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
  92. Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, Optional ByVal lpOverlapped As Long = 0&) As Long
  93. Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, Optional ByVal lpOverlapped As Long = 0&) As Long
  94. Private Declare Function SetFilePointer Lib "kernel32.dll" (ByVal hFile As Long, ByVal lDistanceToMove As Long, ByRef lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
  95. Private Const INVALID_HANDLE_VALUE = -1
  96. Private Const FILE_ATTRIBUTE_NORMAL = &H80&
  97.  
  98. ' used for workaround of VB not exposing IStream interface
  99. Private Declare Function DispCallFunc Lib "oleaut32" (ByVal ppv As Long, ByVal oVft As Long, ByVal cc As Long, ByVal rtTYP As VbVarType, ByVal paCNT As Long, ByVal paTypes As Long, ByVal paValues As Long, ByRef fuReturn As Variant) As Long
  100. Private Declare Function GlobalAlloc Lib "kernel32" (ByVal uFlags As Long, ByVal dwBytes As Long) As Long
  101. Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Long, pPStm As Any) As Long
  102. Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
  103. Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
  104. Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
  105. Private Declare Function GetHGlobalFromStream Lib "ole32" (ByVal pPStm As Long, hGlobal As Long) As Long
  106. Private Declare Function OleSaveToStream Lib "ole32.dll" (ByVal pPStm As Long, ByVal pStm As stdole.IUnknown) As Long
  107. Private Declare Function OleLoadPicture Lib "olepro32" (pStream As Any, ByVal lSize As Long, ByVal fRunmode As Long, riid As Any, ppvObj As Any) As Long
  108. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
  109.  
  110. ' These structures are used to help organize code & make code more user-friendly
  111. Private Type StructureFileHeader
  112.     MagicNumber As Long                 ' identifier for this type of file
  113.     Version As Single                    ' version (integer=Ansi, decimal=Unicode)
  114.     ImageListOffset As Long
  115.     HeadersOffset As Long               ' position in file where column headers begin
  116.     ListItemOffset As Long              ' position in file where listitems begin
  117.     Columns As Long                     ' number of column headers
  118.     Items As Long                       ' how many list items
  119.     ImageLists As Long                  ' number of exported listimages
  120.     Flags As Long                       ' whether headers/imagelists/tags are written to file
  121.     ListViewStructSize As Long          ' size of the StructureListview used
  122. End Type                                ' 36 bytes used for import/export
  123. Private Type StructureListView
  124.     AllowColumnReorder As Byte
  125.     AppearanceFlat As Byte
  126.     BorderStyleNone As Byte
  127.     Checkboxes As Byte
  128.     FlatScrollBar As Byte
  129.     FullRowSelect As Byte
  130.     GridLines As Byte
  131.     HideColumnHeaders As Byte
  132.     HotTracking As Byte
  133.     HoverSelection As Byte
  134.     LabelEditManual As Byte
  135.     LabelWrap As Byte
  136.     MultiSelect As Byte
  137.     Sorted As Byte
  138.     SortOrderDesc As Byte
  139.     TextBkgOpaque As Byte               ' 16 bytes
  140.     Arrange As Integer
  141.     PictureAlignment As Integer
  142.     SortKey As Integer
  143.     View As Integer                     ' 8 bytes
  144.     BackColor As Long
  145.     ForeColor As Long                   ' 8 bytes
  146.     Tag As String                       ' 4 bytes (not used for export, used for import)
  147. End Type                                ' 32 bytes used for export
  148. Private Type StructureHeaders
  149.     Position As Long
  150.     Left As Single
  151.     Width As Single                     ' 12 bytes
  152.     Alignment As Integer
  153.     TagType As Integer
  154.     IconType As Integer                 ' 6 bytes (18 bytes used for export)
  155.     Text As String                      ' 4 bytes (following used during import only)
  156.     Key As String                       ' 4 bytes
  157.     Tag As Variant                      ' 16 bytes
  158.     Icon As Variant                     ' 16 bytes
  159. End Type
  160. Private Type StructureImageList
  161.     Count As Long
  162.     BackColor As Long
  163.     MaskColor As Long                   ' 12 bytes
  164.     ImageWidth As Integer
  165.     ImageHeight As Integer
  166.     UseMaskColor As Boolean             ' 6 bytes
  167.     Tag As String                       ' 4 bytes
  168. End Type                                ' 18 bytes used for export
  169. Private Type StructureListItem
  170.     SubCount As Long
  171.     ForeColor As Long
  172.     IconTypes As Long                   ' 12 bytes
  173.     TagType As Integer
  174.     BoldChecked As Integer              ' 4 bytes
  175.     Text As String
  176.     Tooltip As String
  177.     Key As String
  178.     IconSm As Variant
  179.     IconLg As Variant
  180.     Tag As Variant                      ' 16 bytes used for export, all used for import
  181. End Type
  182. Private Type StructureListSubItem
  183.     ForeColor As Long                   ' 4 bytes
  184.     IconType As Integer
  185.     TagType As Integer                  ' 4 bytes
  186.     Bold As Byte                        ' 1 byte
  187.     Text As String
  188.     Tooltip As String
  189.     Key As String
  190.     ReportIcon As Variant
  191.     Tag As Variant                      ' 9 bytes used for export, all used for import
  192. End Type
  193. Private Type StructureFont
  194.     Attributes As Long              ' bold,italic,underline,strikethru
  195.     CharSet As Integer
  196.     Weight As Integer
  197.     Size As Currency                ' 16 bytes used for export, all used for import
  198.     Name As String
  199. End Type
  200.  
  201. Public Enum lvImportImageList
  202.     ilColumnHeaders = 1
  203.     ilLargeIcons = 2
  204.     ilSmallIcons = 3
  205. End Enum
  206. Private Enum lvFlags
  207.     fgHasImageList = 1
  208.     fgHasHeaderTags = 2
  209.     fgHasItemTags = 4
  210.     fgHasHeaders = 8
  211.     fgHasCtrlFormat = 16
  212.     fgHasTextFormat = 32
  213. End Enum
  214.  
  215. Private c_Flags As Long
  216. Private lvObject As MSComctlLib.ListView
  217.  
  218. Public Property Let IncludeImageLists(ByVal bInclude As Boolean)
  219.     ' initialized to False during class load
  220.     ' Exporting: If True, will cache the imagelist controls used by the listview to the same file, including all images else will not
  221.     ' Importing: If True, will overwrite existing imagelist controls (see 3 ImageList properties below) control & repopulate with the one saved in the file
  222.     '   :: If no imagelist was saved in the file, nothing will be done the imagelists
  223.     '   :: If property is False, no images will be extracted from the file
  224.     If bInclude <> Me.IncludeImageLists Then c_Flags = c_Flags Xor fgHasImageList
  225. End Property
  226. Public Property Get IncludeImageLists() As Boolean
  227.     IncludeImageLists = CBool(c_Flags And fgHasImageList)
  228. End Property
  229.     
  230. Public Property Let IncludeColumnHeaders(ByVal bInclude As Boolean)
  231.     ' initialized to True during class load
  232.     ' Exporting: If True, will include column headers and their individual properties else will not
  233.     ' Importing: If True, will clear the listiview and repopulate the headers from the file
  234.     '   :: If no column headers were saved in the file, then nothing will be done to the listview's original header columns
  235.     '   :: If property is False, no column headers will be extracted from the file
  236.     If bInclude <> Me.IncludeColumnHeaders Then c_Flags = c_Flags Xor fgHasHeaders
  237. End Property
  238. Public Property Get IncludeColumnHeaders() As Boolean
  239.     IncludeColumnHeaders = CBool(c_Flags And fgHasHeaders)
  240. End Property
  241.     
  242. Public Property Let IncludeHeaderTags(ByVal bInclude As Boolean)
  243.     ' initialized to False during class load
  244.     ' Exporting: If True, column header tags will be exported to the file else they will not
  245.     ' Importing: Applies only if IncludeColumnHeaders is True
  246.     '   :: If True, exported column header tags will be added to new column headers else null tags will be set
  247.     '   :: If the file was exported without column header tags, no action is taken
  248.     If bInclude <> Me.IncludeHeaderTags Then c_Flags = c_Flags Xor fgHasHeaderTags
  249. End Property
  250. Public Property Get IncludeHeaderTags() As Boolean
  251.     IncludeHeaderTags = CBool(c_Flags And fgHasHeaderTags)
  252. End Property
  253.     
  254. Public Property Let IncludeListItemTags(ByVal bInclude As Boolean)
  255.     ' initialized to False during class load
  256.     ' Exporting: If True, list item tags & subItem tags will be exported to the file else they will not
  257.     ' Importing: If True, exported tags will be added to listItems & subItems else null tags will be set
  258.     '   :: if the file was exported without tags, no action is taken
  259.     If bInclude <> Me.IncludeListItemTags Then c_Flags = c_Flags Xor fgHasItemTags
  260. End Property
  261. Public Property Get IncludeListItemTags() As Boolean
  262.     IncludeListItemTags = CBool(c_Flags And fgHasItemTags)
  263. End Property
  264.  
  265. Public Property Let IncludeControlFormatting(ByVal bInclude As Boolean)
  266.     ' initialized to True during class load
  267.     ' Exporting: If True, the physical appearance of the listview control will be exported (borders, colors, font, picture, etc)
  268.     ' Importing: If True, the imported listview control will be changed to match the exported appearance
  269.     '   :: if the file was exported without the appearance, no action is taken
  270.     If bInclude <> Me.IncludeControlFormatting Then c_Flags = c_Flags Xor fgHasCtrlFormat
  271. End Property
  272. Public Property Get IncludeControlFormatting() As Boolean
  273.     IncludeControlFormatting = CBool(c_Flags And fgHasCtrlFormat)
  274. End Property
  275.  
  276. Public Property Let IncludeTextFormatting(ByVal bInclude As Boolean)
  277.     ' initialized to True during class load
  278.     ' Exporting: If True, the physical appearance of the listview items will be exported (colors, boldness)
  279.     ' Importing: If True, the imported listitems will be changed to match the exported appearance
  280.     '   :: if the file was exported without the appearance, no action is taken
  281.     If bInclude <> Me.IncludeTextFormatting Then c_Flags = c_Flags Xor fgHasTextFormat
  282. End Property
  283. Public Property Get IncludeTextFormatting() As Boolean
  284.     IncludeTextFormatting = CBool(c_Flags And fgHasTextFormat)
  285. End Property
  286.  
  287. Public Property Get ListViewReference() As MSComctlLib.ListView
  288.     ' ReadOnly property. Can be called during one of the public events if desired
  289.     ' to see which listview is being imported into
  290.     Set ListViewReference = lvObject
  291. End Property
  292.  
  293. Public Function ExportToFile(ListView As MSComctlLib.ListView, FileName As String, Optional SaveStringsANSI As Boolean = True) As Boolean
  294.  
  295.     ' Parameter SaveStringsANSI
  296.     ' :: can reduce filesize, but is slower overall
  297.     ' :: if using unicode strings for any part of the listview, set this to False
  298.  
  299.     If ListView Is Nothing Then Exit Function
  300.     If FileName = vbNullString Then Exit Function
  301.     
  302.     Dim fileNum As Long, useUnicode As Boolean, bSuccess As Boolean
  303.     Dim offsetHDR As Long, offsetLI As Long, offsetIL As Long
  304.     Dim vWritten As Long, imgListCount As Long
  305.     If IsWindowUnicode(GetDesktopWindow) Then useUnicode = True
  306.     
  307.     On Error GoTo EH
  308.     fileNum = GetFileHandle(FileName, False, useUnicode)
  309.     
  310.     Set lvObject = ListView
  311.     If WriteObjAttributes(fileNum, SaveStringsANSI, imgListCount) Then
  312.         offsetIL = SetFilePointer(fileNum, 0&, 0&, 1&)
  313.         If Me.IncludeImageLists = True And imgListCount > 0& Then
  314.             bSuccess = WriteImageLists(fileNum, SaveStringsANSI)
  315.         Else
  316.             bSuccess = True
  317.         End If
  318.         If bSuccess Then
  319.             offsetHDR = SetFilePointer(fileNum, 0&, 0&, 1&)
  320.             If Me.IncludeColumnHeaders = True And lvObject.ColumnHeaders.Count > 0& Then
  321.                 bSuccess = WriteHeaders(fileNum, SaveStringsANSI)
  322.             Else
  323.                 bSuccess = True
  324.             End If
  325.             If bSuccess Then
  326.                 offsetLI = SetFilePointer(fileNum, 0&, 0&, 1&)
  327.                 If lvObject.ListItems.Count > 0& Then
  328.                     bSuccess = WriteListItems(fileNum, SaveStringsANSI)
  329.                 Else
  330.                     bSuccess = True
  331.                 End If
  332.                 If bSuccess Then
  333.                     SetFilePointer fileNum, 8&, 0&, 0&
  334.                     WriteFile fileNum, offsetIL, 4&, vWritten
  335.                     WriteFile fileNum, offsetHDR, 4&, vWritten
  336.                     WriteFile fileNum, offsetLI, 4&, vWritten
  337.                 End If
  338.             End If
  339.         End If
  340.     End If
  341. EH:
  342.     If Not fileNum = INVALID_HANDLE_VALUE Then CloseHandle fileNum
  343.     If Err Then
  344.         MsgBox Err.Description, vbExclamation + vbOKOnly, "Failed to Export ListView Contents"
  345.         Err.Clear
  346.     ElseIf bSuccess Then
  347.         ExportToFile = bSuccess
  348.     Else
  349.         MsgBox "Failed to Export the ListView Contents", vbExclamation + vbOKOnly, "Error"
  350.     End If
  351.     Set lvObject = Nothing
  352.     
  353. End Function
  354.  
  355. Public Function ImportFromFile(ListView As MSComctlLib.ListView, ByVal FileName As String) As Boolean
  356.  
  357.     If ListView Is Nothing Then Exit Function
  358.     If FileName = vbNullString Then Exit Function
  359.     
  360.     Dim fileNum As Long, lLoc As Long
  361.     Dim bSuccess As Boolean, useUnicode As Boolean
  362.     Dim udtFile As StructureFileHeader
  363.     
  364.     If IsWindowUnicode(GetDesktopWindow) Then useUnicode = True
  365.     fileNum = GetFileHandle(FileName, True, useUnicode)
  366.     If fileNum = INVALID_HANDLE_VALUE Then
  367.         If FileExists(FileName, useUnicode) Then
  368.             MsgBox "Cannot access that file", vbExclamation + vbOKOnly, "Failed To Import ListView"
  369.         Else
  370.             MsgBox "The file: " & FileName & " does not exist", vbExclamation + vbOKOnly, "Failed to Import ListView"
  371.         End If
  372.         Exit Function
  373.     End If
  374.     
  375.     On Error GoTo EH
  376.     If ReadFileHeader(fileNum, udtFile) Then
  377.         ' prompt user with enough info to modify destination listview, set class properties, create imagelists, etc
  378.         RaiseEvent ImportSummary((udtFile.Columns > 0&), udtFile.ImageLists, udtFile.Items, bSuccess)
  379.         
  380.         If bSuccess Then
  381.             Set lvObject = ListView
  382.             If Me.IncludeControlFormatting = True And ((udtFile.Flags And fgHasCtrlFormat) = fgHasCtrlFormat) Then
  383.                 bSuccess = ReadObjAttributes(fileNum, udtFile)
  384.             Else
  385.                 bSuccess = True
  386.             End If
  387.             If bSuccess Then
  388.                 If Me.IncludeImageLists = True And udtFile.ImageLists > 0& Then
  389.                     lLoc = SetFilePointer(fileNum, 0&, 0&, 1&)
  390.                     SetFilePointer fileNum, udtFile.ImageListOffset - lLoc, 0&, 1&
  391.                     bSuccess = ReadImageLists(fileNum, udtFile)
  392.                 Else
  393.                     bSuccess = True
  394.                 End If
  395.                 If bSuccess Then
  396.                     If udtFile.Columns > 0& And Me.IncludeColumnHeaders = True Then
  397.                         lLoc = SetFilePointer(fileNum, 0&, 0&, 1&)
  398.                         SetFilePointer fileNum, udtFile.HeadersOffset - lLoc, 0&, 1&
  399.                         bSuccess = ReadHeaders(fileNum, udtFile)
  400.                     Else
  401.                         bSuccess = True
  402.                     End If
  403.                     If bSuccess Then
  404.                         If udtFile.Items > 0& Then
  405.                             lLoc = SetFilePointer(fileNum, 0&, 0&, 1&)
  406.                             SetFilePointer fileNum, udtFile.ListItemOffset - lLoc, 0&, 1&
  407.                             bSuccess = ReadListItems(fileNum, udtFile)
  408.                         Else
  409.                             bSuccess = True
  410.                         End If
  411.                         If (udtFile.Flags And 1024&) Then lvObject.Sorted = True
  412.                     End If
  413.                 End If
  414.             End If
  415.         End If
  416.     End If
  417. EH:
  418.     CloseHandle fileNum
  419.     Set lvObject = Nothing
  420.     If Err Then Err.Clear
  421.     ImportFromFile = bSuccess
  422.     If Not bSuccess Then MsgBox "Failed to Import Listview Contents", vbExclamation + vbOKOnly, "Failure"
  423. End Function
  424.  
  425. Private Function WriteObjAttributes(fileNum As Long, SaveStringsANSI As Boolean, imgListExported As Long) As Boolean
  426.     
  427.     ' Purpose: Write the overall listview attributes/properties
  428.     ' File is written/read in the following order
  429.     ' :: File Header
  430.     ' :: Font
  431.     ' :: Picture Property
  432.     ' :: Tag property
  433.     ' :: Control Properties
  434.     
  435.     Dim udtAttr As StructureListView
  436.     Dim udtFont As StructureFont
  437.     Dim udtFile As StructureFileHeader
  438.     Dim vWritten As Long
  439.     
  440.     On Error GoTo EH
  441.     With udtFile
  442.         .MagicNumber = 1447843404
  443.         If SaveStringsANSI Then .Version = 1! Else .Version = 1.1!
  444.         If Me.IncludeColumnHeaders Then .Columns = lvObject.ColumnHeaders.Count
  445.         .Items = lvObject.ListItems.Count
  446.         .Flags = c_Flags
  447.         .ListViewStructSize = 32&
  448.         If Me.IncludeImageLists Then
  449.             If Not lvObject.ColumnHeaderIcons Is Nothing Then .ImageLists = 1&
  450.             If Not lvObject.Icons Is Nothing Then
  451.                 If Not lvObject.Icons Is lvObject.ColumnHeaderIcons Then .ImageLists = .ImageLists + 1&
  452.             End If
  453.             If Not lvObject.SmallIcons Is Nothing Then
  454.                 If Not lvObject.SmallIcons Is lvObject.Icons Then
  455.                     If Not lvObject.SmallIcons Is lvObject.ColumnHeaderIcons Then .ImageLists = .ImageLists + 1&
  456.                 End If
  457.             End If
  458.         End If
  459.         imgListExported = .ImageLists
  460.     End With
  461.     SetFilePointer fileNum, 0&, 0&, 0&
  462.     WriteFile fileNum, udtFile, 40&, vWritten
  463.     If vWritten = 40& Then
  464.         
  465.         If Me.IncludeControlFormatting Then
  466.             On Error Resume Next
  467.             ' extract the listview properties; not all listview versions will have same properties,
  468.             ' therefore, we use the On Error statement
  469.             With udtAttr
  470.                 .AllowColumnReorder = Abs(lvObject.AllowColumnReorder)
  471.                 .AppearanceFlat = Abs(lvObject.Appearance = ccFlat)
  472.                 .Arrange = lvObject.Arrange
  473.                 .BackColor = lvObject.BackColor
  474.                 .BorderStyleNone = Abs(lvObject.BorderStyle = ccNone)
  475.                 .Checkboxes = Abs(lvObject.Checkboxes)
  476.                 .FlatScrollBar = Abs(lvObject.FlatScrollBar)
  477.                 .ForeColor = lvObject.ForeColor
  478.                 .FullRowSelect = Abs(lvObject.FullRowSelect)
  479.                 .GridLines = Abs(lvObject.GridLines)
  480.                 .HideColumnHeaders = Abs(lvObject.HideColumnHeaders)
  481.                 .HotTracking = Abs(lvObject.HotTracking)
  482.                 .HoverSelection = Abs(lvObject.HoverSelection)
  483.                 .LabelEditManual = Abs(lvObject.LabelEdit = lvwManual)
  484.                 .LabelWrap = Abs(lvObject.LabelWrap)
  485.                 .MultiSelect = Abs(lvObject.MultiSelect)
  486.                 .PictureAlignment = lvObject.PictureAlignment
  487.                 .Sorted = Abs(lvObject.Sorted)
  488.                 .SortKey = lvObject.SortKey
  489.                 .SortOrderDesc = Abs(lvObject.SortOrder = lvwDescending)
  490.                 .TextBkgOpaque = Abs(lvObject.TextBackground = lvwOpaque)
  491.                 .View = lvObject.View
  492.             End With
  493.             ' start writing everything
  494.             ' if an error occurs here, we abort the routine
  495.             On Error GoTo EH
  496.             With lvObject.Font       ' write the font used
  497.                 udtFont.Attributes = Abs(.Bold = True)
  498.                 udtFont.Attributes = udtFont.Attributes Or Abs(.Italic) * &H2
  499.                 udtFont.Attributes = udtFont.Attributes Or Abs(.Strikethrough) * &H4
  500.                 udtFont.Attributes = udtFont.Attributes Or Abs(.Underline) * &H8
  501.                 udtFont.CharSet = .CharSet
  502.                 udtFont.Size = .Size
  503.                 udtFont.Weight = .Weight
  504.             End With
  505.             WriteFile fileNum, udtFont, 16&, vWritten
  506.             If vWritten = 16& Then  ' write the font name
  507.                 If WriteString(fileNum, lvObject.Font.Name, False) Then
  508.                     ' save the picture property & .tag property
  509.                      If WritePicture(fileNum, lvObject.Picture) Then
  510.                         If WriteString(fileNum, lvObject.Tag, SaveStringsANSI) Then
  511.                             ' write the listview attributes
  512.                             WriteFile fileNum, udtAttr, udtFile.ListViewStructSize, vWritten
  513.                             WriteObjAttributes = (vWritten = udtFile.ListViewStructSize)
  514.                         End If
  515.                      End If
  516.                 End If
  517.             End If
  518.         Else
  519.             WriteObjAttributes = True
  520.         End If
  521.     End If
  522. EH:
  523.     If Err Then Err.Clear
  524. End Function
  525.  
  526. Private Function ReadFileHeader(fileNum As Long, udtFile As StructureFileHeader) As Boolean
  527.     ' Read the file header only
  528.     On Error GoTo EH
  529.     Dim vRead As Long
  530.     SetFilePointer fileNum, 0&, 0&, 0&
  531.     ReadFile fileNum, udtFile, 40&, vRead
  532.     If vRead = 40& Then ReadFileHeader = (udtFile.MagicNumber = 1447843404)
  533. EH:
  534.     If Err Then Err.Clear
  535. End Function
  536.  
  537. Private Function ReadObjAttributes(fileNum As Long, udtFile As StructureFileHeader) As Boolean
  538.     
  539.     ' Section is read in the following order
  540.     ' :: File Header, read in ReadFileHeader routine
  541.     ' :: Font
  542.     ' :: Picture Property
  543.     ' :: Tag property
  544.     ' :: Control Properties
  545.     
  546.     Dim udtAttr As StructureListView
  547.     Dim udtFont As StructureFont
  548.     Dim vRead As Long
  549.     Dim lvFont As StdFont, lvPic As StdPicture
  550.     
  551.     On Error GoTo EH
  552.     ReadFile fileNum, udtFont, 16&, vRead ' read the font information
  553.     If vRead = 16& Then
  554.         Set lvFont = New StdFont
  555.         With udtFont ' create the font
  556.             lvFont.Bold = (.Attributes And &H1)
  557.             lvFont.Italic = ((.Attributes \ &H2) And &H1)
  558.             lvFont.Strikethrough = ((.Attributes \ &H4) And &H1)
  559.             lvFont.Underline = (.Attributes \ &H8)
  560.             lvFont.CharSet = .CharSet
  561.             lvFont.Size = .Size
  562.             lvFont.Weight = .Weight
  563.         End With
  564.         ' read the font name & set the font
  565.         If ReadString(fileNum, False, udtFont.Name) Then
  566.             lvFont.Name = udtFont.Name
  567.             ' read the picture property data
  568.             If ReadPicture(fileNum, lvPic) Then
  569.                 ' read the .Tag property
  570.                 If ReadString(fileNum, (udtFile.Version = 1!), udtAttr.Tag) Then
  571.                     ReadFile fileNum, udtAttr, 32&, vRead ' read the v1 structure size
  572.                     If vRead = 32& Then
  573.                         On Error Resume Next
  574.                         With lvObject ' update the listview properties with what was read
  575.                             .AllowColumnReorder = udtAttr.AllowColumnReorder
  576.                             If udtAttr.AppearanceFlat Then .Appearance = ccFlat
  577.                             .Arrange = udtAttr.Arrange
  578.                             .BackColor = udtAttr.BackColor
  579.                             If udtAttr.BorderStyleNone Then .BorderStyle = ccNone
  580.                             .Checkboxes = udtAttr.Checkboxes
  581.                             .FlatScrollBar = udtAttr.FlatScrollBar
  582.                             .ForeColor = udtAttr.ForeColor
  583.                             .FullRowSelect = udtAttr.FullRowSelect
  584.                             .GridLines = udtAttr.GridLines
  585.                             .HideColumnHeaders = udtAttr.HideColumnHeaders
  586.                             .HotTracking = udtAttr.HotTracking
  587.                             .HoverSelection = udtAttr.HoverSelection
  588.                             If udtAttr.LabelEditManual Then .LabelEdit = lvwManual
  589.                             .LabelWrap = udtAttr.LabelWrap
  590.                             .MultiSelect = udtAttr.MultiSelect
  591.                             .PictureAlignment = udtAttr.PictureAlignment
  592.                             .SortKey = udtAttr.SortKey
  593.                             If udtAttr.SortOrderDesc Then .SortOrder = lvwDescending
  594.                             If udtAttr.Sorted Then udtFile.Flags = udtFile.Flags Or 1024& ' re-sort after list items loaded
  595.                             lvObject.Sorted = False
  596.                             If udtAttr.TextBkgOpaque Then .TextBackground = lvwOpaque
  597.                             .View = udtAttr.View
  598.                             .Tag = udtAttr.Tag
  599.                             Set lvObject.Font = lvFont
  600.                             Set lvObject.Picture = lvPic
  601.                             ReadObjAttributes = True
  602.                         End With
  603.                     End If
  604.                 End If
  605.             End If
  606.         End If
  607.     End If
  608. EH:
  609.     If Err Then Err.Clear
  610. End Function
  611.  
  612. Private Function WriteHeaders(fileNum As Long, StringsAsAnsi As Boolean) As Boolean
  613.  
  614.     ' Section is written in the following order
  615.     ' :: Properties
  616.     ' :: Icon reference
  617.     ' :: Tag
  618.     
  619.     Dim h As Long, vWritten As Long
  620.     Dim udtHdr As StructureHeaders
  621.     
  622.     On Error GoTo EH
  623.     For h = 1 To lvObject.ColumnHeaders.Count
  624.         With lvObject.ColumnHeaders(h)
  625.             udtHdr.Alignment = .Alignment
  626.             udtHdr.Position = .Position
  627.             udtHdr.Left = .Left
  628.             udtHdr.Width = .Width
  629.             Select Case VarType(.Icon)
  630.             Case vbInteger
  631.                 udtHdr.IconType = vbInteger
  632.             Case vbString
  633.                 If .Icon = vbNullString Then udtHdr.IconType = 0 Else udtHdr.IconType = 0
  634.             Case Else
  635.                 udtHdr.IconType = 0
  636.             End Select
  637.             If Me.IncludeHeaderTags Then
  638.                 Select Case VarType(.Tag)
  639.                 Case vbString, vbLong, vbInteger, vbByte, vbDate, vbCurrency, vbSingle, vbDouble, vbBoolean
  640.                     udtHdr.TagType = VarType(.Tag)
  641.                 Case Else
  642.                     udtHdr.TagType = 0
  643.                 End Select
  644.             End If
  645.         End With
  646.         WriteFile fileNum, udtHdr, 18&, vWritten
  647.         If vWritten <> 18& Then Exit For
  648.         Select Case udtHdr.IconType
  649.         Case 0
  650.         Case vbString
  651.             If WriteString(fileNum, CStr(lvObject.ColumnHeaders(h).Icon), StringsAsAnsi) = False Then Exit For
  652.         Case vbInteger
  653.             WriteFile fileNum, CInt(lvObject.ColumnHeaders(h).Icon), 2, vWritten
  654.             If vWritten <> 2 Then Exit For
  655.         End Select
  656.         If udtHdr.TagType Then
  657.             If WriteVariantTag(fileNum, lvObject.ColumnHeaders(h).Tag, StringsAsAnsi) = False Then Exit For
  658.         End If
  659.         If WriteString(fileNum, lvObject.ColumnHeaders(h).Text, StringsAsAnsi) = False Then Exit For
  660.         If WriteString(fileNum, lvObject.ColumnHeaders(h).Key, StringsAsAnsi) = False Then Exit For
  661.     Next
  662.     WriteHeaders = (h > lvObject.ColumnHeaders.Count)
  663. EH:
  664.     If Err Then Err.Clear
  665. End Function
  666.  
  667. Private Function ReadHeaders(fileNum As Long, udtFile As StructureFileHeader) As Boolean
  668.  
  669.     ' Section is read in the following order
  670.     ' :: Properties
  671.     ' :: Icon reference
  672.     ' :: Tag
  673.     
  674.     Dim h As Long, vRead As Long, tSize As Long
  675.     Dim sIcon As String, iIcon As Integer
  676.     Dim bApplyTags As Boolean, hasTags As Boolean
  677.     Dim bApplyIcon As Boolean, StringsAsAnsi As Boolean
  678.     
  679.     Dim udtHdr() As StructureHeaders
  680.     
  681.     On Error Resume Next
  682.     ReDim udtHdr(1 To udtFile.Columns)
  683.     
  684.     If (udtFile.Flags And fgHasHeaderTags) Then
  685.         hasTags = True
  686.         If Me.IncludeHeaderTags = True Then bApplyTags = True
  687.     End If
  688.     If (udtFile.Version = 1!) Then StringsAsAnsi = True
  689.     If Not lvObject.ColumnHeaderIcons Is Nothing Then bApplyIcon = True
  690.     
  691.     For h = 1 To udtFile.Columns
  692.         ReadFile fileNum, udtHdr(h), 18&, vRead
  693.         If vRead <> 18 Then Exit For
  694.         Select Case udtHdr(h).IconType
  695.         Case vbString
  696.             If ReadString(fileNum, StringsAsAnsi, sIcon) = False Then Exit For
  697.             udtHdr(h).Icon = sIcon
  698.         Case vbInteger
  699.             ReadFile fileNum, iIcon, 2&, vRead
  700.             If vRead <> 2 Then Exit For
  701.             udtHdr(h).Icon = iIcon
  702.         Case Else
  703.             udtHdr(h).Icon = 0
  704.         End Select
  705.         If hasTags Then
  706.             If ReadVariantTag(fileNum, udtHdr(h).TagType, StringsAsAnsi, udtHdr(h).Tag) = False Then Exit For
  707.         End If
  708.         If ReadString(fileNum, StringsAsAnsi, udtHdr(h).Text) = False Then Exit For
  709.         If ReadString(fileNum, StringsAsAnsi, udtHdr(h).Key) = False Then Exit For
  710.     Next
  711.     If h > udtFile.Columns Then
  712.         lvObject.ColumnHeaders.Clear
  713.         For h = 1 To udtFile.Columns
  714.             lvObject.ColumnHeaders.Add , udtHdr(h).Key, udtHdr(h).Text, udtHdr(h).Width, udtHdr(h).Alignment
  715.             If (Not udtHdr(h).Icon = 0) And bApplyIcon = True Then lvObject.ColumnHeaders(h).Icon = udtHdr(h).Icon
  716.             If bApplyTags Then lvObject.ColumnHeaders(h).Tag = udtHdr(h).Tag
  717.         Next
  718.         For h = 1 To udtFile.Columns
  719.             If udtHdr(h).Position <> h Then lvObject.ColumnHeaders(h).Position = udtHdr(h).Position
  720.         Next
  721.         ReadHeaders = True
  722.     End If
  723.     
  724. End Function
  725.  
  726. Private Function ReadImageLists(fileNum As Long, udtFile As StructureFileHeader) As Boolean
  727.     
  728.     ' Section is read in the following order
  729.     ' :: Properties
  730.     ' :: Image Count
  731.     ' :: Image Data per image
  732.     ' :: Tag per image
  733.     ' :: Key per image
  734.     
  735.     Dim vTag As Variant, vRead As Long
  736.     Dim lValue As Long, sKey As String
  737.     Dim i As Long, L As Long, ansiStrings As Boolean
  738.     
  739.     Dim udtIL As StructureImageList
  740.     Dim theList As MSComctlLib.ImageList
  741.     Dim tPic As StdPicture, cImage As MSComctlLib.ListImage
  742.     
  743.     Set lvObject.ColumnHeaderIcons = Nothing
  744.     Set lvObject.Icons = Nothing
  745.     Set lvObject.SmallIcons = Nothing
  746.     
  747.     If udtFile.Version = 1! Then ansiStrings = True
  748.     
  749.     For L = 1 To 3
  750.         On Error GoTo EH
  751.         ReadFile fileNum, lValue, 4&, vRead
  752.         If vRead <> 4& Then Exit For
  753.         
  754.         If lValue > 17& Then
  755.             On Error Resume Next
  756.             RaiseEvent SetImageList(L, theList)
  757.             If theList Is Nothing Then
  758.                 ReadImageLists = True   ' user is not supplying an imagelist, abort
  759.                 Exit Function           ' but continue importing
  760.             Else
  761.                 theList.ListImages.Clear
  762.                 If Err Then     ' we can't clear an imagelist if it is assigned to another control
  763.                     Err.Clear   ' therefore, we will allow importing to continue, but without imagelists
  764.                     ReadImageLists = True
  765.                     Exit Function
  766.                 End If
  767.             End If
  768.             On Error GoTo EH
  769.         ElseIf lValue Then
  770.             If L = ilLargeIcons Then  ' listimage is same as ColumnHeaders
  771.                 Set lvObject.Icons = lvObject.ColumnHeaderIcons
  772.             ElseIf lValue = ilColumnHeaders Then ' listimage is same as ColumnHeaders
  773.                 Set lvObject.SmallIcons = lvObject.ColumnHeaderIcons
  774.             Else ' listimage is same as large icons
  775.                 Set lvObject.SmallIcons = lvObject.Icons
  776.             End If
  777.             lValue = 0& ' we won't be importing any images
  778.         End If
  779.         
  780.         If lValue Then
  781.             lValue = 18&
  782.             ReadFile fileNum, udtIL, lValue, vRead
  783.             If vRead <> lValue Then Exit For
  784.             With theList
  785.                 .BackColor = udtIL.BackColor
  786.                 .ImageHeight = udtIL.ImageHeight
  787.                 .ImageWidth = udtIL.ImageWidth
  788.                 .MaskColor = udtIL.MaskColor
  789.                 .UseMaskColor = udtIL.UseMaskColor
  790.             End With
  791.             If ReadString(fileNum, ansiStrings, sKey) Then theList.Tag = sKey
  792.             
  793.             For i = 1 To udtIL.Count
  794.                 If ReadPicture(fileNum, tPic) = False Then Exit For
  795.                 ReadFile fileNum, lValue, 4&, vRead
  796.                 If vRead <> 4& Then Exit For
  797.                 If ReadVariantTag(fileNum, lValue, ansiStrings, vTag) = False Then Exit For
  798.                 If ReadString(fileNum, ansiStrings, sKey) = False Then Exit For
  799.                 Set cImage = theList.ListImages.Add(, sKey, tPic)
  800.                 cImage.Tag = vTag
  801.             Next
  802.             If i <= udtIL.Count Then Exit For
  803.             Select Case L
  804.             Case 1: Set lvObject.ColumnHeaderIcons = theList
  805.             Case 2: Set lvObject.Icons = theList
  806.             Case 3: Set lvObject.SmallIcons = theList
  807.             End Select
  808.         End If
  809.     Next
  810.     ReadImageLists = (L = 4)
  811. EH:
  812.     If Err Then Err.Clear
  813. End Function
  814.  
  815. Private Function WriteImageLists(fileNum As Long, ansiStrings As Boolean) As Boolean
  816.  
  817.     ' Section is written in the following order
  818.     ' :: Properties
  819.     ' :: Image Count
  820.     ' :: Image Data per image
  821.     ' :: Tag per image
  822.     ' :: Key per image
  823.     
  824.     Dim i As Long, vWritten As Long, L As Long
  825.     Dim theList As MSComctlLib.ImageList
  826.     Dim tPic As StdPicture, TagType As VbVarType
  827.     Dim udtIL As StructureImageList
  828.     
  829.     On Error GoTo EH
  830.     For L = 1 To 3
  831.         Select Case L
  832.         Case 1: Set theList = lvObject.ColumnHeaderIcons
  833.             If theList Is Nothing Then
  834.                 WriteFile fileNum, 0&, 4&, vWritten
  835.                 If vWritten <> 4& Then Exit For
  836.             End If
  837.         Case 2: Set theList = lvObject.Icons
  838.             If theList Is Nothing Then
  839.                 WriteFile fileNum, 0&, 4&, vWritten
  840.                 If vWritten <> 4& Then Exit For
  841.             Else
  842.                 If theList Is lvObject.ColumnHeaderIcons Then
  843.                     Set theList = Nothing ' uses same list as ColumnHeaderIcons
  844.                     WriteFile fileNum, 1&, 4&, vWritten
  845.                     If vWritten <> 4& Then Exit For
  846.                 End If
  847.             End If
  848.         Case 3: Set theList = lvObject.SmallIcons
  849.             If theList Is Nothing Then
  850.                 WriteFile fileNum, 0&, 4&, vWritten
  851.                 If vWritten <> 4& Then Exit For
  852.             ElseIf theList Is lvObject.ColumnHeaderIcons Then
  853.                 Set theList = Nothing ' uses same list as ColumnHeaderIcons
  854.                 WriteFile fileNum, 1&, 4&, vWritten
  855.                 If vWritten <> 4& Then Exit For
  856.             ElseIf theList Is lvObject.Icons Then
  857.                 Set theList = Nothing ' uses same list as Icons
  858.                 WriteFile fileNum, 2&, 4&, vWritten
  859.                 If vWritten <> 4& Then Exit For
  860.             End If
  861.         End Select
  862.     
  863.         If Not theList Is Nothing Then
  864.             With udtIL
  865.                 .BackColor = theList.BackColor
  866.                 .Count = theList.ListImages.Count
  867.                 .ImageHeight = theList.ImageHeight
  868.                 .ImageWidth = theList.ImageWidth
  869.                 .MaskColor = theList.MaskColor
  870.                 .UseMaskColor = theList.UseMaskColor
  871.             End With
  872.             WriteFile fileNum, 18&, 4&, vWritten
  873.             If vWritten <> 4& Then Exit For
  874.             WriteFile fileNum, udtIL, 18&, vWritten
  875.             If vWritten <> 18& Then Exit For
  876.             If WriteString(fileNum, theList.Tag, ansiStrings) = False Then Exit For
  877.             For i = 1 To udtIL.Count
  878.                 
  879.                 Set tPic = theList.ListImages(i).Picture
  880.                 If WritePicture(fileNum, tPic) = False Then Exit For
  881.                 
  882.                 WriteFile fileNum, CLng(VarType(theList.ListImages(i).Tag)), 4&, vWritten
  883.                 If vWritten <> 4& Then Exit For
  884.                 If WriteVariantTag(fileNum, theList.ListImages(i).Tag, ansiStrings) = False Then Exit For
  885.                 If WriteString(fileNum, theList.ListImages(i).Key, ansiStrings) = False Then Exit For
  886.             Next
  887.             If i <= theList.ListImages.Count Then Exit For
  888.         End If
  889.     Next
  890.     WriteImageLists = (L = 4)
  891. EH:
  892.     If Err Then Err.Clear
  893. End Function
  894.  
  895. Private Function WriteListItems(fileNum As Long, ansiStrings As Boolean) As Boolean
  896.  
  897.     ' Section is written in the following order
  898.     ' :: Properties
  899.     ' :: ListSubItems Count
  900.     ' :: Icon reference type & reference
  901.     ' :: Text
  902.     ' :: Key
  903.     ' :: ToolTipText
  904.     ' -- for each sub item
  905.     ' :: Properties
  906.     ' :: Text
  907.     ' :: Key
  908.     ' :: ToolTipText
  909.     ' :: ReportIcon reference type & reference (ListSubItems property)
  910.  
  911.     Dim udtLI As StructureListItem
  912.     Dim udtLIsub As StructureListSubItem
  913.     Dim vWritten As Long
  914.     Dim L As Long, S As Long
  915.     
  916.     For L = 1 To lvObject.ListItems.Count
  917.         With lvObject.ListItems(L)
  918.             If Me.IncludeTextFormatting Then
  919.                 udtLI.BoldChecked = Abs(.Bold) Or Abs(.Checked) * 2&
  920.                 udtLI.ForeColor = .ForeColor
  921.             Else
  922.                 udtLI.BoldChecked = Abs(Checked) * 2&
  923.             End If
  924.             Select Case VarType(.Icon)
  925.             Case vbString
  926.                 If .Icon = vbNullString Then udtLI.IconTypes = 0 Else udtLI.IconTypes = vbString
  927.             Case vbInteger
  928.                 udtLI.IconTypes = vbInteger
  929.             Case Else
  930.                 udtLI.IconTypes = 0&
  931.             End Select
  932.             Select Case VarType(.SmallIcon)
  933.             Case vbString
  934.                 If Not .SmallIcon = vbNullString Then
  935.                     udtLI.IconTypes = udtLI.IconTypes Or (vbString * &H10000)
  936.                 End If
  937.             Case vbInteger
  938.                 udtLI.IconTypes = udtLI.IconTypes Or (vbInteger * &H10000)
  939.             End Select
  940.             If Me.IncludeListItemTags Then
  941.                 Select Case VarType(.Tag)
  942.                 Case vbString, vbLong, vbInteger, vbByte, vbDate, vbCurrency, vbSingle, vbDouble, vbBoolean
  943.                     udtLI.TagType = VarType(.Tag)
  944.                 Case Else
  945.                     udtLI.TagType = 0
  946.                 End Select
  947.             End If
  948.             udtLI.SubCount = .ListSubItems.Count
  949.             WriteFile fileNum, udtLI, 16&, vWritten
  950.             If vWritten <> 16& Then Exit For
  951.             If WriteString(fileNum, .Text, ansiStrings) = False Then Exit For
  952.             If WriteString(fileNum, .Key, ansiStrings) = False Then Exit For
  953.             If WriteString(fileNum, .ToolTipText, ansiStrings) = False Then Exit For
  954.             Select Case (udtLI.IconTypes And &HFFFF&)
  955.             Case 0
  956.             Case vbString
  957.                 If WriteString(fileNum, CStr(.Icon), ansiStrings) = False Then Exit For
  958.             Case vbInteger
  959.                 WriteFile fileNum, CInt(.Icon), 2, vWritten
  960.                 If vWritten <> 2 Then Exit For
  961.             End Select
  962.             Select Case (udtLI.IconTypes \ &H10000)
  963.             Case 0
  964.             Case vbString
  965.                 If WriteString(fileNum, CStr(.SmallIcon), ansiStrings) = False Then Exit For
  966.             Case vbInteger
  967.                 WriteFile fileNum, CInt(.SmallIcon), 2, vWritten
  968.                 If vWritten <> 2 Then Exit For
  969.             End Select
  970.             If Me.IncludeListItemTags Then
  971.                 If WriteVariantTag(fileNum, .Tag, ansiStrings) = False Then Exit For
  972.             End If
  973.         End With
  974.         For S = 1 To udtLI.SubCount
  975.             With lvObject.ListItems(L).ListSubItems(S)
  976.                 udtLIsub.Bold = Abs(.Bold)
  977.                 udtLIsub.ForeColor = .ForeColor
  978.                 Select Case VarType(.ReportIcon)
  979.                 Case vbString, vbInteger
  980.                     udtLIsub.IconType = VarType(.ReportIcon)
  981.                 Case Else
  982.                     udtLIsub.IconType = 0&
  983.                 End Select
  984.                 If Me.IncludeListItemTags Then
  985.                     Select Case VarType(.Tag)
  986.                     Case vbString, vbLong, vbInteger, vbByte, vbDate, vbCurrency, vbSingle, vbDouble, vbBoolean
  987.                         udtLIsub.TagType = VarType(.Tag)
  988.                     Case Else
  989.                         udtLIsub.TagType = 0
  990.                     End Select
  991.                 End If
  992.                 WriteFile fileNum, udtLIsub, 9&, vWritten
  993.                 If vWritten <> 9& Then Exit For
  994.                 If WriteString(fileNum, .Text, ansiStrings) = False Then Exit For
  995.                 If WriteString(fileNum, .Key, ansiStrings) = False Then Exit For
  996.                 If WriteString(fileNum, .ToolTipText, ansiStrings) = False Then Exit For
  997.                 Select Case udtLIsub.IconType
  998.                 Case 0
  999.                 Case vbString
  1000.                     If WriteString(fileNum, CStr(.ReportIcon), ansiStrings) = False Then Exit For
  1001.                 Case vbInteger
  1002.                     WriteFile fileNum, CInt(.ReportIcon), 2, vWritten
  1003.                     If vWritten <> 2 Then Exit For
  1004.                 End Select
  1005.                 If Me.IncludeListItemTags Then
  1006.                     If WriteVariantTag(fileNum, .Tag, ansiStrings) = False Then Exit For
  1007.                 End If
  1008.             End With
  1009.         Next
  1010.         If S <= udtLI.SubCount Then Exit For
  1011.     Next
  1012.     WriteListItems = (L > lvObject.ListItems.Count)
  1013.  
  1014. End Function
  1015.  
  1016. Private Function ReadListItems(fileNum As Long, udtFile As StructureFileHeader) As Boolean
  1017.  
  1018.     ' Section is read in the following order
  1019.     ' :: Properties
  1020.     ' :: ListSubItems Count
  1021.     ' :: Icon reference type & reference
  1022.     ' :: Text
  1023.     ' :: Key
  1024.     ' :: ToolTipText
  1025.     ' -- for each sub item
  1026.     ' :: Properties
  1027.     ' :: Text
  1028.     ' :: Key
  1029.     ' :: ToolTipText
  1030.     ' :: ReportIcon reference type & reference (ListSubItems property)
  1031.     
  1032.     Dim udtLI As StructureListItem
  1033.     Dim udtLIsub As StructureListSubItem
  1034.     Dim vRead As Long, sValue As String
  1035.     Dim L As Long, S As Long, iValue As Integer
  1036.     Dim bApplyTag As Boolean, hasTags As Boolean
  1037.     Dim bApplyIconLG As Boolean, bApplyIconSM As Boolean
  1038.     Dim bApplyFormat As Boolean, ansiStrings As Boolean
  1039.     Dim xItm As MSComctlLib.ListItem
  1040.     Dim xSub As MSComctlLib.ListSubItem
  1041.     
  1042.     On Error Resume Next
  1043.     ' Why resume next?  Icon references, when they exist...
  1044.     ' When icon references exist, here are some errors that are expected
  1045.     ' 1. You did not provide an imagelist control when prompted: error will be no imagelist is initialized
  1046.     ' 2. You did not provide an imagelist but set one to the listview before this is called: error is index/key does not exist
  1047.     ' 3. The imagelist was saved but you opted not to import it: error can be one of the two above
  1048.     
  1049.     If (udtFile.Flags And fgHasItemTags) Then
  1050.         hasTags = True
  1051.         If Me.IncludeListItemTags = True Then bApplyTag = True
  1052.     End If
  1053.     If (udtFile.Flags And fgHasTextFormat) Then
  1054.         If Me.IncludeTextFormatting Then bApplyFormat = True
  1055.     End If
  1056.     If udtFile.Version = 1! Then ansiStrings = True
  1057.     If Not lvObject.Icons Is Nothing Then bApplyIconLG = True
  1058.     If Not lvObject.SmallIcons Is Nothing Then bApplyIconSM = True
  1059.     
  1060.     For L = 1 To udtFile.Items
  1061.         ReadFile fileNum, udtLI, 16&, vRead
  1062.         If vRead <> 16& Then Exit For
  1063.         If ReadString(fileNum, ansiStrings, udtLI.Text) = False Then Exit For
  1064.         If ReadString(fileNum, ansiStrings, udtLI.Key) = False Then Exit For
  1065.         If ReadString(fileNum, ansiStrings, udtLI.Tooltip) = False Then Exit For
  1066.         Select Case (udtLI.IconTypes And &HFFFF&)
  1067.         Case 0
  1068.         Case vbString
  1069.             If ReadString(fileNum, ansiStrings, sValue) = False Then Exit For
  1070.             udtLI.IconLg = sValue
  1071.         Case vbInteger
  1072.             ReadFile fileNum, iValue, 2&, vRead
  1073.             If vRead <> 2& Then Exit For
  1074.             udtLI.IconLg = iValue
  1075.         End Select
  1076.         Select Case (udtLI.IconTypes \ &H10000)
  1077.         Case 0
  1078.         Case vbString
  1079.             If ReadString(fileNum, ansiStrings, sValue) = False Then Exit For
  1080.             udtLI.IconSm = sValue
  1081.         Case vbInteger
  1082.             ReadFile fileNum, iValue, 2&, vRead
  1083.             If vRead <> 2& Then Exit For
  1084.             udtLI.IconSm = iValue
  1085.         End Select
  1086.         If hasTags Then
  1087.             If ReadVariantTag(fileNum, udtLI.TagType, ansiStrings, udtLI.Tag) = False Then Exit For
  1088.         End If
  1089.         Set xItm = lvObject.ListItems.Add(, udtLI.Key, udtLI.Text)
  1090.         If (udtLI.IconTypes And &HFFFF&) Then
  1091.             If bApplyIconLG Then xItm.Icon = udtLI.IconLg
  1092.         End If
  1093.         If (udtLI.IconTypes \ &H10000) Then
  1094.             If bApplyIconSM Then xItm.SmallIcon = udtLI.IconSm
  1095.         End If
  1096.         xItm.Checked = CBool(udtLI.BoldChecked \ 2)
  1097.         xItm.ToolTipText = udtLI.Tooltip
  1098.         If bApplyFormat Then
  1099.             xItm.Bold = CBool(udtLI.BoldChecked And 1)
  1100.             xItm.ForeColor = udtLI.ForeColor
  1101.         End If
  1102.         If bApplyTag Then xItm.Tag = udtLI.Tag
  1103.         
  1104.         For S = 1 To udtLI.SubCount
  1105.             ReadFile fileNum, udtLIsub, 9&, vRead
  1106.             If vRead <> 9& Then Exit For
  1107.             If ReadString(fileNum, ansiStrings, udtLIsub.Text) = False Then Exit For
  1108.             If ReadString(fileNum, ansiStrings, udtLIsub.Key) = False Then Exit For
  1109.             If ReadString(fileNum, ansiStrings, udtLIsub.Tooltip) = False Then Exit For
  1110.             Select Case udtLIsub.IconType
  1111.             Case 0
  1112.             Case vbString
  1113.                 If ReadString(fileNum, ansiStrings, sValue) = False Then Exit For
  1114.                 udtLIsub.ReportIcon = sValue
  1115.             Case vbInteger
  1116.                 ReadFile fileNum, iValue, 2&, vRead
  1117.                 If vRead <> 2& Then Exit For
  1118.                 udtLIsub.ReportIcon = iValue
  1119.             End Select
  1120.             If hasTags Then
  1121.                 If ReadVariantTag(fileNum, udtLIsub.TagType, ansiStrings, udtLIsub.Tag) = False Then Exit For
  1122.             End If
  1123.             Set xSub = xItm.ListSubItems.Add(, udtLIsub.Key, udtLIsub.Text, , udtLIsub.Tooltip)
  1124.             If (Not udtLIsub.IconType = 0) Then xSub.ReportIcon = udtLIsub.ReportIcon
  1125.             If bApplyTag Then xSub.Tag = udtLIsub.Tag
  1126.             If bApplyFormat Then
  1127.                 xSub.Bold = CBool(udtLIsub.Bold)
  1128.                 xSub.ForeColor = udtLIsub.ForeColor
  1129.             End If
  1130.         Next
  1131.         If S <= udtLI.SubCount Then Exit For
  1132.     Next
  1133.     ReadListItems = (L > udtFile.Items)
  1134.     
  1135. End Function
  1136.  
  1137. Private Function ReadVariantTag(fileNum As Long, ByVal varTypo As VbVarType, StringsAsAnsi As Boolean, varReturn As Variant) As Boolean
  1138.  
  1139.     ' Converts file bytes to proper variable type
  1140.     ' Many ListView class Tags are Variant vs String
  1141.  
  1142.     Dim sTag As String, byTag As Byte, iTag As Integer
  1143.     Dim blTag As Boolean, lTag As Long, snTag As Single
  1144.     Dim dtTag As Date, dbTag As Double, crTag As Currency
  1145.     Dim tSize As Long, vRead As Long
  1146.         
  1147.     Select Case varTypo
  1148.     Case vbString
  1149.         If ReadString(fileNum, StringsAsAnsi, sTag) Then
  1150.             varReturn = sTag
  1151.             vRead = tSize
  1152.         Else
  1153.             vRead = tSize - 1&
  1154.         End If
  1155.     Case vbByte
  1156.         tSize = 1&
  1157.         ReadFile fileNum, byTag, tSize, vRead
  1158.         varReturn = byTag
  1159.     Case vbInteger
  1160.         tSize = 2&
  1161.         ReadFile fileNum, iTag, tSize, vRead
  1162.         varReturn = iTag
  1163.     Case vbBoolean
  1164.         tSize = 2&
  1165.         ReadFile fileNum, blTag, tSize, vRead
  1166.         varReturn = blTag
  1167.     Case vbLong
  1168.         tSize = 4&
  1169.         ReadFile fileNum, lTag, tSize, vRead
  1170.         varReturn = lTag
  1171.     Case vbSingle
  1172.         tSize = 4&
  1173.         ReadFile fileNum, snTag, tSize, vRead
  1174.         varReturn = snTag
  1175.     Case vbDate
  1176.         tSize = 8&
  1177.         ReadFile fileNum, dtTag, tSize, vRead
  1178.         varReturn = dtTag
  1179.     Case vbDouble
  1180.         tSize = 8&
  1181.         ReadFile fileNum, dbTag, tSize, vRead
  1182.         varReturn = dbTag
  1183.     Case vbCurrency
  1184.         tSize = 8&
  1185.         ReadFile fileNum, crTag, tSize, vRead
  1186.         varReturn = crTag
  1187.     Case Else
  1188.         vRead = tSize
  1189.         varReturn = vbNullString
  1190.     End Select
  1191.     If vRead = tSize Then
  1192.         varReturn = varReturn
  1193.         ReadVariantTag = True
  1194.     End If
  1195.     
  1196. End Function
  1197.  
  1198. Private Function WriteVariantTag(fileNum As Long, vTag As Variant, ansiStrings As Boolean) As Boolean
  1199.  
  1200.     ' Converts variable type to bytes for file writing
  1201.     ' Many ListView class Tags are Variant vs String
  1202.  
  1203.     Dim vWritten As Long
  1204.     Select Case VarType(vTag)
  1205.     Case vbString
  1206.         WriteVariantTag = WriteString(fileNum, CStr(vTag), ansiStrings)
  1207.     Case vbByte
  1208.         WriteFile fileNum, CByte(vTag), 1&, vWritten
  1209.         WriteVariantTag = (vWritten = 1&)
  1210.     Case vbInteger
  1211.         WriteFile fileNum, CInt(vTag), 2&, vWritten
  1212.         WriteVariantTag = (vWritten = 2&)
  1213.     Case vbBoolean
  1214.         WriteFile fileNum, CBool(vTag), 2&, vWritten
  1215.         WriteVariantTag = (vWritten = 2&)
  1216.     Case vbLong
  1217.         WriteFile fileNum, CLng(vTag), 4&, vWritten
  1218.         WriteVariantTag = (vWritten = 4&)
  1219.     Case vbSingle
  1220.         WriteFile fileNum, CSng(vTag), 4&, vWritten
  1221.         WriteVariantTag = (vWritten = 4&)
  1222.     Case vbDouble
  1223.         WriteFile fileNum, CDbl(vTag), 8&, vWritten
  1224.         WriteVariantTag = (vWritten = 8&)
  1225.     Case vbDate
  1226.         WriteFile fileNum, CDate(vTag), 8&, vWritten
  1227.         WriteVariantTag = (vWritten = 8&)
  1228.     Case vbCurrency
  1229.         WriteFile fileNum, CCur(vTag), 8&, vWritten
  1230.         WriteVariantTag = (vWritten = 8&)
  1231.     Case Else
  1232.         WriteVariantTag = True
  1233.     End Select
  1234.  
  1235. End Function
  1236.  
  1237. Private Function GetFileHandle(FileName As String, bOpen As Boolean, useUnicode As Boolean) As Long
  1238.  
  1239.     ' Function uses APIs to read/create files with unicode support
  1240.  
  1241.     Const GENERIC_READ As Long = &H80000000
  1242.     Const OPEN_EXISTING = &H3
  1243.     Const FILE_SHARE_READ = &H1
  1244.     Const GENERIC_WRITE As Long = &H40000000
  1245.     Const FILE_SHARE_WRITE As Long = &H2
  1246.     Const CREATE_ALWAYS As Long = 2
  1247.     Const FILE_ATTRIBUTE_ARCHIVE As Long = &H20
  1248.     Const FILE_ATTRIBUTE_HIDDEN As Long = &H2
  1249.     Const FILE_ATTRIBUTE_READONLY As Long = &H1
  1250.     Const FILE_ATTRIBUTE_SYSTEM As Long = &H4
  1251.     
  1252.     Dim Flags As Long, Access As Long, bUnicode As Boolean
  1253.     Dim Disposition As Long, Share As Long
  1254.     
  1255.     If bOpen Then
  1256.         Access = GENERIC_READ
  1257.         Share = FILE_SHARE_READ
  1258.         Disposition = OPEN_EXISTING
  1259.         Flags = FILE_ATTRIBUTE_ARCHIVE Or FILE_ATTRIBUTE_HIDDEN Or FILE_ATTRIBUTE_NORMAL _
  1260.                 Or FILE_ATTRIBUTE_READONLY Or FILE_ATTRIBUTE_SYSTEM
  1261.     Else
  1262.         Access = GENERIC_READ Or GENERIC_WRITE
  1263.         Share = 0&
  1264.         If useUnicode Then
  1265.             Flags = GetFileAttributesW(StrPtr(FileName))
  1266.         Else
  1267.             Flags = GetFileAttributes(FileName)
  1268.         End If
  1269.         If Flags < 0& Then Flags = FILE_ATTRIBUTE_NORMAL
  1270.         ' CREATE_ALWAYS will delete previous file if necessary
  1271.         Disposition = CREATE_ALWAYS
  1272.     End If
  1273.     
  1274.     If useUnicode Then
  1275.         GetFileHandle = CreateFileW(StrPtr(FileName), Access, Share, ByVal 0&, Disposition, Flags, 0&)
  1276.     Else
  1277.         GetFileHandle = CreateFile(FileName, Access, Share, ByVal 0&, Disposition, Flags, 0&)
  1278.     End If
  1279.  
  1280. End Function
  1281.  
  1282. Private Function FileExists(FileName As String, useUnicode As Boolean) As Boolean
  1283.     ' test to see if a file exists
  1284.     Const INVALID_HANDLE_VALUE = -1&
  1285.     If useUnicode Then
  1286.         FileExists = Not (GetFileAttributesW(StrPtr(FileName)) = INVALID_HANDLE_VALUE)
  1287.     Else
  1288.         FileExists = Not (GetFileAttributes(FileName) = INVALID_HANDLE_VALUE)
  1289.     End If
  1290. End Function
  1291.  
  1292.  
  1293. Private Function WriteString(fileNum As Long, theString As String, asAnsi As Boolean) As Boolean
  1294.     
  1295.     ' Writes a string to file in either ANSI or Unicode
  1296.     Dim sData() As Byte, lLen As Long, vWritten As Long
  1297.     
  1298.     lLen = Len(theString)
  1299.     WriteFile fileNum, lLen, 4&, vWritten
  1300.     If lLen Then
  1301.         If asAnsi Then
  1302.             sData() = StrConv(theString, vbFromUnicode)
  1303.             WriteFile fileNum, sData(0), lLen, vWritten
  1304.         Else
  1305.             lLen = lLen + lLen
  1306.             WriteFile fileNum, ByVal StrPtr(theString), lLen, vWritten
  1307.         End If
  1308.         WriteString = (vWritten = lLen)
  1309.     Else
  1310.         WriteString = True
  1311.     End If
  1312.  
  1313. End Function
  1314.  
  1315. Private Function ReadString(fileNum As Long, asAnsi As Boolean, toString As String) As Boolean
  1316.  
  1317.     ' Reads either ANSI or Unicode string from file
  1318.     
  1319.     Dim lLen As Long, vRead As Long, sData() As Byte
  1320.  
  1321.     ReadFile fileNum, lLen, 4&, vRead
  1322.     If vRead = 4& Then
  1323.         If lLen Then
  1324.             If asAnsi Then  ' ANSI version
  1325.                 ReDim sData(0 To lLen - 1)
  1326.                 ReadFile fileNum, sData(0), lLen, vRead
  1327.                 If vRead = lLen Then
  1328.                     toString = StrConv(sData(), vbUnicode)
  1329.                     ReadString = True
  1330.                 End If
  1331.             Else
  1332.                 toString = String$(lLen, vbNullChar)
  1333.                 lLen = lLen + lLen
  1334.                 ReadFile fileNum, ByVal StrPtr(toString), lLen, vRead
  1335.                 If vRead = lLen Then ReadString = True
  1336.             End If
  1337.         Else
  1338.             toString = vbNullString
  1339.             ReadString = True
  1340.         End If
  1341.     End If
  1342.  
  1343. End Function
  1344.  
  1345. Private Function WritePicture(fileNum As Long, thePicture As StdPicture) As Boolean
  1346.  
  1347.     ' Writes a picture property to file, preceding it with byte length
  1348.     
  1349.     Dim o_hMem As Long, o_lpMem As Long
  1350.     Dim o_lngByteCount As Long
  1351.     Dim vWritten As Long, bSuccess As Integer
  1352.     
  1353.     ' In order to use the OLESaveToStream function, we need the pointer to the IPersistStream interface
  1354.     ' This portion will return that pointer if the interface is implemented
  1355.     
  1356.     Dim varRtn As Variant, pIPS As Long
  1357.     Dim aGUID(0 To 3) As Long, IFauxStream As IUnknown
  1358.     Dim pvTypes(0 To 1) As Integer, pvPtrs(0 To 1) As Long, pValues(0 To 1) As Variant
  1359.     
  1360.     Const IUnknownQueryInterface As Long = 0&   ' IUnknown vTable offset to Query implemented interfaces
  1361.     Const IUnknownRelease As Long = 8&          ' IUnkownn vTable offset to decrement reference count
  1362.     Const CC_STDCALL As Long = 4&
  1363.     
  1364.     aGUID(0) = &H109            ' GUID for IPersistStream (00000109-0000-0000-C000-000000000046)
  1365.     aGUID(2) = &HC0
  1366.     aGUID(3) = &H46000000
  1367.     
  1368.     If Not thePicture Is Nothing Then
  1369.         If thePicture.Handle Then
  1370.     
  1371.             On Error GoTo CATCH_EXCEPTION
  1372.             g, IFauxSpvPtrverts variable typ he inteAs Long = 8&x)uted in Lo (000Pn ryInterL_EXCEPTION
  1373.           nkn he inteAs Long ew beO (000Pn rLror GVong tream , IFauxSpvPtrveIng, IFauxSpvPtrverts variable typ he inIng, n1nteAs r(theStrihe inI)riteF
  1374.     
  1375. 00Pnp-g, n1nteAs r(theeeeeeeeeeeeeeeee(000PPn otg ewng, Im ,anp-g, n1nteAs r(theeeeeeeeeeeeeeeee(000PPn otRNSI or Unicode sct Case VarType(.Tag)SGinteAs Lerence (sct C10PPn of Notng ew     eee(000PPn otg ewng, Im ,anp-g, n1nteAs r(theeeeeeeeeeeeeeeee(000PPn otRNSI or Unicode sct Case VarType(-otg e sct Case VarType(-otg e sct nW(StrPtadFile fileNum,_heeeeeeeeeeeeeeeee(000PPn otRNSI or Unicode scte(-otg e sd Fu          otRNSI or Unicode scte(-ote
  1376.  
  1377.     Rea n1nteAs r(theeeeeeicodeI or Unicode scte(-ote
  1378.  
  1379.     Rea n1nteAs r(theeeeeeicodeI or Unicode scte(-ote
  1380.  
  1381.     Rea n1nteAs r(theeeeeeicodeI or Unicode scte(-ote
  1382. oo,Lrence (sct C10PPnISTING = &      otRNSI or UnicoUnicoUnicoUnicoUnicoUnicoUnicoUd iS, vWricoUnicoUnicoUnicoUnren at As Booleanleanleanleanleanleatnicode scte(-otg e sd Fu          otRNSI eadFile fileNum, ByVal StrrType(-otg e sct=    Dim sDazcnleanltTTRIBUFauxSpvPtrverts vaT,sd Fu          otRNSI eanicoUnren at As igU= de vWric/p& refm sDat eadFile fileNum, ByVric/p& refm sDat eadFt Fu   Trver6e Function ReadImagev TAion = CREATE_ALWAYS prompted: 4ReadImagev Longee(-ote2, Longee(-gee(-o(theten AsaIf lLen Theneten AsaIf lLen Theneten A= CREATE_ALWAYS prompted: 4ReadImagev LongeeWAYS pren at As Booleanleanleanleanleanleatnicode scte(-otg e sd Fu          otRNSI eadFile fileNum, ByVal StyVric/p& refm ansiStrings As n at As Booleanleat AWnt, pIPS As Long
  1383.     Dim aGUID(0 To 3) As Long, IFa' This pope0 To 3Wnt, pPS As Long
  1384.     D(-ote.theeeeeeicodeI or Unicode scte(-gT    
  1385.     If Not thengnicoUniicoUnicoUnicoUnicoUnicoUnicoUnicoUd iS,ecod istSEnd If
  1386.         If Flags < 0& Theny imeteIfUnico VFile fil rnd Ifinf Flany (End If
  1387. cNI(  If Not ttttt byeger de vUd iSTag
  1388. Retute.BdFir de vUd iSTaB        Case vbInteger
  1389.               IFat As Long
  1390.     Dim vWrit    CoV, p  
  1391. e scte Thenoe The de vUdoV, ng, Im ,anp-g, n1nteAWrit    CoV, pe vUdoV, ng, Im ,anp ,iicoUnicoUnicccccccccc Rea n1nteAs r(thWrit    CoV, p  
  1392. e scte Thenoe The de vUdosposition, Flags, 0&)
  1393.     As n at As  sctI r(thWrit    CoV (000Pn ryInterL_EXCEslee poag)tr Flags, 0&)
  1394.     As n at As  sctI r(thWrit   Pcte &)
  1395.     As n at A LoPit YS  = l   r(toStRea n1ntf
  1396.   vWrit   Pcte &)
  1397.     As n at A LoPlPn otRNSI or UnicoiR   ConsV, ng, Im ,anp-g, n1nteAWrit    CoV, pe OSnp-g, n1nteAWrL As Long = 4&
  1398. Colose vbLtt   ConsVooooooleatn Cas    vaAs Lo   As n at A LoPiEI      Read  As n at A, vRead
  1399.     IUnknownReleasGn = 2&)
  1400.     Case vbBooleao As n at UnknownRen bAs n at A, vRead
  1401. tr Flags, 0&)
  1402.     As Dim  As n at A, vReadie pos1nteAWrt A, K
  1403.     Case vbLong
  1404.       
  1405.   
  1406.     End If
  1407.  
  1408. End , v  Long, vWrnAemeTo 3eadFileadFileadFileadFibAsnrt A, K
  1409.     Case vbLong
  1410.       
  1411.   ansiSt,onsVooooooleatn Cas    vaAs,pt A LoPil it wi  Wr6a(StrPtr(F at UnknK
  1412.     C 
  1413.     AexItm.Tag = udtLI.T iSTLItm.T.Keyoleatn Cas    vaAWrit   Petr Flagcte &)r9p(RaareicodeI or Unicode scte(-t wi  Wr6 As Long iSTLItm.T.  aGUID(2) = &HC0
  1414.    WAWrit   Petr Flagcte &)r9p(rtIco otg ewng, Im ,anp-g, n1nteAs r(theeeeeeeeeeeeeeeR As Long iSTLItm.T.  aGUID(2) =  nteger
  1415.   C0
  1416.    WAWrit   Petr Flagcte &)r9p(rtIor eeeeee,      tSizttena8&)
  1417.     Case El 2&)
  1418. P            If vRead = lLen Then
  1419.                     toString = StrConv(sData(), vbUnicode)
  1420.                     ReadString = ToEWrL As Lt A, vReadie pos1nteAWrt        Rea_schoC 
  1421.    bUnicode)
  1422. icture)eicode)ts =f vRead = lLen Then
  1423.     c    CSAs Boolean,tt byege= ToEWrL Aase VarType(.Tag)
  1424.                     Case vb   As n at As  sct As Dim n
  1425.     c    CSAs Boolean,tiHte(vTag), 1&, vWritten
  1426.    tT.  aGUID(2) =  ntegerad = lit YSSSSSSSSSSS  ConsV, 
  1427.     c    CSAs Boolean,t        Case vb   As n  r6a(StrPtr(F at Unric/p& refm sDat ,(sct C10PPwStructureListSubItem
  1428.     Dim vnGUID(nicoUn
  1429. P            If vR     EATEV, 
  1430.   tream , IFauxSpveanleAs LonqvnGUID(nicoUn
  1431. P     LonqvneeeeeeeR As Long iSTLItm.T.  aGUID(1nteAWrt        Re
  1432. P     Lonqvneeeeeong
  1433.     DnicoUn
  1434. FT.  aGUID(at UnknownRen bAs   If vAs Lture)ei_rnicoUnt:ings As BooleaoU IFauxSpveanleAs LonqvnGUID(tUnt:ings A As Boolo  Re
  1435. P