Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Automatic Scroll when highlighted textbox goes off the screen

Status
Not open for further replies.

sdocker

IS-IT--Management
Aug 12, 2010
218
GB


I am using a scrolling region within a form.

Is it possible to have the scrolling region scroll up or down when the highlighted field moves off the visible portion?

This would be similar to how a grid operates.
Thanks,
Sam
 
Hi Sam,

What method are you using to add the scrolling region? Is it the method that I described in this article: ?

If so, then the scrolling region is itself a form, and has all the properties and methods of a form. To scroll a form, you adjust the viewport. If you don't know how to do that, read the VFP Help on the SetViewport method, and the various ViewportXXXX properties.

Come back if you have any further questions.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks Mike,
I am using the method you refer to. Thank you

I'll learn about "ViewPort", and take it from there.

Sam
 

I understand a little about viewports now.
How do I determine if the highlight is on a textbox that is within the viewport?
If I knew that it was on the bottom line of the viewport, I could code something if the down-arrow is pressed.

Thanks,
Sam
 
OBJTOCLIENT() is a helpful function. IIRC it returns 0, if a control is not within the visible viewport area, which I for example used in a grid with about the same goal - to scroll a column into the visible part of the grid, if it isn't visible.

Bye, Olaf.



 
Keep in mind that the Top property of a control is relative to the top of the form, regardless of how it is scrolled. ViewPortTop and ViewPortHeight together give you the (vertical) boundaries of the current viewport. So if the object's Top >= the viewport's top, but <= the viewport's top + the viewport's height, it is within the visible area. Similarly with Left, ViewPortLeft and ViewPortWidth.

These settings take account of the window title and borders, so you don't need to worry about them. But, surprisingly, they don't take account of the width of the scrollbars themselves. In practice, this is not likely to be a problem, but it's worth keeping in mind.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 

Olaf,

I am using a scrollable form as an object on another form.

As the scrollable region is moved, so do the controls it contains, and the value returned by OBJTOCLIENT doesn't change.

What I'm looking for is a way to determine an objects position in the viewport of the scrollable form.

Thanks,
Sam
 
Sam,

To elaborate, the following code should do what you want. Place it in the GotFocus of the control in question.

Code:
IF NOT BETWEEN(this.Top, thisform.ViewPortTop, thisform.ViewPortTop + thisform.ViewPortHeight)
    thisform.SetViewPort(thisform.ViewPortLeft, this.Top - (0.5 * thisform.ViewPortHeight))
ENDIF

The above code handles vertical scrolling only. If the form can also scroll horizontally, you would need a similar block of code, but referring to Left, ViewportLeft and ViewportWidth, rather than Top, Viewport and ViewportHeight.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 

Mike,

The code works nicely.

There are numerous controls that need this test. So, is there a way to avoid putting this into all their GotFocus events.

I am using my own textbox class, so I could put it there quite easily.

Is there any reason not to do it this way.

Thanks,
Sam

 
Well, I know you use a form as container. In case of the grid control in column objtoclient() returns 0, if the objects are not visible, I was hoping that to also be true for control outside of the viewport area, but didn't test.

If that had been the case you would get the position within the subform when controls are visible and 0 if not visible, of course you would never get the position in relation to the parent form, but that wouldn't have mattered.

Bye, Olaf.
 
You've answered your own question, Sam. Given that you have your own textbox class, it would make perfect sense to add the code to the GotFocus at the class level.

That said, you probably use that same textbox class for all your textboxes, not just the ones you place in the scrolling region. It might seem a bit wasteful to have to execute the scrolling code every time a textbox gets focus, even though only a minority of textboxes need it.

There are two possible solutions to that. First, create a subclass of your textbox class, exclusively for use in the scrolling region; and include the scrolling code in the subclass, not the base class. But that's not ideal, because the whole thing would get messy if you later decide to create further classes lower down the hierarchy.

The other option is add a property to the textbox class that acts as a sort of master switch. The property would be set to .F. by default; you would then only do the scrolling stuff when it was set to .T. Going further, you could set it to .T. for all the controls in the scrolling region, via a single THISFORM.Setall() call in the Init of the scrolling form.

Anyway, I'm glad you've found the scrolling region idea useful. As far as I recall, this is the first time I've heard of anyone using it (apart from myself).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 

Mike,
The second option is obviously much more efficient. I'll try it.
I would guess many programmers have used it. I'm may just be the first one with questions.

One final question.
When I load the form with the scrollable region, I can get an object in the scrollable region to be highlighted, so I am assuming it received focus.

However, the scrollable region does not respond to any keyboard input until I click anywhere on the form with the mouse.

Sam
 
The scrollarea not reacting most probably is because it's not the active form. A form can be inactive, while a control in it has focus, there always is just one active window overall, not onoly for each application, and keyboard input only gets to this single foreground form. You need to activate the form, eg by SetForeGroundWindow API call.

Bye, Olaf.
 
Olaf,

I tried a the API call without any success.

The Form I'm referring to is in the foreground, on another form which is modeless. It just doesn't respond to keyboard input until it is moused.

Sam
 
Off hand, I can't see why SetForegoundWindow doesn't work, nor can I think of a workaround - except perhaps using the MOUSE command to programmatically click in the scrolling area. But that's ugly.

If I come up with a solution, I'll let you know.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 

Thanks Mike.

I'll try some more with the API call.

In the meantime. .... MOUSE CLICK AT 10,10 RIGHT .... works


Sam
 
Yes, I don't doubt that would work. The reason I described it as ugly was that the user would see the mouse pointer suddenly jump around the screen through no action on their part. Still, if it's the only way ....

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hm, I created a tooltip form and thought about how to return focus to the calling form, as the tip should not get foucus. I had to do nothing, because after callin loTooltipForm.Show() the form showed and focus was back at the calling form anyway.

I don't know how you create the form for your scrolling region at runtime, but of course the TabOrder in it is independant on the taborder of your mainform, one of the controls has focus additionally to one of the controls on the main form, but only one of these is active and receives keyboard events.

If that is disturbing you, you better use another way to make a scrollable region. For example Craig Boyd has done that based on container, so it's still just a control on your form, no hassles with this foreground window thing.

Bye, Olaf.
 
Olaf's post reminded me of another way of solving the problem: call the scrolling form's Show method after the control receives focus. Like the AlwaysOnTop idea, I don't know if it will work, but it would only take a moment to try.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top