home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 4_2005-2006.ISO / data / Zips / Listbox_Re198443412006.psc / cListClass.cls < prev    next >
Text File  |  2006-04-01  |  16KB  |  422 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 = "cListClass"
  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. ' __________________________________________________________________________
  17. '/ListClass version 1.2                                                     \
  18. '\==========================================================================/
  19. '|Author: HardStream Group                                                  |
  20. '|Date  : 04-01-2006                                                        |
  21. '|Name  : cListClass                                                        |
  22. '|Verson: 1.2                                                               |
  23. '/==========================================================================\
  24. '|Version 1.0:                                                              |
  25. '|First version of this list class. This class is meant to be a replacement |
  26. '|for the listbox. If you're writing an application with forms, this won't  |
  27. '|be very helpful, but if you're writing a DLL, a console application or    |
  28. '|any different type of program without visible objects, this can be a very |
  29. '|helpful class.                                                            |
  30. '\==========================================================================/
  31. '|Version 1.1                                                               |
  32. '|The class has been updated with a sorting function, so items can be sorted|
  33. '|alphabetically.                                                           |
  34. '|For the sorting, I've used Rde's QuickSort 2.1 module. Link:              |
  35. '|http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=64095&lngWId=1    |
  36. '|                                                                          |
  37. '|I've also added the ability to add items somewhere in the middle of the   |
  38. '|list using an index, just like in the VB listbox.                         |
  39. '|You can now automaticly put the list in a textbox and in a listbox.       |
  40. '|If you want to put it in other controls, you can use the same technique,  |
  41. '|but apply it to the control you want :D                                   |
  42. '|The class now also has events, so you can call the class as a WithEvents. |
  43. '/==========================================================================\
  44. '|WithEvents explanation                                                    |
  45. '|                                                                          |
  46. '|In in the Declarations part of the form/module etc. code, you put:        |
  47. '|Private WithEvents vList As cListClass                                    |
  48. '|                                                                          |
  49. '|In the Form_Load/UserControl_Initialize etc. part you put:                |
  50. '|Set vList = New cListClass                                                |
  51. '|                                                                          |
  52. '|Then you can call events like with any other (visible) control.           |
  53. '|If you want to call the ItemAdd event, just copypaste the following code: |
  54. '|Private Sub vList_ItemAdd(Index As Long)                                  |
  55. '|                                                                          |
  56. '|Just make sure you're using the same datatypes as used in the Events in   |
  57. '|the class. Using different datatypes may result in error.                 |
  58. '\==========================================================================/
  59. '|Version 1.2                                                               |
  60. '|New added features:                                                       |
  61. '|1) Search: search through the listbox to get the index of an item.        |
  62. '|2) Import and export functions, so you can easily import from and export  |
  63. '|   to a file.                                                             |
  64. '|3) Encryption/decryption so you can store private data without worrying   |
  65. '|   about other people reading it.                                         |
  66. '|   The encrypting/decrypting routine still needs work, check the example  |
  67. '|   program to see for yourself what goes wrong. I'm not an expert on      |
  68. '|   encrypting/decrypting, but because I wanted my own code as much as     |
  69. '|   possible (but there's no way I'm going to write the sorting stuff :P), |
  70. '|   I just wanted to have my own encrypting/decrypting code, but it's not  |
  71. '|   working very well, so if anyone else could do this for me... :)        |
  72. '\__________________________________________________________________________/
  73. ' |ps.                                                                     |
  74. ' |1) Sorry for my bad English, it's not my native language :P             |
  75. ' |2) If you find any error(s), please report them, I'll try to fix them   |
  76. ' \________________________________________________________________________/
  77.  
  78. 'Events
  79. Event ItemAdd(Index As Long)
  80. Event ItemRemove(Index As Long)
  81. Event Clear()
  82. Event Sort(SortTime As Double, Success As Boolean)
  83. Event ListCreated(Ctl As Control)
  84. Event Error(Number As Byte, Description As String)
  85. Event SearchFinish(Result As Long)
  86. Event ExportDone(Filename As String, BytesWritten As Long)
  87. Event ImportDone(Filename As String, BytesRead As Long)
  88. Event EncodeDone()
  89. Event DecodeDone()
  90.  
  91. 'Private APIs
  92. Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
  93. Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
  94.  
  95. 'Private variables
  96. Private sList As String
  97. Private cFrequency As Currency
  98. Private cStart As Currency
  99. Private cNow As Currency
  100. Private bAvailable As Boolean
  101.  
  102. '\/Stopwatch related
  103. 'If you want to remove the stopwatch from the class, you have to remove all
  104. 'API calls and the following 3 functions.
  105. 'You can use the Find function ([Ctrl]+[F]) in VB to find all calls to
  106. 'stopwatch related functions in other functions.
  107. 'You can also remove all private variable, except sList.
  108. Private Sub Class_Initialize()
  109. bAvailable = (QueryPerformanceFrequency(cFrequency) <> 0)
  110. If (bAvailable) Then Debug.Print "Ticks/sec: "; cFrequency * 10000 Else Debug.Print "Performance Counter not available"
  111. End Sub
  112.  
  113. 'Reset the stopwatch
  114. Private Sub sw_Reset()
  115. QueryPerformanceCounter cStart
  116. End Sub
  117.  
  118. 'Get the elapsed time
  119. Private Function sw_Elapsed() As Double
  120. Call QueryPerformanceCounter(cNow)
  121. If (bAvailable) Then sw_Elapsed = 1000 * (cNow - cStart) / cFrequency
  122. End Function
  123. '/\Stopwatch related
  124.  
  125. Private Function PrettySort(StringArray() As String, Optional CapsFirst As Boolean = True, Optional ReverseOrder As Boolean = False) As String
  126. On Error GoTo FndErr
  127. Dim LB As Long, UB As Long
  128. Dim p_CapsFirst As Boolean
  129. Dim p_eDirection As Long
  130.  
  131. p_CapsFirst = (CapsFirst = 1)
  132. p_eDirection = (ReverseOrder * -2) + 1 '0 >> 1 : 1 >> -1
  133. LB = LBound(StringArray)
  134. UB = UBound(StringArray)
  135. strPrettySort StringArray, LB, UB, p_CapsFirst, p_eDirection
  136. PrettySort = Join(StringArray, vbCrLf)
  137. Exit Function
  138.  
  139. FndErr:
  140.     PrettySort = ""
  141. End Function
  142.  
  143. 'Count the number of occurrences of a (set of) character(s) in an expression
  144. Private Function Occur(Expression As String, Optional Delimiter = vbCrLf) As Long
  145. Occur = UBound(Split(Expression, Delimiter))
  146. End Function
  147.  
  148. 'Read one line from a multiline string
  149. Private Function ReadLine(Expression As String, Line As Long) As String
  150. If Line > Occur(Expression) Then 'Line number is too high
  151.     ReadLine = ""
  152.     Exit Function
  153.         ElseIf Line < 0 Then 'Line number is too low
  154.     ReadLine = ""
  155.     Exit Function
  156. End If
  157.  
  158. ReadLine = Split(Expression, vbCrLf)(Line) 'Read the line
  159. End Function
  160.  
  161. 'Add a new line to an expression
  162. Private Sub AddToString(Storage As String, Expression As String)
  163. If Trim(Storage) = "" Then Storage = Expression Else Storage = Storage & vbCrLf & Expression
  164. End Sub
  165.  
  166. 'Add an item to the list
  167. Sub AddItem(Item As String, Optional Index = -1)
  168. Dim Part(0 To 1) As String
  169. Dim i As Long
  170. Dim ReturnIndex As Long
  171.  
  172. If IsNumeric(Index) = False Then 'The index isn't numeric
  173.     Err.Raise 102, "ListClass", "Non-numeric index"
  174.     RaiseEvent Error(102, "Non-numeric index")
  175.     Exit Sub
  176. End If
  177.  
  178. If Trim(sList) = "" Then 'The list is empty
  179.     sList = Item
  180.     ReturnIndex = 0
  181.     GoTo AddDone
  182. End If
  183.  
  184. If Index = -1 Then 'Add the item as the last item
  185.     sList = sList & vbCrLf & Item
  186.     ReturnIndex = Occur(sList)
  187.         ElseIf Index = 0 Then 'Add the item as the first item
  188.     sList = Item & vbCrLf & sList
  189.     ReturnIndex = 0
  190.         ElseIf Index > 0 Then 'Add somewhere in the middle
  191.     If Index = Occur(sList) + 1 Then 'Add the item as the last item
  192.         sList = sList & vbCrLf & Item
  193.         ReturnIndex = Index 'Return the correct index
  194.             ElseIf Occur(sList) + 1 < Index Then 'The list is smaller than index+1, so just add as last item and return corrected index
  195.         sList = sList & vbCrLf & Item
  196.         ReturnIndex = Occur(sList) - 1
  197.             Else 'Really add the item somewhere in the middle of the list
  198.         For i = 0 To Index - 1 'Loop through the first part of the list
  199.             AddToString Part(0), ReadLine(sList, i)
  200.         Next i
  201.         For i = Index To Occur(sList) 'Loop through the second part of the list
  202.             AddToString Part(1), ReadLine(sList, i)
  203.         Next i
  204.         
  205.         sList = Part(0) & vbCrLf & Item & vbCrLf & Part(1) 'Add the item
  206.         ReturnIndex = Index 'Return the correct index
  207.     End If
  208. End If
  209.  
  210. AddDone:
  211.     RaiseEvent ItemAdd(ReturnIndex)
  212. End Sub
  213.  
  214. 'Remove an item from the list
  215. Sub RemoveItem(Index As Long)
  216. Dim Tmp As String
  217. Dim i As Long
  218.  
  219. If IsNumeric(Index) = False Then 'Non-numeric index
  220.     Err.Raise 102, "ListClass", "Non-numeric index"
  221.     RaiseEvent Error(102, "Non-numeric index")
  222.     Exit Sub
  223. End If
  224.  
  225. If Index = 0 Then 'Remove the first item
  226.     For i = 1 To Occur(sList)
  227.         AddToString Tmp, ReadLine(sList, i)
  228.     Next i
  229.         ElseIf Index < 0 Then 'Invalid index
  230.         ElseIf Index > 0 Then 'Remove a later item
  231.     For i = 0 To Index - 1
  232.         AddToString Tmp, ReadLine(sList, i)
  233.     Next i
  234.     
  235.     If Index < Occur(sList) Then 'The removed item isn't the last item in the list
  236.         For i = Index + 1 To Occur(sList)
  237.             AddToString Tmp, ReadLine(sList, i)
  238.         Next i
  239.     End If
  240. End If
  241.  
  242. sList = Tmp 'Save
  243. Tmp = "" 'Clear up
  244.  
  245. RaiseEvent ItemRemove(Index)
  246. End Sub
  247.  
  248. 'Clear the list
  249. Sub Clear()
  250. sList = ""
  251. RaiseEvent Clear
  252. End Sub
  253.  
  254. 'Get the text of a list item
  255. 'Set Index=-1 to get the complete list
  256. Function Text(Optional Index As Long = -1) As String
  257. If Index = vbNullString Then
  258.     Text = ""
  259.     Exit Function
  260. End If
  261.  
  262. If IsNumeric(Index) = False Then 'Non-numeric index
  263.     Err.Raise 102, "ListClass", "Non-numeric index"
  264.     RaiseEvent Error(102, "Non-numeric index")
  265.     Text = ""
  266.     Exit Function
  267. End If
  268.  
  269. If Index >= 0 Then Text = ReadLine(sList, Index)
  270. If Index = -1 Then Text = sList
  271. End Function
  272.  
  273. 'Get the number of items
  274. Function ListCount()
  275. ListCount = Occur(sList) + 1
  276. End Function
  277.  
  278. 'Sort the list
  279. Function Sort(Optional CapsFirst As Boolean = True, Optional ReverseOrder As Boolean = False) As Double
  280. Dim tSort() As String
  281. Dim Result As String, OldList As String
  282. Dim SortTime As Double
  283.  
  284. sw_Reset 'Reset the stopwatch
  285.  
  286. If Trim(sList) = "" Then GoTo Pointless 'Check if the list string is not empty
  287. If Occur(sList) = 0 Then GoTo Pointless 'Check if there really is a multi-line string, not just a single-line string
  288. Result = "" 'Make sure the result buffer is empty
  289. tSort = Split(sList, vbCrLf) 'Create the array
  290. Result = PrettySort(tSort, CapsFirst, ReverseOrder) 'Sort and store in a temporary buffer
  291. OldList = sList 'Store the old list (unsorted). In case of an error, this is restored, so the list won't be lost
  292.  
  293. If Trim(Result) <> "" Then
  294.     sList = Result 'Apply
  295.     Result = "" 'Clean the temporary buffer
  296.     OldList = "" 'Clean the old list buffer
  297.     SortTime = sw_Elapsed 'Return elapsed time since sort start
  298.     Sort = SortTime
  299.     RaiseEvent Sort(SortTime, True)
  300.     Exit Function
  301.         Else
  302.     SortTime = sw_Elapsed
  303.     RaiseEvent Sort(SortTime, False)
  304. End If
  305.  
  306. Pointless: 'Unnecessary to sort, but not error worthy
  307.     Sort = 0
  308.     Exit Function
  309.  
  310. FndErr: 'An error occurred
  311.     RaiseEvent Sort(0, False)
  312.     Err.Raise 101, "ListClass", "Sorting failed"
  313.     RaiseEvent Error(101, "Sorting failed")
  314.     sList = OldList 'Restore the old list (in case the corrupted sorted list has been applied)
  315.     Sort = 0
  316. End Function
  317.  
  318. 'Put all items in a control.
  319. 'Currently there is only support for Textbox, Listbox and Combobox controls, but you can easily add support for more controls
  320. Sub PutInControl(Ctl As Control, Optional AutoClean As Boolean = True)
  321. Dim i As Long
  322.  
  323. 'Auto clean (if true)
  324. If AutoClean = True Then
  325.     If TypeOf Ctl Is TextBox Then Ctl.Text = "" 'Textbox
  326.     If TypeOf Ctl Is ListBox Or TypeOf Ctl Is ComboBox Then Ctl.Clear 'Listbox/Combobox
  327. End If
  328.  
  329. For i = 0 To Occur(sList) 'Loop through all items
  330.     If TypeOf Ctl Is TextBox Then 'Using a textbox
  331.         If Trim(Ctl.Text) = "" Then Ctl.Text = ReadLine(sList, i) Else Ctl.Text = Ctl.Text & vbCrLf & ReadLine(sList, i)
  332.             ElseIf TypeOf Ctl Is ListBox Or TypeOf Ctl Is ComboBox Then 'Using a listbox or combobox (doesn't matter in this case, because they both have the necessary functions)
  333.         Ctl.AddItem ReadLine(sList, i)
  334.     End If
  335. Next i
  336.  
  337. RaiseEvent ListCreated(Ctl)
  338. End Sub
  339.  
  340. 'Search for an item in the list
  341. Function SearchItem(Expression As String, Optional ExactMatch As Boolean = False, Optional CaseMatch As Boolean = False) As Long
  342. Dim i As Long
  343. Dim Tmp(0 To 1) As String
  344.  
  345. If CaseMatch = True Then Tmp(1) = Expression Else Tmp(1) = LCase(Expression)
  346.  
  347. For i = 0 To Occur(sList) 'Loop through the list
  348.     Tmp(0) = ReadLine(sList, i) 'Read the current line
  349.     
  350.     If ExactMatch = True Then 'Exact match required
  351.         If Tmp(0) = Expression Then 'Match
  352.             SearchItem = i
  353.             RaiseEvent SearchFinish(i)
  354.             Exit Function
  355.                 Else 'No match
  356.             GoTo TryNext
  357.         End If 'Match
  358.             Else 'Exact match not required
  359.         If InStr(1, Tmp(0), Expression) > 0 Then 'Match
  360.             SearchItem = i
  361.             RaiseEvent SearchFinish(i)
  362.             Exit Function
  363.                 Else 'No match
  364.             GoTo TryNext
  365.         End If
  366.     End If 'ExactMatch
  367. TryNext:
  368. Next i
  369.  
  370. 'The code hereunder will only be executed if there are no results
  371. SearchItem = -1
  372. RaiseEvent SearchFinish(-1)
  373. End Function
  374.  
  375. 'Export the list to a file
  376. Sub Export(Filename As String)
  377. Dim FF As Long
  378.  
  379. FF = FreeFile
  380. Open Filename For Binary Access Write As #FF 'Open the file for writing
  381.     Put #FF, , sList 'Write to the file
  382. Close #FF 'Close the file
  383. RaiseEvent ExportDone(Filename, Len(sList))
  384. End Sub
  385.  
  386. 'Import list from a file
  387. Sub Import(Filename As String)
  388. Dim FF As Long
  389.  
  390. FF = FreeFile
  391. Open Filename For Binary Access Read As #FF 'Open the file for reading
  392.     sList = Input(LOF(FF), FF) 'Read from the file
  393. Close #FF 'Close the file
  394. RaiseEvent ImportDone(Filename, Len(sList))
  395. End Sub
  396.  
  397. 'Encode the list
  398. Sub Encode()
  399. Dim i As Long, Tmp As String
  400.  
  401. For i = 0 To Occur(sList)
  402.     Tmp = Tmp & vbCrLf & Encrypt(ReadLine(sList, i))
  403. Next i
  404. sList = Tmp
  405. Tmp = ""
  406.  
  407. RaiseEvent EncodeDone
  408. End Sub
  409.  
  410. 'Decode the list
  411. Sub Decode()
  412. Dim i As Long, Tmp As String
  413.  
  414. For i = 0 To Occur(sList)
  415.     Tmp = Tmp & vbCrLf & Decrypt(ReadLine(sList, i))
  416. Next i
  417. sList = Tmp
  418. Tmp = ""
  419.  
  420. RaiseEvent DecodeDone
  421. End Sub
  422.