Runtime Dimension Switching: Implementation

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

image\DIAMOND.gif lNumControlDims is the number of objects for which dimensions are returned

image\DIAMOND.gif 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

image\DIAMOND.gif FileX is the file index within the project

image\DIAMOND.gif 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

image\DIAMOND.gif 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

Dimensioning Overview