home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l391 / 2.ddi / SPIN.BA$ / SPIN.bin
Encoding:
Text File  |  1992-08-19  |  24.6 KB  |  604 lines

  1. ' ----------------------------------------------------------------------------
  2. ' SPIN.BAS: Spin Custom Control Event Procedures
  3. '
  4. ' The Spin custom control can be used with another
  5. ' control to increment and decrement numbers.  It can
  6. ' also be used to scroll back and forth through a
  7. ' range of values or a list of items.
  8. '
  9. ' At run-time, when the user clicks the up (or right)
  10. ' arrow of the spin button or presses the up (or right)
  11. ' arrow key, Custom events of type "SpinUp" are
  12. ' generated and the value property is incremented accordingly.
  13. ' Likewise, when the user clicks the down (or left) arrow
  14. ' of the spin button or presses the down (or left) arrow
  15. ' key, Custom events of type "SpinDown" are generated and
  16. ' the value property is decremented.
  17. '
  18. ' The Style property determines the type of spin
  19. ' control:
  20. '     0 - Vertical (default)
  21. '     1 - Horizontal
  22. ' The Interval property is used to determine how often
  23. '     the SpinUp and SpinDown events are generated (in
  24. '     milliseconds - default = 100).
  25. ' The Min and Max properties determine the lower and
  26. '     upper range that the Value property cycles
  27. '     (or spins) through.  When Value becomes equal
  28. '     to Max it is reset to Min and vice-versa.
  29. ' The BorderStyle property is not available at
  30. ' run-time.  Width and Height properties are read-only
  31. ' at run-time - the control size is fixed.  All other
  32. ' properties behave similar to the same properties of
  33. ' the standard controls.
  34. '
  35. ' Custom control event procedure template created by
  36. ' CUSTGEN.EXE (Custom Control Template Generator).
  37. ' CUSTGEN.EXE is a utility provided to make custom
  38. ' control development easier.  It allows you to select
  39. ' the events you want your custom control to respond to,
  40. ' then generates code templates and a custom control
  41. ' registration routine for these events.
  42. '
  43. ' Modify the code template file as necessary, then build
  44. ' your custom control as follows:
  45. '    ML -c spinreg.asm             ; Assumes Masm 6.0 compiler
  46. '    BC /x/o spin.bas;
  47. '    DEL spin.lib                  ; Delete existing library if exists
  48. '    LIB spin.lib+spinreg.obj+spin.obj
  49. '    LINK /Q spin.lib,spin.qlb,,VBDOSQLB.LIB;
  50. ' You can combine the spin custom control with other custom controls
  51. ' into one Quick library for use within the programming environment
  52. ' as follows:
  53. '    DEL <CombinedLib.LIB>         ; Delete existing library if exists
  54. '    LIB <CombinedLib.LIB>+spin.lib+<Cust2.LIB>+<CustN.LIB>
  55. '    LINK /Q <CombinedLib.LIB>,<CombinedLib.QLB>,,VBDOSQLB.LIB;
  56. ' To create an Alternate Math custom control library (instead of an
  57. ' Emulator Math custom control library as shown above), compile
  58. ' SPIN.BAS with the /FPa switch.  Note, an Altmath library cannot be
  59. ' used to create a Quick Library.
  60. '
  61. '
  62. ' Copyright (C) 1982-1992 Microsoft Corporation
  63. '
  64. ' You have a royalty-free right to use, modify, reproduce
  65. ' and distribute the sample applications and toolkits provided with
  66. ' Visual Basic for MS-DOS (and/or any modified version)
  67. ' in any way you find useful, provided that you agree that
  68. ' Microsoft has no warranty, obligations or liability for
  69. ' any of the sample applications or toolkits.
  70. ' ----------------------------------------------------------------------------
  71.  
  72.  
  73. ' Include file containing constant definitions for
  74. ' Property, Event, Method and ControlType ID numbers.
  75. '$INCLUDE: 'CUSTINCL.BI'
  76.  
  77. ' Turn on option explicit to force all variables to be
  78. ' declared before use.  Note, this is an optional debugging aid.
  79. OPTION EXPLICIT
  80.  
  81. ' Declarations for custom control callbacks.
  82. ' These callbacks are used to set and get custom control
  83. ' properties and invoke custom control methods and events.
  84. '
  85. '    AID = Attribute Id - list is found in CUSTINCL include file.
  86. '    CID = Control Id created internally by Visual Basic
  87. '    EID = Event Id - list is found in CUSTINCL include file.
  88. '    MthID = Method Id - list is found in CUSTINCL include file.
  89. '    PID = Property Id - list is found in CUSTINCL include file.
  90.  
  91. ' Declare callbacks for invoking methods and events and getting
  92. ' and setting properties.  These callbacks accept a variable number
  93. ' and types of arguments depending on the method or event that is
  94. ' being invoked.
  95. DECLARE SUB InvokeEvent
  96. DECLARE SUB InvokeMethod
  97. DECLARE SUB GetProperty
  98. DECLARE SUB SetProperty
  99. DECLARE SUB SetIntProperty ALIAS "SetProperty" (BYVAL value AS INTEGER, BYVAL CID AS INTEGER, BYVAL PID AS INTEGER)
  100. DECLARE SUB SetStringProperty ALIAS "SetProperty" (value AS STRING, BYVAL CID AS INTEGER, BYVAL PID AS INTEGER)
  101. DECLARE SUB SetLongProperty ALIAS "SetProperty" (BYVAL value AS LONG, BYVAL CID AS INTEGER, BYVAL PID AS INTEGER)
  102.  
  103. ' Declare callback for setting a control's attributes (access key,
  104. ' focus availability, arrow key trapping ability, and text cursor
  105. ' location).
  106. DECLARE SUB SetAttribute (BYVAL CID AS INTEGER, BYVAL AID AS INTEGER, BYVAL value AS INTEGER)
  107.  
  108. ' Declare callback for getting a control's container object.
  109. ' This callback returns a CID for the container object.
  110. DECLARE FUNCTION GetContainer (BYVAL CID AS INTEGER) AS INTEGER
  111.  
  112. ' Procedure declarations for handled events.
  113. DECLARE FUNCTION Spin_CClick (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  114. DECLARE FUNCTION Spin_CDblClick (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  115. DECLARE FUNCTION Spin_CIntegerGet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, value AS INTEGER) AS INTEGER
  116. DECLARE FUNCTION Spin_CIntegerSet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, BYVAL value AS INTEGER) AS INTEGER
  117. DECLARE FUNCTION Spin_CGotFocus (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  118. DECLARE FUNCTION Spin_CKeyDown (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, keycode AS INTEGER, Shift AS INTEGER) AS INTEGER
  119. DECLARE FUNCTION Spin_CKeyPress (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, KeyAscii AS INTEGER) AS INTEGER
  120. DECLARE FUNCTION Spin_CKeyUp (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, keycode AS INTEGER, Shift AS INTEGER) AS INTEGER
  121. DECLARE FUNCTION Spin_CLoad (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  122. DECLARE FUNCTION Spin_CLostFocus (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  123. DECLARE FUNCTION Spin_CMouseDown (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, Button AS INTEGER, Shift AS INTEGER, X AS SINGLE, Y AS SINGLE) AS INTEGER
  124. DECLARE FUNCTION Spin_CMouseMove (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, Button AS INTEGER, Shift AS INTEGER, X AS SINGLE, Y AS SINGLE) AS INTEGER
  125. DECLARE FUNCTION Spin_CMouseUp (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, Button AS INTEGER, Shift AS INTEGER, X AS SINGLE, Y AS SINGLE) AS INTEGER
  126. DECLARE FUNCTION Spin_CMthAddItem (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, value AS STRING, BYVAL Index AS INTEGER) AS INTEGER
  127. DECLARE FUNCTION Spin_CMthCls (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  128. DECLARE FUNCTION Spin_CMthHide (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  129. DECLARE FUNCTION Spin_CMthMove (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, BYVAL pLeft AS INTEGER, BYVAL pTop AS INTEGER, BYVAL pWidth AS INTEGER, BYVAL pHeight AS INTEGER) AS INTEGER
  130. DECLARE FUNCTION Spin_CMthPrint (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  131. DECLARE FUNCTION Spin_CMthRemoveItem (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, BYVAL Index AS INTEGER) AS INTEGER
  132. DECLARE FUNCTION Spin_CMthShow (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, BYVAL Modal AS INTEGER) AS INTEGER
  133. DECLARE FUNCTION Spin_CPaint (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  134. DECLARE FUNCTION Spin_CStringGet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, value AS STRING, Index AS INTEGER) AS INTEGER
  135. DECLARE FUNCTION Spin_CStringSet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, value AS STRING, Index AS INTEGER) AS INTEGER
  136. DECLARE FUNCTION Spin_CTimer (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  137. DECLARE SUB FireSpin (Ctrl AS CONTROL, ControlID AS INTEGER, FromRoutine$)
  138.  
  139.  
  140. DIM SHARED wSpin_ButtonDown AS INTEGER  ' Button is depressed.
  141. DIM SHARED wSpin_Tracking   AS INTEGER  ' Currently tracking spin events.
  142. DIM SHARED sSpin_X AS SINGLE            ' X mouse coordinate.
  143. DIM SHARED sSpin_Y AS SINGLE            ' Y mouse coordinate.
  144.  
  145. ' Constant definitions.
  146. CONST SPIN_UP = 1                   ' Spin directions.
  147. CONST SPIN_DOWN = 2
  148. CONST KEY_LEFT = 37                 ' Key trapping.
  149. CONST KEY_UP = 38
  150. CONST KEY_RIGHT = 39
  151. CONST KEY_DOWN = 40
  152. CONST LEFT_BUTTON = 1               ' Mouse button.
  153. CONST TRUE = -1                     ' True/False.
  154. CONST FALSE = 0
  155.  
  156. ' Error codes.
  157. CONST ERR_METHNOTAPPLICABLE = 421   ' Method not applicable for this object
  158. CONST ERR_INVALIDPROPVALUE = 380    ' Invalid property value
  159. CONST ERR_PROPERTYRO = 383          ' Property is read-only
  160. CONST ERR_PROPNOTFOUND = 422        ' Property not found
  161. CONST ERR_PROPNOTAVAIL = 386        ' Property not available at run-time
  162.  
  163. ' Control procedure for generating spin events.
  164. ' Determine which direction to spin, then adjusts value
  165. ' and fires event accordingly.
  166. SUB FireSpin (Ctrl AS CONTROL, ControlID AS INTEGER, FromRoutine$)
  167.     DIM w AS INTEGER
  168.     DIM h AS INTEGER
  169.     DIM wSpinDir%
  170.     DIM mx AS INTEGER
  171.     DIM mn AS INTEGER
  172.     DIM v AS LONG
  173.  
  174.     mx = Ctrl.Max
  175.     mn = Ctrl.Min
  176.     v = Ctrl.value
  177.  
  178.     ' Determine which direction to spin and calculate
  179.     ' new value.
  180.     IF Ctrl.Style = 1 THEN
  181.         w = Ctrl.Width \ 2
  182.         IF (sSpin_X < w) THEN
  183.             wSpinDir% = SPIN_DOWN
  184.             v = v - 1
  185.         ELSE
  186.             wSpinDir% = SPIN_UP
  187.             v = v + 1
  188.         END IF
  189.     ELSE
  190.         h = Ctrl.Height \ 2
  191.         IF (sSpin_Y < h) THEN
  192.             wSpinDir% = SPIN_UP
  193.             v = v + 1
  194.         ELSE
  195.             wSpinDir% = SPIN_DOWN
  196.             v = v - 1
  197.         END IF
  198.     END IF
  199.  
  200.     ' Store new Value
  201.     IF (v < mn) THEN v = mx
  202.     IF (v > mx) THEN v = mn
  203.     SetIntProperty CINT(v), ControlID, PROP_Value
  204.  
  205.     ' Invoke CUSTOM event with correct event type.
  206.     ON LOCAL ERROR RESUME NEXT
  207.     ERR = 0
  208.     InvokeEvent wSpinDir%, BYVAL ControlID, BYVAL EVENT_Custom
  209.     IF (ERR) THEN MSGBOX FromRoutine$ + ": " + ERROR$, 0, "Spin Custom Control Assertion"
  210. END SUB
  211.  
  212. ' Click event for control.
  213. FUNCTION Spin_CClick (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  214.     ' Trap event so not sent to user's code.
  215. END FUNCTION
  216.  
  217. ' Double click event for control.
  218. FUNCTION Spin_CDblClick (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  219.     ' Trap event so not sent to user's code.
  220. END FUNCTION
  221.  
  222. ' GotFocus event for control.
  223. ' Sets blinking cursor to show focus.
  224. FUNCTION Spin_CGotFocus (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  225.     SetAttribute ControlID, ATTR_TextCursor, TC_UnderScore
  226. END FUNCTION
  227.  
  228. ' Integer property get event for control.
  229. ' Allows value retrieval for supported properties.
  230. FUNCTION Spin_CIntegerGet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, value AS INTEGER) AS INTEGER
  231.     SELECT CASE PropertyId
  232.         ' Return value of supported properties.
  233.         CASE PROP_Width, PROP_Height, PROP_Style, PROP_Min, PROP_Max, PROP_Value, PROP_DragMode, PROP_Index, PROP_MousePointer, PROP_TabIndex, PROP_TabStop, PROP_BackColor, PROP_ForeColor, PROP_Top, PROP_Left, PROP_Enabled, PROP_Visible:
  234.             Spin_CIntegerGet = 0
  235.         ' Borderstyle not available at run-time.
  236.         CASE PROP_BorderStyle:
  237.             Spin_CIntegerGet = ERR_PROPNOTAVAIL
  238.         ' All other properties not supported for this control.
  239.         CASE ELSE
  240.             Spin_CIntegerGet = ERR_PROPNOTFOUND
  241.     END SELECT
  242. END FUNCTION
  243.  
  244. ' Integer property set event for control.
  245. ' Allows supported property values to be set.
  246. FUNCTION Spin_CIntegerSet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, BYVAL value AS INTEGER) AS INTEGER
  247.     DIM v AS INTEGER
  248.     DIM wSpinDir AS INTEGER
  249.  
  250.     v = Ctrl.value
  251.     SELECT CASE PropertyId
  252.         ' Height and Width properties are read-only.
  253.         CASE PROP_Width, PROP_Height:
  254.             Spin_CIntegerSet = ERR_PROPERTYRO
  255.  
  256.         ' Borderstyle is not available at run-time.
  257.         CASE PROP_BorderStyle:
  258.             Spin_CIntegerSet = ERR_PROPNOTAVAIL
  259.  
  260.         ' Set control height and width based on style property.
  261.         CASE PROP_Style:
  262.             SELECT CASE value
  263.                 CASE 0
  264.                     SetIntProperty 1, ControlID, PROP_Width
  265.                     SetIntProperty 2, ControlID, PROP_Height
  266.                     SetIntProperty 0, ControlID, PROP_Style
  267.                     Spin_CIntegerSet = Spin_CPaint(Ctrl, ControlID)
  268.                 CASE 1
  269.                     SetIntProperty 2, ControlID, PROP_Width
  270.                     SetIntProperty 1, ControlID, PROP_Height
  271.                     SetIntProperty 1, ControlID, PROP_Style
  272.                     Spin_CIntegerSet = Spin_CPaint(Ctrl, ControlID)
  273.                 CASE ELSE
  274.                     Spin_CIntegerSet = ERR_INVALIDPROPVALUE
  275.             END SELECT
  276.         
  277.         ' Set min property and adjust value property if needed.
  278.         CASE PROP_Min:
  279.             IF value > Ctrl.Max THEN
  280.                 IF (v < Ctrl.Max) THEN SetIntProperty Ctrl.Max, ControlID, PROP_Value
  281.             ELSE
  282.                 IF (v < value) THEN SetIntProperty value, ControlID, PROP_Value
  283.             END IF
  284.             SetIntProperty value, ControlID, PropertyId
  285.  
  286.         ' Set max property and adjust value property if needed.
  287.         CASE PROP_Max:
  288.             IF value < Ctrl.Min THEN
  289.                 IF (v > Ctrl.Min) THEN SetIntProperty Ctrl.Min, ControlID, PROP_Value
  290.             ELSE
  291.                 IF (v > value) THEN SetIntProperty value, ControlID, PROP_Value
  292.             END IF
  293.             SetIntProperty value, ControlID, PropertyId
  294.  
  295.         ' Set value property, adjusting it if needed.
  296.         CASE PROP_Value:
  297.             ' Value cannot be greater than Max.
  298.             IF value > Ctrl.Max THEN
  299.                 SetIntProperty Ctrl.Max, ControlID, PROP_Value
  300.             ' Value cannot be less than Min.
  301.             ELSEIF value < Ctrl.Min THEN
  302.                 SetIntProperty Ctrl.Min, ControlID, PROP_Value
  303.             ELSE
  304.                 SetIntProperty value, ControlID, PROP_Value
  305.             END IF
  306.  
  307.         ' Allow other supported properties to be set.
  308.         CASE PROP_DragMode, PROP_Index, PROP_MousePointer, PROP_TabIndex, PROP_TabStop, PROP_Interval, PROP_BackColor, PROP_ForeColor, PROP_Top, PROP_Left, PROP_Enabled, PROP_Visible:
  309.             ERR = 0
  310.             ON LOCAL ERROR RESUME NEXT
  311.             SetIntProperty value, ControlID, PropertyId
  312.             Spin_CIntegerSet = ERR
  313.  
  314.         ' All other properties are not supported.
  315.         CASE ELSE
  316.             Spin_CIntegerSet = ERR_PROPNOTFOUND
  317.     END SELECT
  318.  
  319.     ' Fire Spin event if Value has changed due to
  320.     ' Min or Max property settings.
  321.     IF Ctrl.value > v THEN
  322.         wSpinDir = SPIN_UP
  323.     ELSEIF Ctrl.value < v THEN
  324.         wSpinDir = SPIN_DOWN
  325.     ELSE
  326.         wSpinDir = 0
  327.     END IF
  328.  
  329.     IF wSpinDir > 0 THEN
  330.         ' Invoke CUSTOM event with correct event type.
  331.         ON LOCAL ERROR RESUME NEXT
  332.         ERR = 0
  333.         InvokeEvent wSpinDir, BYVAL ControlID, BYVAL EVENT_Custom
  334.         IF (ERR) THEN MSGBOX "Load: " + ERROR$, 0, "Spin Custom Control Assertion"
  335.     END IF
  336.  
  337. END FUNCTION
  338.  
  339. ' KeyDown event for control.
  340. ' Fires spin events based on key that is pressed.
  341. FUNCTION Spin_CKeyDown (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, keycode AS INTEGER, Shift AS INTEGER) AS INTEGER
  342.     SELECT CASE keycode
  343.     CASE KEY_LEFT, KEY_DOWN
  344.         sSpin_X = 0
  345.         sSpin_Y = 1
  346.         wSpin_Tracking = ControlID
  347.         CALL FireSpin(Ctrl, ControlID, "KEYDOWN")
  348.     CASE KEY_RIGHT, KEY_UP
  349.         sSpin_X = 1
  350.         sSpin_Y = 0
  351.         wSpin_Tracking = ControlID
  352.         CALL FireSpin(Ctrl, ControlID, "KEYDOWN")
  353.     END SELECT
  354. END FUNCTION
  355.  
  356. ' KeyPress event for control.
  357. FUNCTION Spin_CKeyPress (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, KeyAscii AS INTEGER) AS INTEGER
  358.     ' Trap event so not sent to user's code.
  359. END FUNCTION
  360.  
  361. ' KeyDown event for control.
  362. ' Ends spin events.
  363. FUNCTION Spin_CKeyUp (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, keycode AS INTEGER, Shift AS INTEGER) AS INTEGER
  364.     wSpin_Tracking = FALSE
  365. END FUNCTION
  366.  
  367. ' Load event for control.
  368. ' Sets default property values at control load time.
  369. FUNCTION Spin_CLoad (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  370.     DIM Min AS INTEGER
  371.     DIM Max AS INTEGER
  372.     DIM v AS INTEGER
  373.     DIM wSpinDir AS INTEGER
  374.  
  375.     ' Set run-time borderstyle (none).
  376.     SetIntProperty 0, ControlID, PROP_BorderStyle
  377.  
  378.     ' Set control width and height based on style (horizontal or vertical).
  379.     IF (Ctrl.Style = 1) THEN
  380.         SetIntProperty 1, ControlID, PROP_Height
  381.         SetIntProperty 2, ControlID, PROP_Width
  382.     ELSE
  383.         SetIntProperty 1, ControlID, PROP_Width
  384.         SetIntProperty 2, ControlID, PROP_Height
  385.         SetIntProperty 0, ControlID, PROP_Style
  386.     END IF
  387.  
  388.     Min = Ctrl.Min
  389.     Max = Ctrl.Max
  390.     v = Ctrl.value
  391.  
  392.     ' Set default max value.
  393.     IF Max = 0 THEN SetIntProperty 32767, ControlID, PROP_Max
  394.  
  395.     ' Set value property based on min and max.
  396.     IF v < Min AND Min < Max THEN
  397.         SetIntProperty Min, ControlID, PROP_Value
  398.     ELSEIF v > Max AND Min < Max THEN
  399.         SetIntProperty Max, ControlID, PROP_Value
  400.     ELSEIF v < Max AND Max < Min THEN
  401.         SetIntProperty Max, ControlID, PROP_Value
  402.     ELSEIF v > Min AND Max < Min THEN
  403.         SetIntProperty Min, ControlID, PROP_Value
  404.     END IF
  405.  
  406.     ' Set default interval value.
  407.     IF Ctrl.Interval = 0 THEN SetLongProperty 100, ControlID, PROP_Interval
  408.  
  409.     ' Fire Spin event if Value has changed due to
  410.     ' Min or Max property settings.
  411.     IF Ctrl.value > v THEN
  412.         wSpinDir = SPIN_UP
  413.     ELSEIF Ctrl.value < v THEN
  414.         wSpinDir = SPIN_DOWN
  415.     ELSE
  416.         wSpinDir = 0
  417.     END IF
  418.  
  419.     IF wSpinDir > 0 THEN
  420.         ' Invoke CUSTOM event with correct event type.
  421.         ON LOCAL ERROR RESUME NEXT
  422.         ERR = 0
  423.         InvokeEvent wSpinDir, BYVAL ControlID, BYVAL EVENT_Custom
  424.         IF (ERR) THEN MSGBOX "Load: " + ERROR$, 0, "Spin Custom Control Assertion"
  425.     END IF
  426. END FUNCTION
  427.  
  428. ' LostFocus event for control.
  429. ' Turns off blinking cursor to show no focus.
  430. FUNCTION Spin_CLostFocus (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  431.     SetAttribute ControlID, ATTR_TextCursor, TC_NoCursor
  432. END FUNCTION
  433.  
  434. ' MouseDown event for control.
  435. ' Fires spin events based on cursor location.
  436. FUNCTION Spin_CMouseDown (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, Button AS INTEGER, Shift AS INTEGER, X AS SINGLE, Y AS SINGLE) AS INTEGER
  437.     DIM w AS INTEGER
  438.     DIM h AS INTEGER
  439.     DIM wSpinDir%
  440.  
  441.     ' Store current cursor location and mouse state.
  442.     sSpin_X = X
  443.     sSpin_Y = Y
  444.     wSpin_ButtonDown = TRUE
  445.     wSpin_Tracking = ControlID
  446.  
  447.     ' Fire spin event.
  448.     CALL FireSpin(Ctrl, ControlID, "MOUSEDOWN")
  449. END FUNCTION
  450.  
  451. ' MouseMove event for control.
  452. ' Fires spin events based on cursor location.
  453. FUNCTION Spin_CMouseMove (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, Button AS INTEGER, Shift AS INTEGER, X AS SINGLE, Y AS SINGLE) AS INTEGER
  454.     ' Store current cursor location and mouse state.
  455.     sSpin_X = X
  456.     sSpin_Y = Y
  457.  
  458.     ' If mouse button is still down, update tracking information.
  459.     IF (wSpin_ButtonDown) THEN
  460.         IF ((X >= 0) AND (X < Ctrl.Width)) THEN
  461.             IF ((Y >= 0) AND (Y < Ctrl.Height)) THEN
  462.                 wSpin_Tracking = ControlID
  463.             ELSE
  464.                 wSpin_Tracking = FALSE
  465.             END IF
  466.         ELSE
  467.             wSpin_Tracking = FALSE
  468.         END IF
  469.     END IF
  470. END FUNCTION
  471.  
  472. ' MouseUp event for control.
  473. ' Ends spin events.
  474. FUNCTION Spin_CMouseUp (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, Button AS INTEGER, Shift AS INTEGER, X AS SINGLE, Y AS SINGLE) AS INTEGER
  475.     ' Store current cursor location and mouse state.
  476.     sSpin_X = X
  477.     sSpin_Y = Y
  478.     wSpin_ButtonDown = FALSE
  479.     wSpin_Tracking = FALSE
  480. END FUNCTION
  481.  
  482. ' Method trap - returns error if attempt to use unsupported methods.
  483. FUNCTION Spin_CMthAddItem (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, value AS STRING, BYVAL Index AS INTEGER) AS INTEGER
  484.     Spin_CMthAddItem = ERR_METHNOTAPPLICABLE
  485. END FUNCTION
  486.  
  487. ' Method trap - returns error if attempt to use unsupported methods.
  488. FUNCTION Spin_CMthCls (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  489.     Spin_CMthCls = ERR_METHNOTAPPLICABLE
  490. END FUNCTION
  491.  
  492. ' Method trap - returns error if attempt to use unsupported methods.
  493. FUNCTION Spin_CMthHide (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  494.     Spin_CMthHide = ERR_METHNOTAPPLICABLE
  495. END FUNCTION
  496.  
  497. ' Move method trap.
  498. ' Traps attempts to size control via Move method
  499. ' as control size is read-only at run-time.
  500. FUNCTION Spin_CMthMove (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, BYVAL pLeft AS INTEGER, BYVAL pTop AS INTEGER, BYVAL pWidth AS INTEGER, BYVAL pHeight AS INTEGER) AS INTEGER
  501.     ' Can't size control.
  502.     IF (Count > 2) THEN
  503.         Spin_CMthMove = ERR_PROPERTYRO
  504.     ' Move control.
  505.     ELSE
  506.         ERR = 0
  507.         ON LOCAL ERROR RESUME NEXT
  508.         Ctrl.Left = pLeft
  509.         IF (ERR) THEN
  510.             Spin_CMthMove = ERR
  511.             EXIT FUNCTION
  512.         END IF
  513.  
  514.         ERR = 0
  515.         Ctrl.Top = pTop
  516.         IF (ERR) THEN
  517.             Spin_CMthMove = ERR
  518.             EXIT FUNCTION
  519.         END IF
  520.  
  521.         Spin_CMthMove = Spin_CPaint(Ctrl, ControlID)
  522.     END IF
  523. END FUNCTION
  524.  
  525. ' Method trap - returns error if attempt to use unsupported methods.
  526. FUNCTION Spin_CMthPrint (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  527.     Spin_CMthPrint = ERR_METHNOTAPPLICABLE
  528. END FUNCTION
  529.  
  530. ' Method trap - returns error if attempt to use unsupported methods.
  531. FUNCTION Spin_CMthRemoveItem (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, BYVAL Index AS INTEGER) AS INTEGER
  532.     Spin_CMthRemoveItem = ERR_METHNOTAPPLICABLE
  533. END FUNCTION
  534.  
  535. ' Method trap - returns error if attempt to use unsupported methods.
  536. FUNCTION Spin_CMthShow (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL Count AS INTEGER, BYVAL Modal AS INTEGER) AS INTEGER
  537.     Spin_CMthShow = ERR_METHNOTAPPLICABLE
  538. END FUNCTION
  539.  
  540. ' Paint event for control.
  541. ' Displays spin control based on control style.
  542. FUNCTION Spin_CPaint (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  543.     DIM w AS INTEGER
  544.     DIM h AS INTEGER
  545.     DIM X AS INTEGER
  546.     DIM Y AS INTEGER
  547.     DIM f AS INTEGER
  548.     DIM b AS INTEGER
  549.     DIM S$
  550.  
  551.     f = Ctrl.ForeColor
  552.     b = Ctrl.BackColor
  553.  
  554.     w = Ctrl.Width \ 2
  555.     h = Ctrl.Height \ 2
  556.  
  557.     ' Draw horizontal spin control.
  558.     IF Ctrl.Style = 1 THEN
  559.         InvokeMethod BYVAL 0, BYVAL 0, BYVAL f, BYVAL b, CHR$(17), BYVAL 5, BYVAL ControlID, BYVAL METHOD_Print
  560.         X = Ctrl.Width - 1
  561.         InvokeMethod BYVAL X, BYVAL 0, BYVAL f, BYVAL b, CHR$(16), BYVAL 5, BYVAL ControlID, BYVAL METHOD_Print
  562.     ' Draw vertical spin control.
  563.     ELSE
  564.         X = 0
  565.         Y = 0
  566.         S$ = CHR$(30)
  567.         InvokeMethod BYVAL X, BYVAL Y, BYVAL f, BYVAL b, S$, BYVAL 5, BYVAL ControlID, BYVAL METHOD_Print
  568.         X = 0
  569.         Y = Ctrl.Height - 1
  570.         S$ = CHR$(31)
  571.         InvokeMethod BYVAL X, BYVAL Y, BYVAL f, BYVAL b, S$, BYVAL 5, BYVAL ControlID, BYVAL METHOD_Print
  572.     END IF
  573. END FUNCTION
  574.  
  575. ' String property get event for control.
  576. ' Allows value retrieval for supported properties.
  577. FUNCTION Spin_CStringGet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, value AS STRING, Index AS INTEGER) AS INTEGER
  578.         ' Only Tag string property is supported.
  579.         IF (PropertyId <> PROP_Tag) THEN
  580.             Spin_CStringGet = ERR_PROPNOTFOUND
  581.         END IF
  582. END FUNCTION
  583.  
  584. ' String property set event for control.
  585. ' Allows tag property value to be set.
  586. FUNCTION Spin_CStringSet (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER, BYVAL PropertyId AS INTEGER, value AS STRING, Index AS INTEGER) AS INTEGER
  587.         ' Only Tag string property is supported.
  588.         IF PropertyId = PROP_Tag THEN
  589.             SetStringProperty value, ControlID, PROP_Tag
  590.         ELSE
  591.             Spin_CStringSet = ERR_PROPNOTFOUND
  592.         END IF
  593. END FUNCTION
  594.  
  595. ' Timer event for control.
  596. ' Allows continuous firing of spin control provided mouse
  597. ' or key is down.
  598. FUNCTION Spin_CTimer (Ctrl AS CONTROL, BYVAL ControlID AS INTEGER) AS INTEGER
  599.     IF (wSpin_Tracking = ControlID) THEN
  600.         CALL FireSpin(Ctrl, ControlID, "TIMER")
  601.     END IF
  602. END FUNCTION
  603.  
  604.