When VBLM is configured to implement runtime dimension switching (RDS), it does so by integrating RDS data into the language database and inserting code that fetches and uses it into the VBLM_SetProperties procedure added to all files that have a translated visible interface.
The inserted code takes the overall form of
Retrieve dimension data from database or resource
For control container and each control
Use dimension data to resize it
Next
Retrieving Dimension Data
The procedure that each file calls to retrieve dimension data is named VBLM_GetDimensions() and is located in the RSV support module added to the project. Although there is a different version of VBLM_GetDimensions() for each LDB format, all take the same arguments and return the same value:
lNumControlDims = VBLM_GetDimensions(PrjX, FileX, ControlDims(), Container.ScaleMode)
where
lNumControlDims is the number of objects for which dimensions are returned
PrjX is 1 if the LMP is based on a VBP file, or the project index if the LMP is based on a VBG file
FileX is the file index within the project
ControlDims() is an array of indexed dimension data user-defined types, defined in the RSV support module as:
Type tagControlDims
CtrlX As Long
Left As Long
Top As Long
Width As Long
Height As Long
Ptr As Long
End Type
Container.ScaleMode is the value of the file's ScaleMode property
When VBLM creates the code, it inserts the necessary declarations, then writes the call with hard-coded project and file indices:
Dim CtrlDim() As tagControlDims
Dim lNumControlDims As Long, cx As Long
lNumControlDims = VBLM_GetDimensions(1, 3, CtrlDim(), ScaleMode)
The Object.Move Resizing Statements
The resizing code consists of iterated .Move statements in a For/Next loop that uses cx as the index variable to step through the container (cx=1) and the controls (cx=2...n):
For cx = 1 to lNumControlDims
Object.Move
Next
The .Move statements take 1 of 3 forms, depending on option settings. The options, set on the RDS page of the Build window, specify for forms and controls separately whether to switch their origins, their dimensions, or both.
If both origins and dimensions are selected, the statement takes the form
Object.Move CtrlDim(cx).Left, CtrlDim(cx).Top, CtrlDim(cx).Width, CtrlDim(cx).Height
If origins only are selected, the statement takes the form
Object.Move CtrlDim(cx).Left, CtrlDim(cx).Top
If dimensions only are select, , the statement takes the form
Object.Move Object.Left, Object.Top, CtrlDim(cx).Width, CtrlDim(cx).Height
because Left and Top are not optional arguments to .Move, and are thus passed as their existing values.
Hide While Switching
If the Hide While Switching RDS option is checked (the default setting), VBLM brackets the resizing loop with Save Visible State/Hide/Restore Visible State code insuring that the interface is hidden while it resizes, without showing the interface if it isn't already visible:
Dim bVisCache as Boolean
bVisCache = Visible
Hide
For cx = 1 to lNumControlDims
Object.Move
Next
Visible = bVisCache
Special Treatment for VB.Line Controls
Line controls have X1, X2, Y1, and Y2 properties instead of Left, Top, Width and Height, and VBLM codes for them accordingly.
If both origins and dimensions are selected, the code is
Line.X1 = CtrlDim(cx).Left
Line.Y1 = CtrlDim(cx).Top
Line.X2 = CtrlDim(cx).Width
Line.Y2 = CtrlDim(cx).Height
If origins only are selected, the code is
Line.X1 = CtrlDim(cx).Left
Line.Y1 = CtrlDim(cx).Top
And if dimensions only are selected, the code is
Line.X2 = CtrlDim(cx).Width
Line.Y2 = CtrlDim(cx).Height
Not All Controls Should Get Resized
Some control classes, timers for example, should not be moved or resized even though they may have origin properties. Because this distinction is arbitrary, VBLM maintains an editable list of control classes that should not be resized. The list includes CommonDialog, ImageList, Menu, and Timer by default, but you can add to it on the Controls Excluded from Dimension Switching page of the Build window.
Matching Controls with Dimensions
Because not all of the controls on a form will be resized, VBLM needs a mechanism for matching controls with dimensions, ie making sure that each control gets the right dimension data even though there's no assurance that the sequence of controls on the form and the sequence of data in the CtrlDim() array match up (if, for example, the 5th control on a form was a timer, CtrlDim(5) would contain data for the 6th control, and so forth). VBLM's mechanism is to store each control's sequence number with the dimension data, so that CtrlDim(5).CtrlX will be 6. When it writes the resizing loop, it references the CtrlX, not the loop counter:
For cx = 1 to lNumControlDims
Select Case CtrlDim(cx).CtrlX
Case 1
Move Left, Top, CtrlDim(cx).Width, CtrlDim(cx).Height
Case 2
txtLoopCount.Move CtrlDim(cx).Left, CtrlDim(cx).Top, CtrlDim(cx).Width, CtrlDim(cx).Height
Case ...
Handling Missing Data
It is completely acceptable to define dimension data for some but not all languages in a multilingual RSV (see Assigning Dimension Data to Languages). When this is the case, VBLM_GetDimensions() returns 0 for languages without data. When lNumControlDims is 0, the resizing loop never executes
Example
When all of this is put together, you get something like the following. VBLM generated this code for the frmExplore.frm file found in the Optimize.vbp sample app that shipped with VB5 and VB6.
'Begin dimension switching code
Dim CtrlDim() As tagControlDims
Dim lNumControlDims As Long, cx As Long
Dim bVisible As Boolean
lNumControlDims = VBLM_GetDimensions(1, 5, CtrlDim(), ScaleMode)
bVisible = Visible
Hide
For cx = 1 To lNumControlDims
Select Case CtrlDim(cx).CtrlX
Case 1
Move Left, Top, CtrlDim(cx).Width, CtrlDim(cx).Height
Case 2
tvExample.Move CtrlDim(cx).Left, CtrlDim(cx).Top, CtrlDim(cx).Width, CtrlDim(cx).Height
Case 3
StatusBar1.Move CtrlDim(cx).Left, CtrlDim(cx).Top, CtrlDim(cx).Width, CtrlDim(cx).Height
Case 5
Line1(0).X1 = CtrlDim(cx).Left
Line1(0).Y1 = CtrlDim(cx).Top
Line1(0).X2 = CtrlDim(cx).Width
Line1(0).Y2 = CtrlDim(cx).Height
Case 6
lblInfoWnd(0).Move CtrlDim(cx).Left, CtrlDim(cx).Top, CtrlDim(cx).Width, CtrlDim(cx).Height
Case 7
Line1(1).X1 = CtrlDim(cx).Left
Line1(1).Y1 = CtrlDim(cx).Top
Line1(1).X2 = CtrlDim(cx).Width
Line1(1).Y2 = CtrlDim(cx).Height
Case Else
End Select
Next
Visible = bVisible
'End dimension switching code
See Also