home *** CD-ROM | disk | FTP | other *** search
/ Dan Appleman's Visual Bas…s Guide to the Win32 API / Dan.Applmans.Visual.Basic.5.0.Programmers.Guide.To.The.Win32.API.1997.Ziff-Davis.Press.CD / VB5PG32.mdf / articles / vbpj / source / eventmod.bas < prev    next >
Encoding:
BASIC Source File  |  1996-01-29  |  10.9 KB  |  369 lines

  1. Attribute VB_Name = "EVENTMOD"
  2. ' Eventcod.bas
  3. '
  4. ' Sample program exploring how common algorithms can be
  5. ' converted to event driven versions for Visual Basic
  6. '
  7. ' Copyright (c) 1992, by Desaware
  8. '
  9. '
  10.  
  11. '   For demo purposes, we load our sample array with
  12. '   numbers 1 through ARRAYSIZE in random order
  13. '
  14. '   First call starts the initialization
  15. '   Returns 0 when initialization is complete, -1 otherwise
  16. '   Next call will start initialization again.
  17. '
  18. Function LoadSampleArray%()
  19.     Static x%
  20.     Static inprogress%
  21.  
  22.     Dim temp, pos1%, pos2%, cnt%
  23.     
  24.     If Not inprogress% Then ' Do this part uninterrupted
  25.         inprogress% = -1
  26.         ' Initialize array values
  27.         For cnt% = 1 To ArraySize
  28.             SampleArray(cnt%) = cnt%
  29.         Next cnt%
  30.     End If
  31.  
  32.     ' Now shuffle them to random locations
  33.     
  34.     For cnt% = 1 To 100
  35.         pos1% = Int(Rnd * ArraySize + 1)
  36.         pos2% = Int(Rnd * ArraySize + 1)
  37.         temp = SampleArray(pos1%)
  38.         SampleArray(pos1%) = SampleArray(pos2%)
  39.         SampleArray(pos2%) = temp
  40.         x% = x% + 1
  41.         If x% > ArraySize Then
  42.             inprogress% = 0
  43.             Exit For
  44.         End If
  45.     Next cnt%
  46.     LoadSampleArray% = inprogress%
  47.  
  48.     
  49. End Function
  50.  
  51. '
  52. '
  53. ' -1 if a search the sort is in progress.  The calling
  54. ' program will generally keep calling this function until
  55. ' it receives a result = 0
  56. '
  57. ' On first call, startpos% and endpos% should be set to
  58. '   the start and end positions.
  59. '
  60. ' On all further calls, both of these parameters must
  61. '   be set to zero.
  62. '
  63. ' Calling this function with startpos% set to -1 aborts
  64. ' the current background operation and returns a result
  65. ' 1
  66. '
  67. Function QSortBackground%(ByVal startpos%, ByVal endpos%)
  68. Dim splitloc%
  69. Dim sp%, ep%    ' Internal use start & end position
  70. Static startlocs(300) As Integer
  71. Static endlocs(300) As Integer
  72. Static stackptr%
  73. ' When the function is cancelled, we clear the stack and
  74. ' flag the cancelation for return by the NEXT call -
  75. ' this makes it possible for the code that does the cancelation
  76. ' to not have to do the timer cleanup.
  77. Static cancelpending%
  78.  
  79.     
  80.     If startpos% = -1 Then
  81.         stackptr% = 0
  82.         cancelpending% = -1
  83.         QSortBackground% = -1
  84.         Exit Function
  85.         End If
  86.     
  87.     If endpos% > 0 Then ' It's the first call
  88.         stackptr% = 0   ' Reinitialize the stack pointer
  89.         ' Set up the stack for the next call
  90.         stackptr% = stackptr% + 1
  91.         startlocs(stackptr%) = startpos%
  92.         endlocs(stackptr%) = endpos%
  93.         QSortBackground% = -1
  94.         Exit Function
  95.         End If
  96.     
  97.     ' The sort is complete if the stack is empty
  98.     If stackptr% = 0 Then
  99.         If cancelpending% Then QSortBackground% = 1 Else QSortBackground% = 0
  100.         cancelpending% = 0
  101.         Exit Function
  102.         End If
  103.     
  104.     ' Get the current stack values and pop them off the stack
  105.     sp% = startlocs(stackptr%)
  106.     ep% = endlocs(stackptr%)
  107.     stackptr% = stackptr% - 1
  108.  
  109.     ' This entry is sorted if the start position is
  110.     ' beyond the end position
  111.     If sp% >= ep% Then
  112.         QSortBackground% = -1
  113.         Exit Function
  114.         End If
  115.  
  116.     ' Parition the array into two sections
  117.     splitloc% = QSplit%(sp%, ep%)
  118.  
  119.     ' Now quicksort each of the sections by pushing it
  120.     ' on the stack for the next call
  121.     
  122.     stackptr% = stackptr% + 1
  123.     startlocs(stackptr%) = splitloc% + 1
  124.     endlocs(stackptr%) = ep%
  125.  
  126.     stackptr% = stackptr% + 1
  127.     startlocs(stackptr%) = sp%
  128.     endlocs(stackptr%) = splitloc%
  129.  
  130.     QSortBackground% = -1   ' And continue
  131. End Function
  132.  
  133. '
  134. ' Simple quicksort algorithm without background processing
  135. '
  136. Sub QSortNoEvents(ByVal startpos%, ByVal endpos%)
  137. Dim splitloc%
  138.  
  139.     ' It's over if the start position is beyond the end
  140.     ' position
  141.     If startpos% >= endpos% Then Exit Sub
  142.  
  143.     ' Parition the array into two sections
  144.     splitloc% = QSplit%(startpos%, endpos%)
  145.     ' Now quicksort each of the sections
  146.     QSortNoEvents startpos%, splitloc%
  147.     QSortNoEvents splitloc% + 1, endpos%
  148.     ' That's all there is to it.
  149.  
  150. End Sub
  151.  
  152. '
  153. '   Given a portion of the SampleArray starting at startpos%
  154. '   and ending at endpos% (including both startpos% and
  155. '   endpos%), split the array at an arbitrary point.
  156. '   The selected point will be returned as a result by this
  157. '   function.
  158. '   All entries in the array subset from startpos% to this
  159. '   point are guaranteed to be smaller than the entry for this
  160. '   point.
  161. '   All entries in the array subset from this point to endpos%
  162. '   are guaranteed to be larger than the entry for this point.
  163. '
  164. Function QSplit%(ByVal startpos%, ByVal endpos%)
  165.  
  166. Dim splitloc%
  167. Dim partval#, tval#
  168. Dim fwdscan%, backscan%
  169.  
  170.     
  171.     ' If the array is nearly sorted, using the first entry
  172.     ' as the split value is likely to lead to a stack
  173.     ' overflow in VB, so we pick an entry near the center
  174.     ' as the split value, and move it out of the way to
  175.     ' the front of the array (see sidebar)
  176.  
  177.     If endpos% - startpos% > 5 Then
  178.         splitloc% = (endpos% - startpos%) / 2 + startpos%
  179.         tval# = SampleArray(splitloc%)
  180.         SampleArray(splitloc%) = SampleArray(startpos%)
  181.         SampleArray(startpos%) = tval#
  182.         End If
  183.  
  184.     ' We'll use the first value as the split value
  185.     partval# = SampleArray(startpos%)
  186.  
  187.     fwdscan% = startpos% + 1 ' Index to scan start to end
  188.     backscan% = endpos%     ' Index to scan end to start
  189.  
  190.     Do ' A left and right scan towards the partition value
  191.         ' Search forward until a value is found that is
  192.         ' larger than the partition value.
  193.         Do While fwdscan% <= endpos% And SampleArray(fwdscan%) < partval#
  194.             fwdscan% = fwdscan% + 1
  195.             Loop
  196.         ' Search backward until a value is found that is
  197.         ' smaller than the partition value.
  198.         Do While backscan% >= startpos% + 1 And SampleArray(backscan%) > partval#
  199.             backscan% = backscan% - 1
  200.             Loop
  201.         If fwdscan% < backscan% Then
  202.             ' These two entries are on the wrong side of
  203.             ' the partition value, so swap them
  204.             tval# = SampleArray(fwdscan%)
  205.             SampleArray(fwdscan%) = SampleArray(backscan%)
  206.             SampleArray(backscan%) = tval#
  207.         Else ' Otherwise, the partition is complete, i.e.
  208.             ' All entries from startpos% to backscan% are
  209.             ' smaller than partval#, all entries from
  210.             ' backscan%+1 to endpos% are larger than tval#
  211.             Exit Do
  212.         End If
  213.     Loop
  214.     ' The split is complete. The entry at position
  215.     ' backscan% is now the first entry smaller than
  216.     ' partval# when scaning from the end. We now swap it
  217.     ' with the partition value that was (as you recall)
  218.     ' the first entry in the array.
  219.     tval# = SampleArray(backscan%)
  220.     SampleArray(backscan%) = SampleArray(startpos%)
  221.     SampleArray(startpos%) = tval#
  222.  
  223.     ' And return the actual location of the partition value
  224.     QSplit% = backscan%
  225. End Function
  226.  
  227. ' Shows a search using a looping algorithm that is designed
  228. ' for use in an event driven environment.  The calling
  229. ' function will receive information indicating if the
  230. ' search is done or needs to be continued.  The search
  231. ' can be cancelled by simply ceasing the calls or
  232. ' reset by starting a new search
  233. '
  234. ' searchval& is the number to search for - it is only
  235. ' used when newsearch is true (-1)
  236. '
  237. ' newsearch% is -1 to start a new search, 0 to continue
  238. ' an existing search.
  239. '
  240. ' Returns the position of the number, or 0 if not found,
  241. ' -1 if a search the search is in progress.  The calling
  242. ' program will generally keep calling this function until
  243. ' it receives a result >= 0
  244. '
  245. '
  246. '
  247. Function SearchEventfully%(searchval, newsearch%)
  248. '
  249.     Static x%
  250.     Static savedsearchval
  251.     Dim cnt%
  252.  
  253.     If newsearch% Then  ' Setting up a new search
  254.         savedsearchval = searchval
  255.         x% = 1
  256.     End If
  257.  
  258.     If x% = 0 Then ' Search was not properly started
  259.         SearchEventfully% = x%
  260.         Exit Function
  261.     End If
  262.  
  263.  
  264.     ' Refer to the article for information on granularity
  265.     ' of background operations.
  266.     For cnt% = 1 To 100
  267.         ' Here we access the data.  In a real application
  268.         ' this could be a database or file access.
  269.         If savedsearchval = SampleArray(x%) Then
  270.             SearchEventfully% = x%
  271.             Exit Function
  272.         End If
  273.  
  274.         ' Increment x% and check for the end condition
  275.         x% = x% + 1
  276.         If x% > ArraySize Then Exit For
  277.     Next cnt%
  278.     
  279.     If x% > ArraySize Then
  280.         SearchEventfully% = 0
  281.         x% = 0
  282.     Else
  283.         SearchEventfully% = -1
  284.     End If
  285.     
  286. End Function
  287.  
  288. ' Shows a search using a looping algorithm that uses
  289. ' DoEvents to allow other applications to continue to
  290. ' run, and this application to continue to respond to
  291. ' events.
  292. '
  293. ' searchval is the number to search for
  294. '
  295. ' Returns the position of the number, or 0 if not found,
  296. ' -1 if a search is already in progress.
  297. '
  298. '
  299. Function SearchWithDoEvents%(searchval)
  300. '
  301.     Dim x%, counter%, temp%
  302.  
  303.     ' We use this flag to prevent multiple searches from
  304.     ' starting, which could lead to an overflow
  305.     Static NowSearching
  306.  
  307.     If NowSearching Then
  308.         ' A Search is already in progress - the calling
  309.         ' application should not start a new one due to the
  310.         ' risk of stack overflows.
  311.         SearchWithDoEvents% = -1
  312.         Exit Function
  313.     End If
  314.  
  315.     
  316.     For x% = 1 To ArraySize
  317.         ' Here we access the data.  In a real application
  318.         ' this could be a database or file access.
  319.         If searchval = SampleArray(x%) Then
  320.             SearchWithDoEvents% = x%
  321.             Exit Function
  322.         End If
  323.  
  324.         counter% = counter% + 1
  325.         If counter% = 10 Then ' Every 10th we do a DoEvents()
  326.             counter% = 0
  327.             temp% = DoEvents()  ' Let events take place
  328.             ' This would be a good place to monitor a
  329.             ' module or global variable for cancellation
  330.             ' of the search
  331.         End If
  332.         
  333.     Next x%
  334.  
  335.     ' No value found
  336.     SearchWithDoEvents% = 0
  337.     
  338.  
  339. End Function
  340.  
  341. ' Shows a search using a looping algorithm that ties up
  342. ' the system.
  343. '
  344. ' searchval% is the number to search for
  345. '
  346. ' Returns the position of the number, or 0 if not found
  347. '
  348. Function SearchWithoutEvents%(searchval)
  349.     Dim x%, oldmousepointer%
  350.  
  351.     oldmousepointer% = Screen.MousePointer
  352.     Screen.MousePointer = 11
  353.     For x% = 1 To ArraySize
  354.         ' Here we access the data.  In a real application
  355.         ' this could be a database or file access.
  356.         If searchval = SampleArray(x%) Then
  357.             SearchWithoutEvents% = x%
  358.             Screen.MousePointer = oldmousepointer%
  359.             Exit Function
  360.         End If
  361.     Next x%
  362.  
  363.     ' No value found
  364.     SearchWithoutEvents% = 0
  365.     Screen.MousePointer = oldmousepointer%
  366.  
  367. End Function
  368.  
  369.