*-------------------------------------------------------------------------------------------------------------------------------------------------------- * (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!! *-------------------------------------------------------------------------------------------------------------------------------------------------------- *< FOXBIN2PRG: Version="1.21" SourceFile="sfsplitter.vcx" CPID="1252" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries) * * DEFINE CLASS gripper AS container *< CLASSDATA: Baseclass="container" Timestamp="" Scale="Pixels" Uniqueid="" /> *-- OBJECTDATA items order determines ZOrder / El orden de los items OBJECTDATA determina el ZOrder *< OBJECTDATA: ObjPath="GripperDot1" UniqueID="" Timestamp="" /> *< OBJECTDATA: ObjPath="GripperDot2" UniqueID="" Timestamp="" /> *< OBJECTDATA: ObjPath="GripperDot3" UniqueID="" Timestamp="" /> *< OBJECTDATA: ObjPath="GripperDot4" UniqueID="" Timestamp="" /> *< OBJECTDATA: ObjPath="GripperDot5" UniqueID="" Timestamp="" /> * *m: repositiononresize && A method to move the gripper to keep it centererd in the Splitter when the hosting form is resized. *m: setupforhorizontalsplitter && A method to set the positions of the dots to a vertical orientation. *m: setupforverticalsplitter && A method to set the positions of the dots to a horizontal orientation. *m: setupgripper && The setup method to positiosn the dots according to the orientation of the splitter, also sets up the number of dots. *p: ndots && Enter a number from 0 to 5 to indicate how many gripper dots to show. Enter 0 for none. *p: _memberdata && XML Metadata for customizable properties * * BackStyle = 0 BorderWidth = 0 Height = 19 Name = "gripper" ndots = 5 Width = 36 _memberdata = * ADD OBJECT 'GripperDot1' AS gripperdot WITH ; Left = 2, ; Name = "GripperDot1", ; Top = 4, ; ShapeDark.BackStyle = 0, ; ShapeDark.Name = "ShapeDark", ; ShapeDark.ZOrderSet = 0, ; ShapeLight.Name = "ShapeLight", ; ShapeLight.ZOrderSet = 1, ; ShapeMiddle.Name = "ShapeMiddle", ; ShapeMiddle.ZOrderSet = 2 *< END OBJECT: ClassLib="sfsplitter.vcx" BaseClass="container" /> ADD OBJECT 'GripperDot2' AS gripperdot WITH ; Left = 6, ; Name = "GripperDot2", ; Top = 4, ; ShapeDark.BackStyle = 0, ; ShapeDark.Name = "ShapeDark", ; ShapeDark.ZOrderSet = 0, ; ShapeLight.Name = "ShapeLight", ; ShapeLight.ZOrderSet = 1, ; ShapeMiddle.Name = "ShapeMiddle", ; ShapeMiddle.ZOrderSet = 2 *< END OBJECT: ClassLib="sfsplitter.vcx" BaseClass="container" /> ADD OBJECT 'GripperDot3' AS gripperdot WITH ; Left = 10, ; Name = "GripperDot3", ; Top = 4, ; ShapeDark.BackStyle = 0, ; ShapeDark.Name = "ShapeDark", ; ShapeDark.ZOrderSet = 0, ; ShapeLight.Name = "ShapeLight", ; ShapeLight.ZOrderSet = 1, ; ShapeMiddle.Name = "ShapeMiddle", ; ShapeMiddle.ZOrderSet = 2 *< END OBJECT: ClassLib="sfsplitter.vcx" BaseClass="container" /> ADD OBJECT 'GripperDot4' AS gripperdot WITH ; Left = 14, ; Name = "GripperDot4", ; Top = 4, ; ShapeDark.BackStyle = 0, ; ShapeDark.Name = "ShapeDark", ; ShapeDark.ZOrderSet = 0, ; ShapeLight.Name = "ShapeLight", ; ShapeLight.ZOrderSet = 1, ; ShapeMiddle.Name = "ShapeMiddle", ; ShapeMiddle.ZOrderSet = 2 *< END OBJECT: ClassLib="sfsplitter.vcx" BaseClass="container" /> ADD OBJECT 'GripperDot5' AS gripperdot WITH ; Left = 18, ; Name = "GripperDot5", ; Top = 4, ; ShapeDark.BackStyle = 0, ; ShapeDark.Name = "ShapeDark", ; ShapeDark.ZOrderSet = 0, ; ShapeLight.Name = "ShapeLight", ; ShapeLight.ZOrderSet = 1, ; ShapeMiddle.Name = "ShapeMiddle", ; ShapeMiddle.ZOrderSet = 2 *< END OBJECT: ClassLib="sfsplitter.vcx" BaseClass="container" /> PROCEDURE Init *-- Get MousePointer setting from parent Splitter this.MousePointer=this.Parent.MousePointer *-- Also, set the MousePointer on each shape in each GripperDot container FOR EACH GripperDot in this.Controls GripperDot.setall('MousePointer', this.MousePointer) EndFor this.SetupGripper() Dodefault() ENDPROC PROCEDURE MouseMove LPARAMETERS nButton, nShift, nXCoord, nYCoord this.parent.MouseMove(nButton, nShift, nXCoord, nYCoord) ENDPROC PROCEDURE repositiononresize && A method to move the gripper to keep it centererd in the Splitter when the hosting form is resized. *-- This method will keep the Gripper container centered when the hosting form is resized. *-- For vertical splitter, we will set the Left of the Gripper container to center it horizontally *-- For horizontal splitter, we will set the Top of the Gripper container to center it vertically. If this.parent.Width>this.parent.Height With this .Anchor=0 .Left=(this.parent.Width-.Width)/2 .Anchor=10 Endwith Else With this .Anchor=0 .top=(this.parent.Height-.height)/2 .Anchor=5 Endwith Endif ENDPROC PROCEDURE setupforhorizontalsplitter && A method to set the positions of the dots to a vertical orientation. *-- A method that will position the dots in a vertical orientation to be used on a horizontal splitter. lnDotHeight=this.GripperDot1.Height this.GripperDot1.Left=2 this.GripperDot1.Top=1 this.GripperDot2.Left=2 this.GripperDot2.Top=1+lnDotHeight this.GripperDot3.Left=2 this.GripperDot3.Top=1+2*lnDotHeight this.GripperDot4.Left=2 this.GripperDot4.Top=1+3*lnDotHeight this.GripperDot5.Left=2 this.GripperDot5.Top=1+4*lnDotHeight With this .Anchor=0 .Height=this.nDots*lnDotHeight && This will cause the container to only show the correct number of dots. .Width=lnDotHeight+1 .Anchor=5 EndWith ENDPROC PROCEDURE setupforverticalsplitter && A method to set the positions of the dots to a horizontal orientation. *-- A method that will position the dots in a horizontal orientation to be used on a vertical splitter. lnDotWidth=this.GripperDot1.Width this.GripperDot1.Left=1 this.GripperDot1.Top=2 this.GripperDot2.Left=1+lnDotWidth this.GripperDot2.Top=2 this.GripperDot3.Left=1+2*lnDotWidth this.GripperDot3.Top=2 this.GripperDot4.Left=1+3*lnDotWidth this.GripperDot4.Top=2 this.GripperDot5.Left=1+4*lnDotWidth this.GripperDot5.Top=2 With this .Anchor=0 .Width=this.nDots*this.GripperDot1.Width+1 && This will cause the container to only show the correct number of dots. .Height=lnDotWidth+1 .Anchor=10 Endwith ENDPROC PROCEDURE setupgripper && The setup method to positiosn the dots according to the orientation of the splitter, also sets up the number of dots. *-- 2009-01-04 By Matt Slay *-- This sets the fixed positions that do no change when the form is resized. *-- For vertical splitter, we will set the Top of the Gripper container to center it vertically. *-- For horizontal splitter, we will set the Left of the Gripper container to center it horiziontally. *-- This method only needs to be called once. If this.parent.Width>this.parent.Height With this .SetupForVerticalSplitter() .Anchor= 0 .top=(this.parent.Height-.height)/2-1 .Anchor=10 Endwith Else With this .SetupForHorizontalSplitter() .Anchor=0 .left=(this.parent.Width-.width)/2-1 .Anchor=5 Endwith Endif this.RepositionOnResize() ENDPROC ENDDEFINE DEFINE CLASS gripperdot AS container *< CLASSDATA: Baseclass="container" Timestamp="" Scale="Pixels" Uniqueid="" /> *-- OBJECTDATA items order determines ZOrder / El orden de los items OBJECTDATA determina el ZOrder *< OBJECTDATA: ObjPath="ShapeDark" UniqueID="" Timestamp="" /> *< OBJECTDATA: ObjPath="ShapeLight" UniqueID="" Timestamp="" /> *< OBJECTDATA: ObjPath="ShapeMiddle" UniqueID="" Timestamp="" /> * BackStyle = 0 BorderWidth = 0 Height = 4 Name = "gripperdot" Width = 4 * ADD OBJECT 'ShapeDark' AS shape WITH ; BackStyle = 1, ; BorderStyle = 0, ; BorderWidth = 0, ; FillColor = 80,80,80, ; FillStyle = 0, ; Height = 2, ; Left = 1, ; Name = "ShapeDark", ; Top = 1, ; Width = 2 *< END OBJECT: BaseClass="shape" /> ADD OBJECT 'ShapeLight' AS shape WITH ; BackStyle = 1, ; BorderStyle = 0, ; BorderWidth = 0, ; FillColor = 250,250,250, ; FillStyle = 0, ; Height = 2, ; Left = 2, ; Name = "ShapeLight", ; Top = 2, ; Width = 2 *< END OBJECT: BaseClass="shape" /> ADD OBJECT 'ShapeMiddle' AS shape WITH ; BackStyle = 1, ; BorderStyle = 0, ; BorderWidth = 0, ; FillColor = 173,209,255, ; FillStyle = 0, ; Height = 1, ; Left = 2, ; Name = "ShapeMiddle", ; Top = 2, ; Width = 1 *< END OBJECT: BaseClass="shape" /> PROCEDURE Init this.MousePointer=this.Parent.Parent.MousePointer this.SetAll('MousePointer', this.MousePointer, 'Shape') ENDPROC PROCEDURE MouseMove LPARAMETERS nButton, nShift, nXCoord, nYCoord this.parent.MouseMove(nButton, nShift, nXCoord, nYCoord) ENDPROC PROCEDURE ShapeDark.MouseMove LPARAMETERS nButton, nShift, nXCoord, nYCoord this.parent.MouseMove(nButton, nShift, nXCoord, nYCoord) ENDPROC PROCEDURE ShapeLight.MouseMove LPARAMETERS nButton, nShift, nXCoord, nYCoord this.parent.MouseMove(nButton, nShift, nXCoord, nYCoord) ENDPROC PROCEDURE ShapeMiddle.MouseMove LPARAMETERS nButton, nShift, nXCoord, nYCoord this.parent.MouseMove(nButton, nShift, nXCoord, nYCoord) ENDPROC ENDDEFINE DEFINE CLASS sfsplitter AS control *< CLASSDATA: Baseclass="control" Timestamp="" Scale="Pixels" Uniqueid="" /> *-- OBJECTDATA items order determines ZOrder / El orden de los items OBJECTDATA determina el ZOrder *< OBJECTDATA: ObjPath="Gripper" UniqueID="" Timestamp="" /> * *m: getobject1size && Gets the size for Object 1 *m: getobject2size && Gets the size for Object 2 *m: getobjectnames && Populates an array from a comma-delimited list *m: getposition && Returns the new position: X for a horizontal splitter and Y for a vertical splitter *m: moveobject1 && Moves Object 1 to the new position *m: moveobject2 && Moves Object 2 to the new position *m: movesplittertoposition && Moves the splitter to the specified position *m: setposition && Sets the new position for the splitter *m: setupgripper && A method to setup various properties on the gripper to visually configure it for Vertical or Horizontal configuration. *m: splittermoved && Called after the splitter is moved *p: cobject1name && The name of the object above (for a vertical splitter) or to the left of (for a horizontal splitter) the splitter *p: cobject2name && The name of the object below (for a vertical splitter) or to the right of (for a horizontal splitter) the splitter *p: linitialized && .T. after the control has been initialized *p: ndots && Enter a value between 0 and 5 for the number of dots to be shown on the gripper. Enter 0 for none. *p: nobject1minsize && The minimum height (for a vertical splitter) or width (for a horizontal splitter) of Object 1 *p: nobject2minsize && The minimum height (for a vertical splitter) or width (for a horizontal splitter) of Object 2 *p: _memberdata && XML Metadata for customizable properties * * BackColor = 192,192,192 BackStyle = 1 BorderColor = 255,0,0 BorderWidth = 2 cobject1name = cobject2name = Height = 248 linitialized = .F. Name = "sfsplitter" ndots = 5 nobject1minsize = 150 nobject2minsize = 150 Width = 25 _memberdata = * ADD OBJECT 'Gripper' AS gripper WITH ; Height = 12, ; Left = 1, ; Name = "Gripper", ; Top = -1, ; Width = 20, ; Gripperdot1.Name = "Gripperdot1", ; Gripperdot1.ShapeDark.Name = "ShapeDark", ; Gripperdot1.ShapeLight.Name = "ShapeLight", ; Gripperdot1.ShapeMiddle.Name = "ShapeMiddle", ; Gripperdot2.Name = "Gripperdot2", ; Gripperdot2.ShapeDark.Name = "ShapeDark", ; Gripperdot2.ShapeLight.Name = "ShapeLight", ; Gripperdot2.ShapeMiddle.Name = "ShapeMiddle", ; Gripperdot3.Name = "Gripperdot3", ; Gripperdot3.ShapeDark.Name = "ShapeDark", ; Gripperdot3.ShapeLight.Name = "ShapeLight", ; Gripperdot3.ShapeMiddle.Name = "ShapeMiddle", ; Gripperdot4.Name = "Gripperdot4", ; Gripperdot4.ShapeDark.Name = "ShapeDark", ; Gripperdot4.ShapeLight.Name = "ShapeLight", ; Gripperdot4.ShapeMiddle.Name = "ShapeMiddle", ; Gripperdot5.Name = "Gripperdot5", ; Gripperdot5.ShapeDark.Name = "ShapeDark", ; Gripperdot5.ShapeLight.Name = "ShapeLight", ; Gripperdot5.ShapeMiddle.Name = "ShapeMiddle" *< END OBJECT: ClassLib="sfsplitter.vcx" BaseClass="container" /> PROTECTED PROCEDURE getobject1size && Gets the size for Object 1 * Abstract method. lparameters toObject ENDPROC PROTECTED PROCEDURE getobject2size && Gets the size for Object 2 * Abstract method. lparameters toObject ENDPROC PROTECTED PROCEDURE getobjectnames && Populates an array from a comma-delimited list lparameters tcList, ; taArray local lnOccurs, ; lnStart, ; lnI, ; lnPos lnOccurs = occurs(',', tcList) + 1 dimension taArray[lnOccurs] lnStart = 1 for lnI = 1 to lnOccurs if lnI = lnOccurs lnPos = len(tcList) + 1 else lnPos = at(',', tcList, lnI) endif lnI = lnOccurs taArray[lnI] = alltrim(substr(tcList, lnStart, lnPos - lnStart)) lnStart = lnPos + 1 next lnI return lnOccurs ENDPROC PROTECTED PROCEDURE getposition && Returns the new position: X for a horizontal splitter and Y for a vertical splitter * Abstract method. lparameters tnXCoord, ; tnYCoord ENDPROC PROCEDURE Init * Make the border invisible and flag that Init has fired. with This .BorderWidth = 0 .lInitialized = .T. .setupgripper()&& 2008-12-31 By Matt Slay endwith dodefault() *--- Changes by Matt Slay to use Gripper control 2008-12-31 ---- * Added a Gripper container class to the VCX. A container consisting of (5) GripperDots. * Added a GripprDot container class to the VCX. A container with a single "Dot" comprised of (3) VFP Shape objects with color, size, and position to make a cool shaded "dot". * Added an instance of the Gripper object to the Splitter base control. * Added nDots property to the Splitter base control. * Added the SetupGripper() method to the Splitter base control. * Added .SetupGripper() call in the Splitter base control Init() method. * Added this.Gripper.RepositionOnResize() call on the Splitter base control Resize() method to keep the Gripper centered when hosting form or container is resized. ENDPROC PROCEDURE MouseMove lparameters tnButton, ; tnShift, ; tnXCoord, ; tnYCoord local lnPosition with This if tnButton = 1 and .Enabled lnPosition = .GetPosition(tnXCoord, tnYCoord) .MoveSplitterToPosition(lnPosition) endif tnButton = 1 ... endwith ENDPROC PROTECTED PROCEDURE moveobject1 && Moves Object 1 to the new position * Abstract method. lparameters toObject ENDPROC PROTECTED PROCEDURE moveobject2 && Moves Object 2 to the new position * Abstract method. lparameters toObject ENDPROC PROCEDURE movesplittertoposition && Moves the splitter to the specified position * Move the splitter to the specified position. Ensure it doesn't go too far, * based on the nObject1MinSize and nObject2MinSize settings. lparameters tnPosition local lnPosition, ; laObjects[1], ; lnObjects, ; lnI, ; loObject, ; lnAnchor with This lnPosition = tnPosition lnObjects = .GetObjectNames(.cObject1Name, @laObjects) for lnI = 1 to lnObjects loObject = evaluate('.Parent.' + laObjects[lnI]) lnPosition = max(lnPosition, .GetObject1Size(loObject)) next lnI lnObjects = .GetObjectNames(.cObject2Name, @laObjects) for lnI = 1 to lnObjects loObject = evaluate('.Parent.' + laObjects[lnI]) lnPosition = min(lnPosition, .GetObject2Size(loObject)) next lnI lnAnchor = .Anchor .Anchor = 0 .SetPosition(lnPosition) .Anchor = lnAnchor * Now move the left and right objects as well. lnObjects = .GetObjectNames(.cObject1Name, @laObjects) for lnI = 1 to lnObjects loObject = evaluate('.Parent.' + laObjects[lnI]) with loObject lnAnchor = .Anchor .Anchor = 0 This.MoveObject1(loObject) .Anchor = lnAnchor endwith next lnI lnObjects = .GetObjectNames(.cObject2Name, @laObjects) for lnI = 1 to lnObjects loObject = evaluate('.Parent.' + laObjects[lnI]) with loObject lnAnchor = .Anchor .Anchor = 0 This.MoveObject2(loObject) .Anchor = lnAnchor endwith next lnI * Call a hook method. .SplitterMoved() endwith ENDPROC PROCEDURE Resize this.Gripper.RepositionOnResize() && 2008-12-31 Added by Matt Slay to keep Gripper centered when form is resized. Dodefault() ENDPROC PROTECTED PROCEDURE setposition && Sets the new position for the splitter * Abstract method. lparameters tnPosition ENDPROC PROCEDURE setupgripper && A method to setup various properties on the gripper to visually configure it for Vertical or Horizontal configuration. *-- Method added by Matt Slay - 2009-01-04 this.Gripper.nDots=this.nDots this.Gripper.SetupGripper() ENDPROC PROCEDURE splittermoved && Called after the splitter is moved * Abstract method. ENDPROC ENDDEFINE DEFINE CLASS sfsplitterh AS sfsplitter OF "sfsplitter.vcx" *< CLASSDATA: Baseclass="control" Timestamp="" Scale="Pixels" Uniqueid="" /> * Anchor = 13 MousePointer = 9 Name = "sfsplitterh" gripper.Gripperdot1.Name = "Gripperdot1" gripper.Gripperdot1.ShapeDark.Name = "ShapeDark" gripper.Gripperdot1.ShapeLight.Name = "ShapeLight" gripper.Gripperdot1.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot2.Name = "Gripperdot2" gripper.Gripperdot2.ShapeDark.Name = "ShapeDark" gripper.Gripperdot2.ShapeLight.Name = "ShapeLight" gripper.Gripperdot2.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot3.Name = "Gripperdot3" gripper.Gripperdot3.ShapeDark.Name = "ShapeDark" gripper.Gripperdot3.ShapeLight.Name = "ShapeLight" gripper.Gripperdot3.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot4.Name = "Gripperdot4" gripper.Gripperdot4.ShapeDark.Name = "ShapeDark" gripper.Gripperdot4.ShapeLight.Name = "ShapeLight" gripper.Gripperdot4.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot5.Name = "Gripperdot5" gripper.Gripperdot5.ShapeDark.Name = "ShapeDark" gripper.Gripperdot5.ShapeLight.Name = "ShapeLight" gripper.Gripperdot5.ShapeMiddle.Name = "ShapeMiddle" gripper.Name = "gripper" * PROCEDURE getobject1size && Gets the size for Object 1 lparameters toObject return toObject.Left + This.nObject1MinSize ENDPROC PROCEDURE getobject2size && Gets the size for Object 2 lparameters toObject return toObject.Left + toObject.Width - This.nObject2MinSize - This.Width ENDPROC PROCEDURE getposition && Returns the new position: X for a horizontal splitter and Y for a vertical splitter lparameters tnXCoord, ; tnYCoord return tnXCoord + This.Left - Objtoclient(this,2) ENDPROC PROCEDURE moveobject1 && Moves Object 1 to the new position lparameters toObject with toObject .Move(.Left, .Top, This.Left - .Left, .Height) endwith ENDPROC PROCEDURE moveobject2 && Moves Object 2 to the new position lparameters toObject with toObject .Move(This.Left + This.Width, .Top, max(.Width + .Left - This.Left - ; This.Width, 0), .Height) endwith ENDPROC PROCEDURE setposition && Sets the new position for the splitter lparameters tnPosition This.Left = tnPosition ENDPROC ENDDEFINE DEFINE CLASS sfsplitterv AS sfsplitter OF "sfsplitter.vcx" *< CLASSDATA: Baseclass="control" Timestamp="" Scale="Pixels" Uniqueid="" /> * Anchor = 14 Height = 10 MousePointer = 7 Name = "sfsplitterv" Width = 200 gripper.Gripperdot1.Name = "Gripperdot1" gripper.Gripperdot1.ShapeDark.Name = "ShapeDark" gripper.Gripperdot1.ShapeLight.Name = "ShapeLight" gripper.Gripperdot1.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot2.Name = "Gripperdot2" gripper.Gripperdot2.ShapeDark.Name = "ShapeDark" gripper.Gripperdot2.ShapeLight.Name = "ShapeLight" gripper.Gripperdot2.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot3.Name = "Gripperdot3" gripper.Gripperdot3.ShapeDark.Name = "ShapeDark" gripper.Gripperdot3.ShapeLight.Name = "ShapeLight" gripper.Gripperdot3.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot4.Name = "Gripperdot4" gripper.Gripperdot4.ShapeDark.Name = "ShapeDark" gripper.Gripperdot4.ShapeLight.Name = "ShapeLight" gripper.Gripperdot4.ShapeMiddle.Name = "ShapeMiddle" gripper.Gripperdot5.Name = "Gripperdot5" gripper.Gripperdot5.ShapeDark.Name = "ShapeDark" gripper.Gripperdot5.ShapeLight.Name = "ShapeLight" gripper.Gripperdot5.ShapeMiddle.Name = "ShapeMiddle" gripper.Name = "gripper" * PROCEDURE getobject1size && Gets the size for Object 1 lparameters toObject return toObject.Top + This.nObject1MinSize ENDPROC PROCEDURE getobject2size && Gets the size for Object 2 lparameters toObject return toObject.Top + toObject.Height - This.nObject2MinSize - This.Height ENDPROC PROCEDURE getposition && Returns the new position: X for a horizontal splitter and Y for a vertical splitter lparameters tnXCoord, ; tnYCoord return tnYCoord + This.Top - Objtoclient(this,1) ENDPROC PROCEDURE moveobject1 && Moves Object 1 to the new position lparameters toObject with toObject .Move(.Left, .Top, .Width, This.Top - .Top) endwith ENDPROC PROCEDURE moveobject2 && Moves Object 2 to the new position lparameters toObject with toObject .Move(.Left, This.Top + This.Height, .Width, max(.Height + .Top - This.Top - ; This.Height, 0)) endwith ENDPROC PROCEDURE setposition && Sets the new position for the splitter lparameters tnPosition This.Top = tnPosition ENDPROC ENDDEFINE