* Original author: Tyson Bonn * Example: PUBLIC RainMaker RainMaker = NewObject("RainMaker", "Rain.PRG") RainMaker.Rain(_SCREEN) * RainMaker.Release() ********************************************* DEFINE CLASS RainMaker AS Relation Timer = .NULL. Form = .NULL. && Object where you want it to rain. ********************************** PROCEDURE Rain(Form) This.Form = IIF(VARTYPE(m.Form)=="O", m.Form, _SCREEN) This.Timer = NEWOBJECT("GenericTimer", "Rain.PRG") This.Timer.Interval = 30 This.Timer.oParent = This This.Timer.Do("This.oParent", "RainDrop()") ENDPROC ********************************** PROCEDURE RainDrop LOCAL Name Name = Sys(2015) This.Form.NewObject(m.Name, "Sprite", "Rain.PRG") This.Timer.Enabled = .T. ENDPROC ********************************** PROCEDURE Release() This.Timer.Release() This.Form.Cls() ENDPROC ENDDEFINE ********************************************* DEFINE CLASS Sprite AS Line xCoordinate = 0 yCoordinate = 0 Size = 1 Color = 0 Max = 75 Increment = 5 Timer = .NULL. ********************************** PROCEDURE Init() This.Timer = NEWOBJECT("GenericTimer", "Rain.PRG") This.Timer.Interval = 50 This.Timer.oParent = This This.Timer.Do("This.oParent", "Show()") This.xCoordinate = RAND() * This.Parent.Width This.yCoordinate = RAND() * This.Parent.Height ENDPROC ********************************** PROCEDURE Show() WITH This.Parent This.Size = m.this.Size + m.this.Increment IF m.this.Size < m.this.Max - m.this.Increment * 2 THEN .ForeColor = RGB(0, 0, 0) .Circle(m.this.Size, m.this.xCoordinate, m.this.yCoordinate, .5) ENDIF IF m.this.Size > m.this.Increment and m.this.Size < m.this.Max - m.this.Increment THEN .ForeColor = RGB(128, 128, 128) .Circle(m.this.Size - m.this.Increment, m.this.xCoordinate, m.this.yCoordinate, .5) ENDIF IF m.this.Size > m.this.Increment * 2 THEN .ForeColor = .BackColor .Circle(m.this.Size - m.this.Increment * 2, m.this.xCoordinate, m.this.yCoordinate, .5) ENDIF ENDWITH IF This.Size >= This.Max THEN This.Release() ELSE This.Timer.Enabled = .T. ENDIF ENDPROC ********************************** PROCEDURE Release This.Timer.Release() RELEASE This ENDPROC ENDDEFINE ************************************************** DEFINE CLASS GenericTimer AS Timer Enabled = .F. Interval = 100 *-- Object Name whose method to call when the Timer Event occurs. objectname = "" *-- Character. Name of the Method to call when the TimeOut Event occurs. methodname = "" *-- Object reference for the creator of the object. oParent = .NULL. Name = "generictimer" *-- This method starts the timer. Pass an object, and the method to call. ie. Do(ThisApp, "Release()'). PROCEDURE do LPARAMETER ObjectName, MethodName, Interval ASSERT VARTYPE(m.ObjectName) = "C" AND NOT EMPTY(m.ObjectName) ; MESSAGE "You must pass the Object Name which contains the Method you wish to call." This.ObjectName = m.ObjectName * First parameter may be ObjectName or a command. IF VARTYPE(m.MethodName) = "N" AND NOT EMPTY(m.MethodName) This.Interval = m.MethodName ELSE IF VARTYPE(m.Interval) = "N" AND NOT EMPTY(m.Interval) This.Interval = m.Interval ENDIF IF NOT EMPTY(m.MethodName) This.MethodName = m.MethodName + IIF("(" $ m.MethodName, '', "()") ENDIF ENDIF This.Reset() This.Enabled = .T. RETURN ENDPROC *-- About this Class. PROCEDURE readme #IF .F. Use this object to call methods where the call stack can get in the way of Release(), or similar situations. Pass the full Object name (with it's hierarchy). Pass the Method you wish to do. or Pass the Command you wish to run and the milliseconds. If desired, pass the number of milliseconds to wait before running that method. Default is .1 secords, or you can change the interval prior to issuing Do(). Example: oTimer = NEWOBJECT("GenericTimer", "Handler.VCX") oTimer.Interval = 1000 oTimer.Do("_SCREEN.x", "SetFocus()") or oTimer = NEWOBJECT("GenericTimer", "Handler.VCX") oTimer.Do("ThisApp", "Release()", 100) or oTimer = NEWOBJECT("GenericTimer", "Handler.VCX") oTimer.oParent = This oTimer.Do("This.oParent", "Release()", 100) or oTimer.Do("WAIT WINDOW TTOC(DATETIME()) NOWAIT" #ENDIF ENDPROC PROCEDURE Reset *Started = SECONDS() *DEBUGOUT ' Current SECONDS():' + TRANSFORM(SECONDS()) ENDPROC PROCEDURE release This.oParent = .NULL. DODEFAULT() ENDPROC PROCEDURE Timer LOCAL Command IF VARTYPE(_SCREEN._Timer) = "L" AND NOT _SCREEN._Timer * Allow user to turn off the timer by doing _SCREEN.AddProperty("_Timer", .F.) ELSE This.Enabled = .F. && Shut down the Timer if we're ready to run && the designated method. IF EMPTY(This.MethodName) OR VARTYPE(This.MethodName) = "N" Command = This.ObjectName &Command. RETURN ELSE IF TYPE(This.ObjectName)=="O" AND NOT ISNULL(EVALUATE(This.ObjectName)) RETURN EVALUATE(This.ObjectName + "." + This.MethodName) ENDIF ENDIF ENDIF ENDPROC *-- Polymorphic method. PROCEDURE refresh ENDPROC ENDDEFINE>Hi,