Tuesday, July 24, 2012

Scroll Form Programmaticaly

A VFP form is tuned up properly to the wheel of the mouse so when you scroll up and down, the form when scrollbars are shown will follow.  However, there are some reports that sometimes the form stops scrolling when mouse is on top of other objects like a container for instance.  Test this:


loTest = Createobject("Sample")
loTest.Show(1)

Define Class Sample As Form
      ScrollBars = 2
      ScrollPos = 0
      Caption = 'Container prevents scrolling'

      Add Object Container1 As Container With ;
            top = 25,;
            left = 25,;
            height = 400,;
            width = 500
Enddefine


You can scroll all you want using the mouse scroll to no avail when it is on top of that container, and you may wonder  why.  That is because an object like a container has its own "MouseWheel" event that is capturing that mouse wheel scrolling when your mouse pointer is on top of it.

So since it is capturing said movement of the mouse wheel, the trick then is to force scroll the form from within that object's own MouseWheel event.  What if you have more containers then?  Plus some more objects?  Then that is where BindEvent() comes very handy.

However, one problem pose with the above.  Unlike grid, a form do not have a DoScroll event where we can simply instruct it to scroll.  So how can we then scroll it programmatically?


The trick I will show here is how to use both BindEvent() plus SetViewPort property of the form.  Combining these two, then your problem on form scrolling is fixed. Here is the sample code with those two in place:


loTest = Createobject("Sample")
loTest.Show(1)

Define Class Sample As Form
    ScrollBars = 2
    ScrollPos = 0
    Caption = 'How to scroll even on top of Container'

    Add Object Container1 As Container With ;
        top = 25,;
        left = 25,;
        height = 400,;
        width = 500

    * Just add this
    Procedure Container1.Init
        Bindevent(This,'MouseWheel',Thisform,'ScrollMe')
    Endproc

    * And this
    Procedure ScrollMe
        Lparameters nDirection, nShift, nXCoord, nYCoord
        Thisform.ScrollPos = Thisform.ScrollPos +;
            Iif(m.nDirection=120,-15,15)
        Thisform.SetViewPort(0,Thisform.ScrollPos)
    Endproc

Enddefine


and there you are, another easy trick!

Cheers!