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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Replicate Class Browser Form Resizing 1

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi, I need some help achieving the resizing of controls within a form. The behavior I'm looking for can be seen when opening any class within the class browser.

Notice that you can grab the right side control (oleMembers) with a vertical bar and drag it left or right and the other side readjusts. If you just move your mouse between the left and right container controls withouit doing anything, you can see the mousepointer change, indicating a resize is possible.

I found the browser.scx form withing the "C:\VFP9\Tools\xsource\VFPSource\browser\" folder but cannot make much sense of it or how to replicate the behavior.

Thanks,
Stanley
 
The browser.scx resize event calls a function defined in browser.prg, look there. It's very specific code, not general. I'd not get happy with that.

VFPs Anchor is a better friend than Resize event code in some ways, as you anchor to the next higher parent container, which can be the form or a container or a page of a pageframe. And so you can anchor to a partial section of the form, if you divide your form into such sectors by introducing containers.

A third option would be using two forms and dock them. Every form would need to react to their resizing by resize event or anchored controls, again, but you'd have an actual splitter bar between forms "magnetically" attached to each other vertically or horizontally (50:50) by default, you don't need code to react to a drag event or something like that, you only need to have your anchoring right or handle things in the two form resize events.



Chriss
 
Hi Chris,

Pertaining to option 1 above, I do not see the command chain. The browser.scx form's resize event references a custom form method named "scaleresize". Within scaleresize I see this line... DO brwScaleResize IN browser WITH (this). I cannot find a reference to "brwScaleResize" anywhere. I expected it to be in the browser.prg as you mentioned. Running VFP's CodeReferences tool, also does not show anything.

I need more info to better understand your options 2 and 3. Lets start with what might be the easiest and one that can be completed to a satisfactory end.

I'm trying to learn how to add the modern common feature of resizing the contents of a form with a vertical splitter, much like SSMS, VSCode, VS, Word, Outlook and many other modern apps. I first went looking for something within VFP that does it and found the class browser can do it, and figured the code already exists in VFP and maybe the easiest to implement. Now if I can just figure out how to implement it.

How would you implement this modern feature in a simple reusable way?

Thanks, Stanley

 
The command chain is incomplete for me, too, but rather in how Resize is triggered.
b
Code:
DO brwScaleResize IN browser WITH (this)
Yes, that's a call into the browser.prg. You'll find the brwScaleResize when you open up the browser.prg of the classbrowser project and open the document view. It'll show an alphabetically ordered list of defines, class definitions, procedures, and functions, which you also can use to navigate in the PRG.

You expect too much from the brwScaleResize function, it's explicitly referencing the form's oleClassList and oleFolderList, besides other things, it's not general code acting on all controls of whatever form is passed in. It's quite a bad programming style to have this code externally as it's specific to this form, even if it is also called from another form it's not the solution to share code between forms - the ideal solution would be to have a form class both forms inherit from.

Chriss
 
Not sure whether this is relevant to your needs, but I have a form class which includes a re-size function.

When the user drags the sides of the form (in your case perhaps when a vertical bar has been dragged between two adjacent forms), this causes all the controls on the form to be re-sized and re-positioned, and for the font size to be adjusted - within reason.

To handle this, each control on the form (textbox, label, listbox &c) is of a class which has has five properties which remember the orginal size, position and shape of the form.

ztop, zleft, zheight, zwidth, zfontsize.​

These are all remembered in the Init() method of the control. So your textbox.init() method would have code like this

Code:
*  STLtextbox.init()
WITH This
   This.zTop = This.Top
   This zFontsize = This.fontsize
   .  .  .  
   ENDWITH

Then, in the Resize() method of STLform, the real business is done. This method determines the ratio in which the height and shape of the form has been adjusted. And for each control on the form, its new position is calculated, using its remembered .ztop, .zleft values. And finally the font size is recalculated : If the form has been increased in size, to the smaller of the increase in height and width &c. If the form has been shrunk there is a lower limit of how much the fontsize should be shrunk !

For grids and listboxes within the form, their own Resize() methods are invoked to resize their own columns.

There are a few refinements. For example, if there is a grid on the form and the user drags the bottom of the form to increase its height, it is quite likely that he is doing this so that he can see more rows on the grid. The STLform.Resize() method could cope with that, giving most of the increased height to the grid. Also there are some controls, like option lists, which you might not want to re-size.

I originally developed this feature because some users needed to make most of the forms bigger that I had designed them - maybe even full-screen. The application remembers the size that a user has given to each form, so that when he logs in the next day he sees the screen as he had re-shaped it.

If this is of interest I can make the class library available.

HTH Andrew
 
Hi Chriss,

> the ideal solution would be to have a form class both forms inherit from.
I'm a bit confused with "both forms". Isn't the class browser form a single form where a vertical resizer bar in between two treeview-like objects trades the width of one object with the other when dragging the resizer bar?

I'm not trying to resize the form, only sections made up of controls inside containers, where one container would consist of the left side group and another container makes up the right side group. When resizing the containers, I need to shorten or lengthen the left and right side section/containers by swapping their widths.

I do see what you mean by how the browser.prg is so specific. It would not be good to have to hand replicate that code for each form where that functionality was needed. I was hoping for a more generic solution.

I was thinking that a form that has 2 resizable containers in conjunction with using the anchor property could potentially give the needed results. I'll start some experimenting...

Thanks, Stanley
 
Hi Andrew,

I'm not trying to resize the form, but instead I'm resizing 2 sections withing the form. Take a look at my last reply to Chriss as I went into more detail. If you think your class can help, I'd be delighted to work with it.

Thanks, Stanley
 
stanlyn,

with "both forms" I wasn't referring to two running forms docked, I was just thinking about the reason of an external PRG used with this form, with code that actually could be in the Form.Resize.

The only viable reason is there is another SCX, which uses the same PRG. And even though that would be code reuse, OOP programming would mean to create a base form class with a Resize event that then is inherited in all derived forms.

stanlyn said:
I was thinking that a form that has 2 resizable containers in conjunction with using the anchor property could potentially give the needed results. I'll start some experimenting...

Good, this is the way to go. If you make it a form class instead of SCX you can have this functionality in many forms.
You may also base it on the control class and then can put this on any form, even multiple splitters.

Chriss
 
Very good. I wasn't even aware of ActiveX resizing problems, so far I only used a few of the standard control coming with VFP and had no issues with them, the hack of the webbrowsercontrol to put a nodefault in Refresh is well known, It's also done in the sample code.

I looked at this class and only dipped very shallow into the readme, the splitters are really just the splitterbars and work on the controls of a single parent container. It's plausible to do that for ease of use, so you don't need to redesign forms for using the splitter, I also imagine it's easy enough to iterate the Objects collection and decide from top/left in comparison with the position of the spllitter what controls are left/right or top/bottom, but aside of this advantage anchoring still will be towards the borders of the parent container, for controls on both sides.

I'd rather opt for a two-appartment-container, even though this means all controls need to be moved one nesting level deeper.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top