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

Controlling Resize and Anchoring

Status
Not open for further replies.

TamarGranor

Programmer
Jan 26, 2005
2,484
US
Figured I'd post this here as well as a couple of other places, since people here seem to be good at out of the box solutions:

I'm going to start with the short question and then explain what got me to it.

Is there something that reliably fires when an interactive Resize is complete? I have a situation where I want to set a flag in Resize and turn it off when the operation is done. I've tried using NODEFAULT/DODEFAULT() to handle it all in Resize. I've also tried binding another event to Resize, set to fire after Resize. I took a look at testing MDOWN() or using MouseDown (which turns out not to fire in this case). None of those gives me what I need (unless I'm missing something).

Here's the background. I'm working on an application where some forms are built dynamically at runtime. (Some controls are added at form start-up, others later.) In addition, some of these forms need to resize dynamically, that is, when the user resizes the form, everything needs to scale up or down.

I'm using Anchor (mostly set to 240, relative everything) and a font resizing class to handle the second requirement and I had it working fairly well. However, building the form dynamically means turning Anchor off and resetting it as things are added. I've been trying to do this with a set of Assign methods on Left, Top, Height and Width. The problem is, those assign methods fire on an interactive resize,
not just programmatic. So, I'd like to set a flag at the beginning of Resize and turn it off afterward. Then I could check this property in the *_Assign methods and only reset Anchor when it's a programmatic change.

My fallback solution is remove the *_Assign methods and have to remember to save/reset Anchor every time something is added dynamically. But I'd really love to build the behavior into the classes.

Any suggestions?

Tamar
 
Hello Tamar;
If your resizer is a class and the forms are being created from a form class, here is an idea.
***Form.Resize()
If lResizeforms ***Public Variable
*** Put start code
This.Reg_Resizer1.Resize(This) ***Resizer class
***put end code
Endif
This will fire for both a Programatic resize and User Interaction. We do Not use Control Anchoring or a Font Class. (Font size is increased appropriately and control placement is calculated, Never really cared too much for anchoring)
 
Thanks for the suggestion. Unfortunately, it's not an simple as that. What I'm really looking for here (and haven't found) is a way to tell whether a resize is occurring programmatically or interactively.

For now, I've removed the assign methods on Height, Width, Top and Left and am hoping to remember that every time I change one of those properties programmatically, I need to save and clear Anchor beforehand and reset it afterwards for that object.

That works, but I really wanted to get this behavior into the base classes so I wouldn't have to remember every time I write positioning code.

Tamar
 
I am sorry, I am not following you. (Yes the suggestion was simple. my resizer class does it all.) You want the controls on your form to know when a Resize is taking place and position and size themselves accordingly? Or let some calling prg, form etc know before a resize is started and when done?
Why? Why not let your Resize custom class do it everytime the resize event fires?
 
HI Tamar,

so the problem is, if the user resizes the forminteractively with you want the Anchoring to have effect, but if you programmatically change the form size, Anchoring should not take place, so you really expand the form and get new space for new controls?

And now in that programmatic case you store all Anchor values, then set them 0, change form size and reset Anchor values and you'd like the controls to do it themslves?

Well, then a flag solution is easy, isn't it? Doesn't this work?

Code:
form.Changeformsize()
lparameters nWidth, nHeight
With Thisform
    .lAnchorZero = .t.
    .Width=nWidth
    .Height=nHeight
    DOEVENTS FORCE && trigger Resize
    .lAnchorZero = .f.
Endwith

And controls will each have Top_, Left_, Height_ and Width_ Assign Methods that, if form.lAnchorZero is true remember Anchor value in a local var, set Anchor to 0, set the property and reset Ancor value afterwards.

You might also try to change Anchor_Access to return 0 for Thisform.lAnchorZero=.T. and the real value for Thisform.lAnchorZero=.F. If that doesn't do the trick...

In each control class add these methods:
Code:
procedure init()
   Local loZeroAnchor
   loZeroAnchor = Createobject("empty")
   Addproperty(loZeroAnchor,"Anchor",0)
   This.Addproperty("oZeroAnchor",loZeroAnchor)
endproc

procedure THIS_Access
   Lparameres cMember
   If lower(cMember)="anchor" and Thisform.lAnchorZero
      Return THIS.oZeroAnchor
   Endif

   Return THIS
Endproc

Bye, Olaf.
 
Hi again,

sorry, some misspellings. But most important:

...And controls will each have Top_, Left_, Height_ and Width_ Access methods (not assign) that, if form.lAnchorZero is true return 0 or else return the real Anchor value?

Bye, Olaf.

 
again...

...And controls will each have an Anchor_Access method that, if form.lAnchorZero is true returns 0 or else return the real Anchor value?

Bye, Olaf.
 
<<so the problem is, if the user resizes the forminteractively with you want the Anchoring to have effect, but if you programmatically change the form size, Anchoring should not take place, so you really expand the form and get new space for new controls?>>

Not exactly. There are several things going on here:

1) When the form opens, I programmatically resize it and then I add some controls to it.

2) The user can add objects to the form, which are programmatically positioned and sized.

3) The user can resize the form as a whole, at which point I want anchoring to kick in and rsize and reposition everything.

Hope that's clearer.

Tamar

 
Hi Tamar,

1) if you have no basic controls in the form, resizing the empty form does not rise any anchoring problems, does it?

2) If you add controls, you can set their Anchor to 0 (I think you do that, as long as the user sets up the original position and size and afterwards set Anchor to the value wanted. If you Move and resize controls afterwards, it doesn't matter how their Anchor value is defined, Anchoring will only have any effect when resizing the form.

The only thing you need to be aware of is, that if left, top, width or height of a control are changed, this does not change the anchoring position and anchoring is still computed for the position and size the control had, when first setting it to some Anchor value >0.

So if you want a control to have it's new Anchor position there is no way as to set Anchor to 0 and then back to it's original value.

3) At this point Anchoring should do the job as wanted, or are there any problems?

How about some code, an example that makes the problem visible?


For 2) the solution could be to have code like this in Anchor_Assign of controls:

Code:
control.Anchor_Assign()
LParameters vNewValue

If vNewValue = -1
   Local lnOldAnchor
   lnOldAnchor = This.Anchor
   This.Anchor = 0
   This.Anchor = lnOldAnchor
Else
   This.Anchor = vNewValue   
Endif

That would give you a way to reanchor controls by setting their Anchor to -1, which will result in no change at the end, but due to setting Anchor to 0 and then back to it's old value will reanchor the control at it's current position and size.

And if you have a container with a group of controls in it, you can make use of SetAll to reanchor the whole group.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top