Scaling in Forms
Description
In general, most properties of a form are stored and returned in pixels (there are one or two oddities such as Width and Height which are returned in Twips, but these are rare), with coordinates starting from zero on the x- and y-axes. However, this may not always suit how you wish to display controls and GDI objects in a form and so, in common with Visual Basic, GFABASIC32 offers the option to create a customised coordinate system, or Scale, so the form better suits what you, as the programmer, which to achieve.
Scaling is implemented by the changing of the scaling factor - the size of the standard unit of measurement - and of the starting coordinates on one or both axes. In addition, changes can be made to scaling at any point of the drawing of the form: those objects drawn before the changes keep their original scaling whilst those drawn afterwards adopt the new attributes.
Note: For form scaling to affect OCX Controls, the OcxScale property of the form must be set to True.
Changing Scaling Factors
ScaleMX, ScaleMY properties Show
Syntax
ScaleMX [= value!]
ScaleMY [= value!]
Description
ScaleMX and ScaleMY hold the basic scaling factors for the x- and y-axes respectively and store them as a multiple of pixels; hence, in a newly created form both properties will return 1 (one). Setting these properties to other values effects both the positioning and size of objects within the current window, as shown in the example below:
// Default window with scaling of 1:1 on X and Y axes
OpenW 1, 10, 10, 200, 200
PBox 10, 10, 30, 30
'
// Customised window with scaling of 4:1 on the X and 5:2 on the Y axis
OpenW 2, 220, 10, 200, 200
ScaleMX = 4 : ScaleMY = 2.5
PBox 10, 10, 30, 30
Effects on Other Properties
- ScaleWidth and/or ScaleHeight are changed to reflect the changed scaling factors.
- ScaleMode is reset to zero (0) or BasUser.
- The CurrentX and CurrentY properties of the active form are adjusted according to the change in scale.
Remarks
- ScaleMX and ScaleMY apply to the current form (Me) and can not be used to return or set scaling for inactive or background forms.
- These properties can also be explicitly changed using the ScaleMMOO function.
- Both properties will be indirectly altered by changes to ScaleMode, ScaleHeight, ScaleWidth and the use of the object based Scale method.
ScaleWidth, ScaleHeight properties Show
Syntax
[object.]ScaleWidth [= value!]
[object.]ScaleHeight [= value!]
object | : Form or Printer object |
Description
By setting these properties, it is possible to subdivide the width and/or height of a form into a set number of custom units - for example, setting the ScaleWidth property of a form 400 pixels wide to 100 will create a custom coordinate system across the x plane four pixels wide.
If object is omitted, the Me Form object is assumed to be object.
// Default window with scaling of 1:1 on X and Y axes
OpenW 1, 10, 10, 200, 200
PBox 10, 10, 30, 30
'
// Customised window with scaling of 2:1 on the X plane
OpenW 2, 220, 10, 200, 200
Win_2.ScaleWidth = 95
PBox 10, 10, 30, 30
'
// Customised window with scaling of 2:1 on the Y plane
OpenW 3, 10, 210, 200, 200
ScaleHeight = 95
PBox 10, 10, 30, 30
'
// Customised window with scaling of 2:1 on the X plane...
// ...and scaling of 1:2 on the Y plane.
OpenW 4, 220, 210, 200, 200
ScaleWidth = 95 : Win_4.ScaleHeight = 380
PBox 10, 10, 30, 30
Effects on Other Properties
- ScaleMX and/or ScaleMY are changed to reflect the changed scaling factors.
- ScaleMode is reset to zero (0) or BasUser.
- The CurrentX and CurrentY properties of the active form are adjusted according to the change in scale.
Remarks
- These properties can also be explicitly changed using the Scale method.
- Both properties will be indirectly altered by changes to ScaleMode, ScaleMX, ScaleMY and the use of the function ScaleMMOO.
- According to documentation, the values of ScaleWidth and ScaleHeight can be negative as well as positive which causes the coordinates to run from right to left or bottom to top; in reality, this does not seem to work.
ScaleMode property and ScaleMode$ function Show
Syntax
[object.]ScaleMode [= value%]
$ = ScaleMode$
object | : Form or Printer object |
Description
ScaleMode is a special property which can be used to set BOTH vertical and horizontal coordinate system to one of the following predetermined unit types:
basUser | (0) | Indicates that one or more of the ScaleHeight, ScaleWidth, ScaleLeft, and ScaleTop properties are set to custom values. |
basTwips | (1) | Twips (1440 twips per logical inch; 567 twips per logical centimeter). |
basPoints | (2) | Point (72 points per logical inch). |
basPixels | (3) | (Default) Pixel (smallest unit of monitor or printer resolution). |
basCharacters | (4) | Character (horizontal = 120 twips per unit; vertical = 240 twips per unit). |
basInches | (5) | Inch. |
basMillimeters | (6) | Millimeter. |
basCentimeters | (7) | Centimeter. |
basHiMetric | (8) | Himetric |
If object is omitted, the Me Form object is assumed to be object.
ScaleMode$ returns the name of the ScaleMode setting of the current object in focus (or Me). Possible return values are "User", "Twip", "Point", "Pixel", "Character", "Inch", "Millimeter", "Centimeter", and "HiMetric".
// Default window with scaling set to pixels
OpenW 1, 10, 10, 200, 220
PBox 10, 10, 30, 30
Text 10, 40, "ScaleMode = " & ScaleMode$ & "(" & Trim(Win_1.ScaleMode) & ")"
// Customised window with scaling set to mms
OpenW 2, 220, 10, 200, 220
ScaleMode = basMillimeters
PBox 10, 10, 30, 30
Text 10, 40, "ScaleMode = " & ScaleMode$ & "(" & Trim(ScaleMode) & ")"
Effects on Other Properties
- ScaleMX, ScaleMY, ScaleWidth and ScaleHeight are changed to reflect the changed scaling factors.
- ScaleLeft and ScaleTop are reset to zero (0).
- The CurrentX and CurrentY properties of the active form are adjusted according to the change in scale.
Remarks
- Changing any other Scale... property changes the value of ScaleMode to 0 or BasUser.
Changing Starting Coordinates
ScaleLeft, ScaleTop properties and OffsetXY command
Show
Syntax
OffsetXY [x!], [y!] (Requires: GfaWinx.lg32)
[object.]ScaleLeft [= value!]
[object.]ScaleTop [= value!]
object | : Form or Printer object |
value!, x!, y! | : Single variables |
Description
Whereas the other scaling properties affect the scaling factor, ScaleLeft and ScaleTop determine the starting origin point for the scaled coordinate system on the horizontal and vertical planes respectively and the values passed are the coordinates of the left and top margins of the form's work area. Hence, a box which an x-coordinate of 10 would usually be drawn 10 units from the left hand side of the form; however, if ScaleLeft is set to -10, the coordinates on the horizontal plane will start counting from that value and the box will now be drawn 20 units in from the left hand margin; similarly, if ScaleLeft was set 5, the box would now only be drawn 5 units from the left.
Note: Traditionally, these properties used the native/custom units of the form; however, due a bug in version 2.32 of the OCX, they use pixels instead. Use DllVersion to mitigate the effect of this. This bug was fixed in version 2.341.
Alternatively, OffsetXY can be used to both replicate the actions of ScaleLeft and ScaleTop - simply set the parameter value you require and omit the other - and also to set both properties at the same time. Note: OffsetXY sets the coordinate values of the origin point (0,0), not the coordinate values of the left and top margins and, therefore, the values used by OffsetXY use the converse sign to those used to set the two properties: i.e. where -10 is used with ScaleLeft property to set the coordinate of the left margin to that value, 10 would be used with OffsetXY as that would set the origin point 10 units in from the left margin; both actions will have the same outcome.
Example
$Library "UpdateRT"
$Library "Gfawinx" // Needed for OffsetXY
UpdateRuntime // Patches GfaWin23.Ocx
OpenW 1, 10, 10, 200, 200
// Set scale factor to millimetres and draw a red box
ScaleMode = basMillimeters
Color 255 : Box 10, 10, 30, 30
// Set left margin to -10 and draw a blue box
OffsetXY 10 //Same as: Win_1.ScaleLeft = Iif(DllVersion = 2.32! Or DllVersion = 2.33!, ScaleX(-10, basPixels, basMillimeters), -10)
Color RGB(0, 0, 255) : Box 10, 10, 30, 30
// Set top margin to -10 and draw a green box
Win_1.ScaleTop = Iif(DllVersion = 2.32! Or DllVersion = 2.33!, ScaleX(-10, basPixels, basMillimeters), -10) // Same as OffsetXY , 10
Color RGB(0, 255, 0) : Box 10, 10, 30, 30
OpenW 2, 220, 10, 200, 200
ScaleMode = basMillimeters
// Draw a red box at default position
Color 255 : Box 10, 10, 30, 30
// Set left margin to 10 and draw a blue box
Win_2.ScaleLeft = Iif(DllVersion = 2.32! Or DllVersion = 2.33!, ScaleX(10, basPixels, basMillimeters), 10) // Same as OffsetXY -10
Color RGB(0, 0, 255) : Box 10, 10, 30, 30
// Set top margin to 10 and draw a green box
OffsetXY , -10 // Same as: Win_2.ScaleTop = Iif(DllVersion = 2.32! Or DllVersion = 2.33!, ScaleX(10, basPixels, basMillimeters), 10)
Color RGB(0, 255, 0) : Box 10, 10, 30, 30
Do : Sleep : Until IsNothing(Win_1) Or IsNothing(Win_2)
CloseW 1
CloseW 2
Effects on Other Properties
- ScaleMode is reset to zero (0) or BasUser.
- The CurrentX and CurrentY properties of the active form are adjusted according to the change in starting point.
Remarks
- These properties can also be explicitly changed using the Scale method and the ScakeMMOO function.
- These properties are not the same as Top and Left.
Changing Both
Scale method Show
Syntax
[object.]Scale x1!, y1!, x2!, y2!
object | : Form or Printer object |
Description
The Scale method sets the coordinates for the top-left (x1!, y1!) and bottom-right (x2!, y2!) of the form. In so doing, it also sets the scaling factor of the form accordingly in the following way:
ScaleLeft = x1!
ScaleTop = y1!
ScaleWidth = x2! - x1!
ScaleHeight = y2! - y1!
ScaleMX = (width in pixels) / (x2! - x1!)
ScaleMY = (height in pixels) / (y2! - y1!)
If object is omitted, the Me Form object is assumed to be object.
Example
Local i As Double
OpenW 1, 10, 0, 700, 260, 0
AutoRedraw = 1
BackColor = $c0c0c0 // clears window
Scale -10, 1, 10, -1
Color $e0e0e0
For i = -10 To 10
Line i, -1, i, 1
Next
For i = -1 To 1 Step .1
Line -10, i, 10, i
Next
Color $808080 // axes
Line -10, 0, 10, 0
Line 0, -1, 0, 1
FontTransparent = 1 // as GraphMode ,TRANSPARENT
For i = -10 To 10 // text for x-axes
Text i - TxtLen(Str(i)) / 2, 0, Str(i)
Next
For i = -1 To 1.01 Step .1
If Abs(i) > .05 // not 0
Text i < 0 ? 0.1 : -.7, i - ScaleY(7, basPixels), Format(i, "0.0")
EndIf
Next
Color 0
Plot -10, 0
For i = -10 To 10 Step .1
If i
Draw To i, Sin(i) / i
Line i, 0 To i, CurrentY, RGB(255, 0, 0)
EndIf
Next
ScaleMMOO function Show
Syntax
ScaleMMOO mx!, my! [, offsetx!, offsety!]
Description
ScaleMMOO sets the scaling factor for the form for both axes (mx!, my!) and, optionally, the values of ScaleLeft and ScaleTop (offsetx!, offsety!). ScaleWidth and ScaleHeight are also automatically reset to a value equal to the width or height of the form in pixels divided by the respective scaling factor.
Example
OpenW 1, 0, 0, 500, 400
Local x%
PBox 10 , 10, 40, 40
ScaleMMOO 2, 2, -100, -100 ' size x 2, origin 100,100
Color 255
PBox 10 , 10, 40, 40
Do : Sleep : Until Win_1 Is Nothing
Manual Scaling & Conversion
If you do not wish to permanently affect the scaling factor of a form, GFABASIC32 has numerous functions that allow you to perform one-off conversion between different measurement types, some of which are listed below:
ScaleX, ScaleY |
These functions allow conversion between Twips, Points, Pixels, Characters, Inches, Millimetres, Centimetres, and HiMetrics; in addition, when used in a scaled form, they can convert between the current user-defined scaling and the standard measurements listed above. |
TwipsPerHimet, HimetsPerTwips |
Screen object properties, these allow conversion between Twips and HiMetrics. |
HimetsToPixelX, HimetsToPixelY, PixelsToHimetX, PixelsToHimetY |
Built-in functions that convert between HiMetrics and Pixels on both the X and Y planes. |
TwipsPerPixelX, TwipsPerPixelY, PixelsToTwipX, PixelsToTwipY |
The first two are Screen and Form based properties, the last two built-in functions: all allow conversion from Pixels to Twips along the specified plane or axis. |
PixelsPerTwipX, PixelsPerTwipY, TwipsToPixelX, TwipsToPixelY |
As with those above but converting from Twips to Pixels. |
See Also
ScaleToDPi, ScaleXYWHToDpi, WM_DPICHANGED, WorkWidth, WorkHeight.
{Created by James Gaite; Last updated: 02/03/2022 by James Gaite; Other Contributors: Jean-Marie Melanson}