General
Form Size
Flicker
Run Time
|
At design time, just drop an ElasticForm component on the form you wish to control. This is all you need to do.

|
It is a good idea to design your forms in a low resolution. The best design resolutions
are 640x480 and 800x600. Actually, any resolution at design
time is acceptable as long as you take the proper precautions. This is explained better in the following.
- The problem is generated from the resolution independence that is imposed by ElasticForm: This means that in the same monitor, your form will have the same physical size (e.g. 20 cm x 15 cm) at all resolutions. However, an area of 20 cm x 15 cm in resolution of 1024x768 is composed of more pixels than the same area in resolution 800x600 (63.84% more pixels, to be exact). This means that shapes, and text are more pleasing visually at the higher resolution. In many cases, text that is very clear in a high resolution, may not be legible in smaller resolution. This is because letters that are 5 mm tall in the design resolution, will be 5 mm tall in all resolutions. As the resolution becomes coarser, fewer and fewer pixels are being used to generate the letter, thus making it less legible.
- If you are determined to use high resolution display, make certain that your controls are large enough to show well at smaller resolution. Run the executable version of your program at low resolution and make certain that your form still looks good at low resolution.
- Be aware of the fact that certain controls are not resizable, nor are they resolution independent. In stead they are controlled directly by windows. These controls are: The form's title bar, the font of menus, the small dimension of the scrollbar, the square shape of the checkbox, the circular shape of the radio button, the image of the bitbutton and the image of the speedbutton. It is very important therefore to make certain that you prevent downward resizing of your form that makes it so small that the non resizable controls become too dominant. For example, you can make a bitbutton so small that its glyph overflows its size.
 |
|
There are a few things that ElasticForm cannot control, and the designer has to make proper provisions for these. In general these problems are related to resolution independence and to resizing to a size that is too small. General solutions to these problems are:
1) Design your form using as small a screen resolution as possible; 2) Consider using a lower bound to a form's size using ElasticForm's properties: MinimumTrackHeight and MinimumTrackWidth
· Scroll bars within components such as DBGrid
The height of horizontal scroll bars and the width of vertical scroll bars within components depends only on the screen resolution. This generates two problems:
At start-up of the program at different resolutions
As the resolution becomes smaller, from 1280x1024 to 640x480, you can see that the height of a horizontal scroll bar becomes larger. On the other hand, the component that contains this scroll bar maintains its size, thus the scroll bar takes a larger proportion of the component.
At resizing of the form at constant resolution:
As a form is resized to smaller size, each component is resized in proportion. However, the height of a horizontal scroll bar and the width of a vertical scroll bar do not change. Thus, components that have scroll bars resize not in perfect proportioning. If you make the component small enough, its space may be taken entirely by its scroll bars.
· BitButtons and SpeedButtons
BitButtons and SpeedButtons include bitmaps that do not stretch-to-fit. For example the bitmap of a
BitButton may be a 24x24 pixels bitmap. This is true in any resolution. The problem is that 24x24 pixels take much more space in 640x480 than in 1280x1024. If the
BitButton is just big enough to contain the bitmap in 1280x1024, it will not be able to contain the bitmap in 640x480. Thus, such buttons must be designed to have enough space to work in all resolutions
· TPicture components with AutoSize = True and Stretch = False
A bitmap within a TPicture component that does not have AutoSize = False and Stretch = True maintains its pixel size in all resolutions and form sizes. This means that such a bitmap that fits snugly within a
TPicture component in resolution 1280x1024, it not fit within this component in a smaller resolution and will not resize when the form resizes, even though the
TPicture resizes. Setting AutoSize = False and Stretch = True
will take care of this problem. However, in this case you must guard against image distortion and make ElasticForm's property
MaintainProportions = true.
· Captions and Text
When a program using ElasticForm starts at any resolution, labels, buttons, edit boxes, etc. maintain the size of their captions to that of the design resolution, within the accuracy of a font's point. For example if
Font Point = 4.3 is needed to maintain exactly the same caption size,
Font Point = 4 will be used and the caption will be slightly smaller. Since the text and label size remains constant, as the resolution decreases, fewer and fewer pixels are used to write a character, and at a very small resolution (compared to the design resolution) the writing may become illegible. There are two ways to avoid this problem: 1) Design your form at low resolution; or 2) Design your form at your favorite resolution, but make certain (i.e. test) that the font's point size is large enough to produce characters that can be seen well with a smaller resolution.
 |
|
What is Resolution Independence?
Resolution independence is the process by which a form and all its components cover an identical percentage of the screen size independent of the screen resolution.
If you create a form of width 800 pixels and height 600 pixels, then this form covers the whole screen at resolution 800x600. However, if the screen resolution changes to 1280x1024 then the same form covers a much smaller percent of your screen. Similarly if the screen resolution changes to 640x480, the form overflows the screen.
If your form design is resolution independent, then a 800x600 pixels form designed at resolution 800x600, will cover the whole screen at any resolution.
How do I achieve Resolution Independence?
Just drop an ElasticForm component on your form!
 |
|
ElasticForm now has an explicit means of suppressing resolution independence. This is provided with property
ResolutionIndependence. Just set the value of this property to false.
 |
|
This is all you have to do:
In the onActivate event of the form enter the code:
ElasticForm1.DisableResize;
And in the onDestroy event of the form enter the code:
ElasticForm1.EnableResize;
 |
|
ElasticForm can perform automated storage of its size as well as the visible state of all its components using its own INI file
or registry processes. This is controlled by ElasticForm's property ElFrmIniFile.
All you have to do is assign a string value to property ElFrmIniFile. This string must be a valid file name. This provides you with automatic INI file processing for D1,D2,D3, and BCB1, or registry recording for D4, D5, BCB3, BCB4, and BCB5. No other action is required from you (well ..in most cases this is true).
Any resizing during run time will be automatically stored in the INI file/registry. The form's sizing upon program termination will be the size that the form will have when the program runs again.
Any form resizing will automatically call method SaveIniFile. However, this automation does not occur when the visible state of a component changes. This must be done manually as shown in the example:
Panel1.Visible := not Panel1.Visible; (*toggle Panel1.Visible property value*)
ElasticForm1.UpdateSize(panel1); (*necessary call for ElasticForm to be made aware of this change*)
ElasticForm1.SaveIniFile; (*Save this new state to the ElasticForm INI file*)
Alternatively, you may wish to consider deferring a call to SaveIniFile in the OnClose event of the form.

|
Restrict Form's smallest size
Resizing a form to a small size, may result in unacceptable appearance for many reasons: 1) Labeled controls, i.e. buttons, labels, edit boxes etc. may become too small to be legible. 2) The bitmaps of bit-buttons and speed-buttons do not resize. Resizing of these buttons may make them too small to contain their bitmaps. 3) In general, a form that is too small may not be what you (the developer) had in mind for the look of your form.
You can restrict how small the form can become by using properties: MinimumTrackHeight and
MinimumTrackWidth.
For example in the Object Inspector you can set:
MinimumTrackWidth 600
MinimumTrackHeight 400
In the above setup, your form cannot become less than 600x400 pixels in size. However, this may not be what you want. A form with size 600x400 pixels would be practically of maximized size in the 640x480 resolution, but would be a bit more than one quarter of the screen in the 1024x768 resolution. An alternative, and better way to do this, is to use a negative integer between -1 and -100. For example in the Object Inspector you can set:
MinimumTrackWidth -60
MinimumTrackHeight -50
The above means that the form's width can never become smaller than 60% of the screen width and the form's Height can never become smaller than 50% of the screen height. This approach is screen resolution independent.

|
|
Sometimes you may not wish to allow a form to be maximized in a way that covers the entire screen. This is how you can do that:
You can restrict the maximized form size and position by adjusting properties:
MaximumTrackHeight, MinimumTrackWidth, MaximizedPosX , and
MaximizedPosY.
For example in the Object Inspector you can set:
MaximumTrackWidth 700
MaximumTrackHeight 500
MaximizedPosX 50
MaximizedPosY 20
In the above setup, you form cannot become larger than 700x500 pixels in size. If the form is maximized, it will be maximized at a size of 700x500 pixels (if the screen resolution allows it) and its left-top coordinates are 50,20 pixels. However, this may not be what you want. A form with size 700x500 pixels covers most of the screen in the 800x600 screen resolution, but it is a much smaller part of the screen in 1024x768 screen resolution! An alternative, and better way to do this, is to use a negative integer between -1 and -100. For example. in the Object Inspector you can set:
MaximumTrackWidth -90
MaximumTrackHeight -80
MaximizedPosX -5
MaximizedPosY -10
The above means that the form's maximized size is (90% by 80%) of the screen's width and height respectively. The left-top coordinate of the form is 5% of the width and 10% of the height, which would place it in the center of the screen, no matter what is the resolution.

|
Fixing the form's aspect ratio to a
constant value.
Arbitrary resizing may change the form's aspect ratio. For example a form may start at resolution 500x500 and can be resized to 800x500. The form started as a square and was resized to a rectangle. Quit often this is not a problem. But sometimes, this may lead to unwanted distortions. Consider for example
a TImage component with the stretch property set to true. Let us assume that you have already made certain that the Image size is the same as the contained bitmap size. Any run-time resizing that is not proportional to the form's original size will result in distortion of the image's shape, which can be unacceptable.
This is a very each problem to resolve with ElasticForm. Just set the MaintainProportions property to true. Any run-time resizing is now forced to keep the design proportions. The result? No distortion of shapes.

|
Interrupting the resizing process for a while
Problem Statement
Consider a form with two panels: panel1 and panel2:
Panel1 resides at the top of the form with width equal to the form's ClientWidth and height equal to 200 pixels.
Panel2 resides below Panel1 (Panel2.top := Panel1.height+1). Panel2 has the same width as panel1 and height := 300 pixels.
Assume that the form's ClientHeight is 500 pixels.
Finally, let a button (Button1) reside in Panel1.
Desired Behavior
You wish to press button1 and if Panel2 is visible, you want to hide it and then reduce the form's height by the height of Panel2. Naturally, you want the size change to occur without resizing of any component.
How it is done
This is done with the help of methods: DisableResize, ReInitializeResizing, and
EnableResize. Here is an example:
////
procedure TForm1.Button1Click(Sender: TObject);
(* If panel2 is visible then hide it and reduce the form's size by the panel's height. *)
begin
ElasticForm1.DisableResize; (*All resizing is disabled*)
Panel2.Visible := not Panel2.Visible;
ElasticForm1.UpdateSize(panel2); (*Needed to store the new visible state of the panel in ElasticForm's data.*)
if Panel2.Visible then Height := Height+Panel2.Height
else Height := Height-Panel2.Height;
ElasticForm1.ReInitializeResizing; (*Before Enabling resizing again, ElasticForm's data are reset to the new reality*)
ElasticForm1.EnableResize; (*From now on Resizing is enabled*)
end;
////

|
Resizing of a (BorderStyle =
bsNone) form
An elegant way of replacing a window's bar is to set the window's BorderStyle property to
bsNone, place a design panel or some other "bar looking" component aligned at the top, add some buttons to the top right that look like the close, restore, minimize, and help, and finally arrange for resizing of the form in our program, either implicitly, or by providing our own handles, which we program to resize the form.
However, adding an ElasticForm to this form prevents such resizing. How do I bypass this problem?
The public field AllowNoBorderResize makes this possible:
At the beginning of the resizing process of your program, (for example in the
OnMouseDown event of the added handle) add the line:
ElasticForm1.AllowNoBorderResize := true;
Then at the end of the resizing process (for example in the OnMouseUp event) add the line:
ElasticForm1.AllowNoBorderResize := false;
This is it!
 |
|
Non-TT fonts cannot become smaller than a certain size (e.g. size 8). As a form and all its controls are resized to become smaller, all captioned controls such as buttons, edit boxes, etc. need to have smaller font so that their caption fits in their reduced size. A non TT font will not be resized below a certain value. For example it may need to become size 6, but cannot become smaller than 8, thus overflowing its intended space and exceeding the boundaries of its container. Also, at fairly large sizes, non-TT fonts look very "blocky" and not so attractive.
The conclusion of all the above is that you do not necessarily have to use TT fonts, but using TT fonts is a very good idea. To change the font to a TT font, all you have to do is change the form's font or the ElasticForm's font to a TT font.
 |
|
If you wish to exclude a control from the resizing process you must call the AddToExcludeList method in the OnCreate event of the owner form.
For example, consider a form with two buttons Button1 and Button2, and an ElasticForm component, named ElasticForm1. The following code in the OnCreate event of the owner form:
ElasticForm1.AddToExcludeList(Button2)
excludes Button2 from resizing.
 |
|
Call this method to close and free a form, for example, when you wish to terminate your program. This method should be called in stead of calling the form's method close. The advantage of using TerminateForm is that it eliminates flicker that relates to the form's closing. Do not call this method if you are closing a form but you are not freeing its memory.
This is a simple example on how to call this method (response to the OnClick event of a button):
ElasticForm1.TerminateForm.
 |
|
Most MDI forms have commands to Cascade and Tile the MDIChild forms that they own. While and MDIChild form resizes with little or no flicker, a call to the Cascade or Tile methods of the MDIForm introduces more flicker as the MDIChild forms resize. How do I fix that?
Replace command
Cascade;
with
MDIform1.ElasticForm1.HideAllControls;
MDIform2.ElasticForm1.HideAllControls;
MDIform3.ElasticForm1.HideAllControls;
cascade;
MDIform1.ElasticForm1.ShowAllControls;
MDIform2.ElasticForm1.ShowAllControls;
MDIform3.ElasticForm1.ShowAllControls;
Similarly, replace command
Tile;
with
MDIform1.ElasticForm1.HideAllControls;
MDIform2.ElasticForm1.HideAllControls;
MDIform3.ElasticForm1.HideAllControls;
Tile;
MDIform1.ElasticForm1.ShowAllControls;
MDIform2.ElasticForm1.ShowAllControls;
MDIform3.ElasticForm1.ShowAllControls;

|
|
When you paint directly on the form's canvas using the OnPaint event of the form, the FormResize method of ElasticForm is called internally more than once and as a result visible flicker may occur when the painting is intensive. To stop this flicker you can do the following:
Define a global or class variable bCanRepaint : boolean;
Wrap the OnPaint event of the form as follows
if not bCanRepaint then exit;
{Do here your painting}
bCanRepaint := false;
Place the following code in the OnAfterResize event of ElasticForm
bCanRepaint := true;
 |
|
When you change the value of FormStyle of a form you will notice that during the process of changing the value of FormStyle, the form flickers. This is because the form is destroyed and recreated. Actually, the form's handle is destroyed and recreated. This is done in the procedure TCustomForm.SetFormStyle(Value: TFormStyle) of the Forms unit. Because the Form's handle is destroyed the windows WM_DESTROY message is sent which results in the "self destruction" of Elasticform's hook to the form. However, the form has not been destroyed and therefore it is not recreated. As a result the hook of the ElasticForm to the owner form is not recreated. The result of this process is that subsequent resizing of the form no more experiences resizing of the controls of the form.
To solve the problem do the following:
· Remove the ElasticForm component from the Form
· Recreate a new ElasticForm into the form.
First Approach to implement this:
Consider the case in which clicking Button1 changes the value of FormStyle from fsNormal to fsStayOnTop. This is the code that is needed:
procedure TForm1.Button1Click(Sender: TObject);
begin
FormStyle := fsStayOnTop;
ElasticForm1.Free; {Destroy ElasticForm }
ElasticForm1 := TElasticForm.create(self); {Recreate ElasticForm}
ElasticForm1.DynamicCreationUpdate; {Initialize ElasticForm}
end;
Second Approach to implement this:
1. Create a private variable of TForm1 : OldHandle : THandle;
2. In the OnCreate event of TForm1 add the line
OldHandle := Handle;
3. In the OnShow event of TForm1 add the code
if Handle <> OldHandle then //This means that the handle was destroyed and
//recreated without the destruction of the form.
//This is the case when the FormStyle of the form
//is changed. ElasticForm must now be destroyed
//and recreated.
begin
OldHandle := Handle; //Reset the value of OldHandle
ElasticForm1.Free; //Destroy ElasticForm1
ElasticForm1 := TElasticForm.create(self); //Recreate ElasticForm1
ElasticForm1.DynamicCreationUpdate;
end;
4. Now, to change the FormStyle of TForm1 add this to the OnClick event of Button1:
procedure TForm1.Button1Click(Sender: TObject);
begin
FormStyle := fsStayOnTop;
end;
If you would like to change the FormStyle of a secondary form on its creation then the process needs be similar to the second method above. Consider a primary Form1 and a secondary Form2 that has a default FormStyle = fsNormal. Form2 is NOT created when Form1 is created. Form1 has two Buttons. Button1 creates a new Form2, which must have FormStyle value = fsMDIform. Button2 creates a new Form2 which must have a FormStyle value = fsStayOnTop.
· Make Form2 a TForm2 variable in the TForm1 unit
· In the OnClick event of Button1 of Form1 add this code:
Application.CreateForm(TForm2, Form2);
Form2.formStyle := fsMDIform;
Form2.visible := TRUE;
· In the OnClick event of Button2 of Form1 add this code:
Application.CreateForm(TForm2,Form2);
Form2.FormStyle := fsStayOnTop;
Form2.visible := TRUE;
· Make the OnShow event of the TForm2 as follows:
ElasticForm.Free;
ElasticForm := TElasticForm.create(self);
with ElasticForm do
begin
DynamicCreationUpdate;
{if Resolution independence is important then define two constants in TForm2 with names DSW, and DSH, where DSW is the Design Screen Width and DSH is the Desing Screen Heigh of TForm2. Then add the following line}
Setbounds(round(self.left*Screen.Width/DSW), round(self.top*Screen.Height/DSH),
round(self.Width*Screen.Width/DSW), round(self.Height*Screen.Height/DSH));
end;

|
|
ElasticForm catalogs and sizes all controls that are present when it (the ElasticForm) is created. Any control that is added after that time (e.g. at run-time) is not sized because ElasticForm is not aware of its existence.
This is an example of the way a new button is added dynamically on a Form that has an ElasticForm component:
NewButton := TButton.Create(form1); //needed
NewButton.Parent := Form1; //needed to make it visible
NewButton.Name := 'New Button';
NewButton.Left := 50;
NewButton.Top := 100;
NewButton.Height := 70;
NewButton.Width := 180;
ElasticForm1.AddControl(NewButton); //needed to make elasticform1 aware of NewButton
To remove the button you can use the RemoveControl method:
ElasticForm1.RemoveControl(NewButton);
NewButton.Free;
The old method of removing a control by using the AddToExludeList method, does not work any more.

|
|
ElasticForm is commonly added to a form at design time. However, in special circumstances you may wish to add ElasticForm dynamically. For example you may generate a form dynamically, add a few controls and ElasticForm to control their sizing.
Here is an example of how ElasticForm can be added to a form dynamically:
ElasticForm1 := TElasticForm.create(form1);
with ElasticForm1 do
DynamicCreationUpdate;
Warning: Any control that will be created after ElasticForm1 will no be sized unless you let ElasticForm1 know about this. How do I do that?
 |
|