When you create a form with multiple components, you can select a fixed size border or let the user resize the form and automatically add scroll bars to reach the components falling outside the visible portion of the form, as we've just seen. This might also happen because a user of your application has a display driver with a much smaller number of pixels than yours.
Instead of simply reducing the form size and scrolling the content, you might want to reduce the size of each of the components at the same time. This automatically happens also if the user has a system font with a different pixel-per-inch ratio than the one you used for development. To address these problems, Delphi has some nice scaling features, but they aren't fully intuitive.
The form's ScaleBy method allows you to scale the form and each of its components. The PixelsPerInch and Scaled properties allow Delphi to resize an application automatically when the application is run with a different system font size, often because of a different screen resolution. In both cases, to make the form scale its window, be sure to also set the
AutoScroll property to False. Otherwise, the contents of the form will be scaled, but the form border itself will not. These two approaches are discussed in the next two sections.
Form scaling is calculated based on the difference between the font height at run time and the font height at design time. Scaling ensures that edit and other controls are large enough to display their text using the user's font preferences without clipping the text. The form scales as well, as we will see later on, but the main point is to make edit and other controls readable.
Any time you want to scale a form, including its components, you can use the ScaleBy method, which has two integer parameters, a multiplier and a divisor—it's a fraction. For example, with this statement the size of the current form is reduced to three-quarters of its original size:
Generally, it is easier to use percentage values. The same effect can be obtained by using: ScaleBy (75, 100);
When you scale a form, all the proportions are maintained, but if you go below or above certain limits, the text strings can alter their proportions slightly. The problem is that in Windows, components can be placed and sized only in whole pixels, while scaling almost always involves multiplying by fractional numbers. So any fractional portion of a component's origin or size will be truncated.
I've built a simple example, Scale or QScale, to show how you can scale a form manually, responding to a request by the user. The form of this application (see Figure 9.10) has two buttons, a label, an edit box, and an UpDown control connected to it (via its Associate property). With this setting, a user can type numbers in the edit box or click the two small arrows to increase or decrease the value (by the amount indicated by the Increment property). To extract the input value, you can use the Text property of the edit box or the Position of the UpDown control.
When you click the Do Scale button, the current input value is used to determine the scaling percentage of the form:
procedure TForm1.ScaleButtonClick(Sender: TObject); begin
AmountScaled := UpDown1.Position; ScaleBy (AmountScaled, 100); UpDown1.Height := Edit1.Height; ScaleButton.Enabled := False; RestoreButton.Enabled := True; end;
The form of the Scale example after a scaling with 50 and 200
This method stores the current input value in the form's AmountScaled private field and enables the Restore button, disabling the one that was clicked. Later, when the user clicks the Restore button, the opposite scaling takes place. By having to restore the form before another scaling operation takes place, I avoid an accumulation of round-off errors. I've added also a line to set the Height of the UpDown component to the same Height as the edit box it is attached to. This prevents small differences between the two, due to scaling problems of the UpDown control.
Note If you want to scale the text of the form properly, including the captions of components, the items in list boxes, and so on, you should use TrueType fonts exclusively. The system font (MS Sans Serif) doesn't scale well. The font issue is important because the size of many components depends on the text height of their captions, and if the caption does not scale well, the component might not work properly. For this reason, in the Scale example I've used an Arial font.
Exactly the same scaling technique also works in CLX, as you can see by running the QScale example. The only real difference is that I have to replace the UpDown component (and the related Edit box) with a SpinEdit control, as the former is not available in Qt.
Was this article helpful?