A number of other languages have a splitter control of some sort, why not Visual FoxPro? To be fair, I have seen some splitter classes floating around from time to time, but I thought I'd try my hand at it. I was convinced it couldn't be too difficult, and Visual FoxPro didn't disappoint me. Below is a download link for the class library that I placed my splitter class in (based on shape) and an example form showing how the class is used (I've taken a screen shot of it so you can see what it looks like). Now, if you want to try the splitter class out before you go to the trouble of downloading it, I've also created a cut-n-paste/execute example that you'll find directly beneath the screen shot. This splitter control is designed to work with Visual FoxPro 9.0. If you are using a previous version then you will need to modify/delete a few things.
Download Splitter.vcx and Form Example (8 KB approx.)
*!* Cut-N-Paste the code below into a prg file and execute it to see and try out a working example of the splitter class
PUBLIC oform1
oform1=NEWOBJECT("form1")oform1.ShowRETURN
************************************DEFINE CLASS form1 AS form************************************
DoCreate = .T. Caption = "Splitter Example" Name = "Form1" MDIForm = .T. Autocenter = .T. ADD OBJECT text1 AS textbox WITH ; Anchor = 11, ; Height = 29, ; Left = 0, ; Top = 0, ; Width = 375, ; Name = "Text1"
ADD OBJECT edit1 AS editbox WITH ; Anchor = 7, ; Height = 217, ; Left = 0, ; Top = 33, ; Width = 184, ; Name = "Edit1"
ADD OBJECT edit2 AS editbox WITH ; Anchor = 15, ; Height = 217, ; Left = 188, ; Top = 33, ; Width = 187, ; Name = "Edit2"
ADD OBJECT splitter1 AS splitter WITH ; Top = 32, ; Left = 183, ; Height = 219, ; Width = 6, ; Anchor = 7, ; Name = "Splitter1"
ADD OBJECT splitter2 AS splitter WITH ; Top = 28, ; Left = 0, ; Height = 6, ; Width = 376, ; Anchor = 10, ; vertical = .F., ; minimumsize = 29, ; Name = "Splitter2"
PROCEDURE Init This.text1.Value = "Visual FoxPro Rocks!" This.Edit1.Value = "Visual FoxPro is an extremely versatile development tool. " + ; "Not only does it allow a developer to create great datacentric applications, " + ; "it also allows the developer to extend the actual language with new classes, " + ; "code libraries, and hooks. If you're an avid Visual FoxPro developer like myself " + ; "then good for you. And, if you're not, then I encourage you to give Visual FoxPro " + ; "a try. You won't regret it" This.Edit2.Value = "This is an example of a splitter class for use in Visual FoxPro 9.0 forms. " + ; "It is pure Visual FoxPro, so there aren't any additional ActiveX or DLL dependencies " + ; "to worry about when distributing your application. To see it in action move the " + ; "horizontal and vertical splitters around on this form. Also, by resizing the form you " + ; "can see that it handles the new Visual FoxPro 9.0 Anchors property with aplomb." ENDPROC
ENDDEFINE
************************************DEFINE CLASS splitter AS shape************************************ Height = 182 Width = 8 MousePointer = 9 SpecialEffect = 0 Style = 0 mousedownat = 0 && Tracks mouse and allows class to ignore moves caused by resizing form vertical = .T. && Set to .F. for horizontal splitter minimumsize = 40 && This is how small (in pixels) the panels can get when moving the splitter Name = "splitter"
PROCEDURE MouseLeave LPARAMETERS nButton, nShift, nXCoord, nYCoord This.mousedownat = 0 ENDPROC
PROCEDURE Move LPARAMETERS nLeft, nTop, nWidth, nHeight *!* If you want to move the splitter during runtime and have it move the other controls *!* then set mousedownat != 0 and call this move method of the splitter *!* remember to set mousedownat back to 0 when you are done moving the splitter
LOCAL loControl, llLockScreenWas, lnMovement, llIsSplitter, lcUniqueTag, lnMarginOfError, lnAnchorWas IF this.MouseDownAt == 0 DODEFAULT(m.nLeft, m.nTop, m.nWidth, m.nHeight) RETURN ENDIF
m.loControl = NULL
*!* The following tag can be placed in controls you don't want moved as well m.lcUniqueTag = "DoN't_MoVe_SpLiT" && Just something that is pretty well guaranteed to be unique THIS.TAG = m.lcUniqueTag m.llLockScreenWas = THISFORM.LOCKSCREEN && JIC the screen was already locked THISFORM.LOCKSCREEN = .T.
m.lnMovementLeft = m.nLeft - THIS.LEFT m.lnMovementTop = m.nTop - THIS.Top
FOR EACH m.loControl IN THIS.PARENT.CONTROLS IF m.loControl.TAG = lcUniqueTag && this splitter so just loop LOOP ENDIF IF PEMSTATUS(m.loControl,"Anchor",5) m.lnAnchorWas = m.loControl.Anchor m.loControl.Anchor = 0 m.llIsSplitter = m.loControl.CLASS = "Splitter" IF THIS.vertical && Vertical Splitter lnMarginOfError = INT(This.width/2) && JIC the developer got the splitter a little too close IF m.loControl.LEFT <= THIS.LEFT && Control is to the left of splitter IF (m.loControl.LEFT + m.loControl.WIDTH) <= (THIS.LEFT + lnMarginOfError) AND !m.llIsSplitter m.loControl.WIDTH = MAX(m.loControl.WIDTH + m.lnMovementLeft, 0) ENDIF ELSE && Control is to the right of splitter IF !m.llIsSplitter m.loControl.WIDTH = MAX(m.loControl.WIDTH - m.lnMovementLeft, 0) ENDIF m.loControl.LEFT = m.loControl.LEFT + m.lnMovementLeft ENDIF ELSE && Horizontal Splitter lnMarginOfError = INT(This.Top/2) && JIC the developer got the splitter a little too close IF m.loControl.TOP <= THIS.TOP && Control is above the splitter IF (m.loControl.TOP + m.loControl.HEIGHT) <= (THIS.TOP + lnMarginOfError) AND !m.llIsSplitter m.loControl.HEIGHT = MAX(m.loControl.HEIGHT + m.lnMovementTop, 0) ENDIF ELSE && Control is below the splitter IF !m.llIsSplitter m.loControl.HEIGHT = MAX(m.loControl.HEIGHT - m.lnMovementTop, 0) ENDIF m.loControl.TOP = m.loControl.TOP + m.lnMovementTop ENDIF ENDIF m.loControl.Anchor = m.lnAnchorWas ENDIF NEXT m.lnAnchorWas = This.Anchor This.Anchor = 0 DODEFAULT(m.nLeft, m.nTop, m.nWidth, m.nHeight) && Finally move the splitter This.Anchor = m.lnAnchorWas THISFORM.LOCKSCREEN = m.llLockScreenWas THIS.TAG = "" ENDPROC
PROCEDURE MouseMove LPARAMETERS nButton, nShift, nXCoord, nYCoord LOCAL lnMovement IF m.nButton = 1 AND !(this.mousedownat == 0) IF THIS.vertical IF m.nXCoord != THIS.mousedownat m.lnMovement = m.nXCoord - THIS.mousedownat IF BETWEEN(THIS.LEFT + m.lnMovement, This.minimumsize, THIS.PARENT.WIDTH - THIS.WIDTH - This.minimumsize) THIS.MOVE(THIS.LEFT + m.lnMovement, THIS.TOP, THIS.WIDTH, THIS.HEIGHT) THIS.mousedownat = m.nXCoord ENDIF ENDIF ELSE && Horizontal IF m.nYCoord != THIS.mousedownat m.lnMovement = m.nYCoord - THIS.mousedownat IF BETWEEN(THIS.TOP + m.lnMovement, This.minimumsize, THIS.PARENT.HEIGHT - THIS.HEIGHT - This.minimumsize) THIS.MOVE(THIS.LEFT, THIS.TOP + m.lnMovement, THIS.WIDTH, THIS.HEIGHT) THIS.mousedownat = m.nYCoord ENDIF ENDIF ENDIF ENDIF ENDPROC
PROCEDURE MouseDown LPARAMETERS nButton, nShift, nXCoord, nYCoord IF THIS.vertical THIS.mousedownat = nXCoord ELSE THIS.mousedownat = nYCoord ENDIF ENDPROC
PROCEDURE Init IF !THIS.vertical THIS.MOUSEPOINTER = 7 && NS ENDIF ENDPROC
PROCEDURE MouseUp LPARAMETERS nButton, nShift, nXCoord, nYCoord This.mousedownat = 0 ENDPROC ENDDEFINE
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u