Results 1 to 22 of 22

Thread: Scaling your form independent of screen resolution

  1. #1

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Scaling your form independent of screen resolution

    Don't you hate it when you go to great lengths to design your forms just so, and then see it on a radically different screen resolution and it looks terrible? Would you like to be able to easily set your forms to resize themselves based on screen resolution? If so, then this code is for you.

    Note that this isn't the first code to make this claim, but hopefully it will be the last. Many don't seem to realize how involved this task really is, and so offer solutions that aren't very robust.

    I'll admit right now that I haven't added support for every possible control; so many have their own quirks. But I am happy to add support for specific controls you need added.

    Note that this code is extremely involved. I'll explain in detail how it works in the following posts. For now, just some basic instructions and the code.

    For each form you want to be resolution-independent, simply add the following line of code to the Form_Load() event:

    FormLayout Me

    There are many additional tweaks you can do, but that's all you really need to get started. Everything is handled by the one (very long) function. Here's a module that contains the main function, plus several more useful routines if you want to get serious about making your forms truly resolution-independent.
    Attached Files Attached Files
    Last edited by Ellis Dee; May 29th, 2008 at 10:45 PM.

  2. #2

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Basic Concept

    Every attempt at this that I've seen takes what I consider to be a flawed approach. They start with the premise that the ratio of the change in resolution can be applied directly to the forms and controls. This simplistic approach will yield subpar results because fonts don't scale in a uniform manner.

    For example, text in Verdana 10 is 240 twips high, and text in Verdana 11 is 270 twips high. While the font size increased by 10%, the screen space used to display it increased by 12.5%. Thus, I consider any solution based on screen ratios to be fundamentally flawed.

    My solution uses fonts as the fundamental sizing ratio. The idea is to start by deciding how many lines of text you want to fit on the screen, regardless of screen resolution. It doesn't matter if your form doesn't fill the whole screen; the concept of "lines on a screen" is merely a theoretical approach. The function starts by figuring out (through a laborious looping process) what the maximum font size is that will still fit the desired number of lines on the screen. This is the target font size.

    Let's look at Verdana 10 on a 1024x768 resolution for an example. As previously noted, Verdana 10 is 240 twips high, or 16 pixels. 768 / 16 is 48, so if you designed your application in 1024x768 resolution, and you used Verdana 10, then you're designing for 48 lines on a screen.

    Once the target font size has been identified, the function looks at the form's font size. If it's already set to the target size, nothing needs to be done and it skips doing anything. If the sizes are different, the function first calculates the resizing ratio based on the difference between the text size of the two fonts, and then kicks into high gear.

    This is where things get complicated.
    Last edited by Ellis Dee; May 22nd, 2008 at 09:33 PM.

  3. #3

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Specific Controls

    Several controls present unique challenges. The function currently handles the following:

    Listbox: Listboxes will only resize in vertical increments that display entire rows; if you try to resize a listbox a few pixels smaller, it will snap down an entire row. Multiple generic resizings will quickly shrink a listbox down to nothing. So what we first need to do is identify how many lines of text the listbox originally displayed. Then we need to identify how much "extra space" is used by its borders. Once we know that, it's a simple matter to resize it based on NumberOfLines * TextHeight + ExtraSpace.

    Combobox: Comboboxes cannot be resized vertically; their height is determined by the font size. This isn't much of a challenge, except for the fact that it's fairly common to have textboxes and comboboxes on the same form. Many programmers try to keep them the same height for a nice unified look, but autoresizing routines tend to break this symmetry. So this solution will size the height of textboxes equal to the height of comboboxes if (and only if) there is at least one combobox on the form.

    Textbox: Even the lowly textbox can add complexity if it is set to multiline.

    Optionbutton, Checkbox: These are possibly the most irritating controls to deal with, because they contain graphics elements that don't change size when the font grows or shrinks..

    SSTab The SSTab control is annoying for resizing routines because of the way it handles tabs. Instead of having actual tab objects, it simply moves controls from hidden tabs 75000 twips left.

    Line: Lines don't have height and width properties, so they have to be handled separately.
    Last edited by Ellis Dee; May 22nd, 2008 at 07:29 PM.

  4. #4

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Example of Issues

    One issue is quite simple but often overlooked. Regardless of font sizing or screen resolution, the form's titlebar never changes size. Let's say your form is 100 pixels high with a 10 pixel titlebar, and you want to size the form 25% larger. If you simply up the form to 125 pixels, you've actually increased the height by 27.8%, not 25%. That's because the usable space of the form was increased from 90 pixels to 115, not 100 to 125. You have to resize the usable region, not the entire form.

    You really want it to end up 122 pixels, not 125. This may not seem like much of a difference, but it's not subtle when you see it in practice. Generally speaking, the bottom-most section of the form will seem out of proportion and awkward if you base the resizing on the form coordinates instead of the scale coordinates. In the picture below, the blank space under the row of command buttons is intended to be the same height as the space between them and the frame above.

    No matter how robust an automated routine is, there are still quirks that need to be handled on a form-by-form basis if you want a polished look. Look at the following form to see an example of several problematic issues that arise when you try to automate resizing:

    Name:  Resize.jpg
Views: 6748
Size:  14.1 KB

    This screen was designed in 1024x768 using Verdana 12. It was resized using the posted function and displayed in 800x600 resolution. Ignoring the previous-century color scheme, consider what exactly has to happen to resize this screen:
    • Resizing option buttons is a tricky affair. The graphical portion never changes size regardless of font, so that has to be taken into account. If you ignore that, then shrinking an option button can and will chop off some of the caption text. (Same idea as the form's titlebar issue described above.)
    • The "Rows" label is left-aligned to be directly under the caption of the option buttons. Note that it's off by one pixel; this is as close as I can seem to get it. Any help on this would be appreciated.
    • The "Rows" label has an etched appearance when disabled. This is achieved by using two label controls. One has normal text and transparent background. The second one has white text, and is placed behind the first one offset by one pixel below and to the right. This one pixel offset must never change, regardless of the font size.
    • The bottom of the text in the "Rows" label perfectly aligns with the bottom of the text in the "Rows" textbox.
    • The UpDown control interferes with resizing its buddy control, so it needs to be un-buddied before sizing, then the textbox needs to be wide enough to hold both its expected text and the buddy control. Only then can the UpDown be "buddied" to it.
    • The graphical command button shouldn't be resized at all.
    • The label describing the graphical command button should be centered vertically next to the command button.

    The utility function uses Advanced Features to handle unique cases. In order to engage the advanced features, you have to use the control's .Tag property. Unfortunately, if you are already using the .Tag property for something else, this presents a conflict.

    The first major hurdle in implementing advanced features is that the function needs to know which controls "belong" to each other. For example, which label goes with which textbox. In order to avoid making the programmer set Tag properties for every control, the TabIndex property is used. When the function iterates through all the controls on a form, it does so in TabIndex order, so be sure you have set the TabIndex properly. (Which you should always do regardless.)
    Last edited by Ellis Dee; May 23rd, 2008 at 06:59 PM.

  5. #5

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Advanced Features .Tag Codes

    The following .Tag codes are currently recognized:

    Fixed
    The control will not be resized, but it will be repositioned. This is useful for images, or any control that uses a graphic instead of text. (eg: Graphical-style Command Button)

    Multiline
    Some controls (Label, OptionButton, TextBox) are autosized based on the font width and/or height instead of absolute ratio. This can cause problems for multi-line controls that use word wrap. Use the Multiline tag to skip the font-based resizing and just use absolute resizing.

    Left
    If the previous control is an OptionButton or CheckBox, align with its caption left instead of the control's left. This lets you align "subitems."

    Right
    Position this control to the right of the previous control on the same line. If the control is a TextBox and the previous control is a Label, this setting will line them up vertically.

    Label
    If the previous control is a Label, this setting will move the label down slightly to align the text bottom.

    Etched
    Signifies an Etched label, which simulates the etched effect on disabled controls like checkboxes. To use this effect, set the main label's background to transparent, add a new label with the same caption, set its ForeColor to white, set its ZOrder behind the main label (send to back), and set its Tag property to Etched. Be sure the etched label is immediately after the main label in TabIndex order.
    Last edited by Ellis Dee; May 23rd, 2008 at 07:02 PM.

  6. #6

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    <reserved>
    Last edited by Ellis Dee; May 22nd, 2008 at 09:12 PM.

  7. #7

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Main Function - Part 1

    Even without the very long comments that go with the function, the function is too long to fit in a single post. So here are the comments that preface it, plus the first part of the function -- basically just declaration and initialization:
    vb Code:
    1. ' FormLayout()
    2. ' Resize a form and all its controls based on screen resolution.
    3. ' All controls are resized in TabIndex order. Advanced positioning lets you
    4. ' position a control based on the previous (in TabIndex order) control's
    5. ' newly resized coordinates. Set any control's Tag property to one of the
    6. ' following (without the quotes) to engage advanced positioning.
    7. ' "Fixed"
    8. '    The control will not be resized, but it will be repositioned.
    9. ' "Multiline"
    10. '    Some controls (Label, OptionButton, TextBox) are autosized
    11. '    based on the font width and/or height instead of the overall ratio,
    12. '    causing problems for multi-line controls that use word wrap. Use
    13. '    this to skip the font-based resizing and just use generic resizing.
    14. ' "Left"
    15. '    If the previous control is an OptionButton or CheckBox, align with
    16. '    its caption left. This lets you align "subitems".
    17. ' "Right"
    18. '    Position this control to the right of the previous control on the
    19. '    same line. If the control is a TextBox and the previous control is a
    20. '    Label, this setting will line them up vertically as well.
    21. ' "Label"
    22. '    If the previous control is a Label, this setting will move the label down
    23. '    slightly to align the text bottom.
    24. ' "Etched"
    25. '    Signifies an Etched label, which simulates the etched effect on
    26. '    disabled controls like checkboxes. To use this effect, set the main
    27. '    label's background to transparent, add a new label with the same
    28. '    caption, set its ForeColor to white, set its ZOrder behind the main
    29. '    label (send to back), and set its Tag property to Etched. Be sure
    30. '    the etched label is immediately after the main label in TabOrder.
    31. ' Parameters:
    32. ' pfrm
    33. '    The form to be resized.
    34. ' psngFontSize can be either:
    35. '     - The new font size for the form and all its controls. Font sizes can
    36. '       be multiples of 0.25.
    37. '     - A negative value (eg: -46) to calculate the new font size based on how
    38. '       many lines of text can fit on a full screen in the current resolution.
    39. '       46 lines (-46) results in nice compact text. 41 lines (-41) results
    40. '       in a nice looking larger font. This is a great setting to expose to
    41. '       the user in some way. (But don't show them negatives!)
    42. '
    43. ' Sample usage:
    44. '
    45. ' Private Sub Form_Load()
    46. '     FormLayout Me
    47. ' End Sub
    48. '
    49. Public Sub FormLayout(pfrm As Form, Optional ByVal psngFontSize As Single = -46)
    50.     Const Spacer = " "
    51.     Const OptionSpacer = "o"
    52.     Const CaptionLeftChar = " "
    53.     Const CaptionLeftOffset = 14
    54.     Dim sngOriginalFontSize As Single
    55.     Dim enScaleMode As ScaleModeConstants
    56.     Dim lngScaleLeft As Long
    57.     Dim lngScaleTop As Long
    58.     Dim lngScaleWidth As Long
    59.     Dim lngScaleHeight As Long
    60.     Dim lngLeft As Long
    61.     Dim lngTop As Long
    62.     Dim lngWidth As Long
    63.     Dim lngHeight As Long
    64.     Dim sngX As Single
    65.     Dim sngY As Single
    66.     Dim lngOldWidth As Long
    67.     Dim lngOldHeight As Long
    68.     Dim lngExtraWidth As Long
    69.     Dim lngExtraHeight As Long
    70.     Dim lngScreenHeight As Long
    71.     Dim lngLines As Long
    72.     Dim lngTabIndex() As Long
    73.     Dim i As Long
    74.     Dim iMax As Long
    75.     Dim ctl As Control
    76.     Dim ctlPrev As Control
    77.     Dim ctlEtched As Control
    78.     Dim lngSSTab As Long
    79.     Dim strCaption As String
    80.     Dim strCaptionPrev As String
    81.     Dim lngComboHeight As Long
    82.    
    83.     With pfrm
    84.         ' Remember starting font size (do nothing if it doesn't end up changing)
    85.         sngOriginalFontSize = .FontSize
    86.         ' Save scale settings so we can set ScaleMode to Twips, greatly simplifying things
    87.         enScaleMode = .ScaleMode
    88.         If enScaleMode = vbUser Then
    89.             lngScaleLeft = .ScaleLeft
    90.             lngScaleTop = .ScaleTop
    91.             lngScaleWidth = .ScaleWidth
    92.             lngScaleHeight = .ScaleHeight
    93.         End If
    94.         .ScaleMode = vbTwips
    95.         ' Get existing dimensions
    96.         lngOldWidth = .TextWidth(Spacer)
    97.         lngOldHeight = .TextHeight(Spacer)
    98.         lngExtraWidth = .Width - .ScaleWidth
    99.         lngExtraHeight = .Height - .ScaleHeight
    100.         ' Calculate new font size based on lines of text per screen
    101.         If psngFontSize < 0 Then
    102.             lngLines = Abs(psngFontSize)
    103.             lngScreenHeight = Screen.Height
    104.             .FontSize = 6 ' Arbitrary minimum size
    105.             ' Grow font until the screen holds < requested number of lines (one size too big)
    106.             ' (psngFontSize retains the previous value, so it'll end up with the correct size)
    107.             Do
    108.                 psngFontSize = .FontSize
    109.                 ' Font sizes have erratic increments; identify the next size up
    110.                 .FontSize = .FontSize + 0.25
    111.                 If psngFontSize = .FontSize Then .FontSize = .FontSize + 0.5
    112.                 If psngFontSize = .FontSize Then .FontSize = .FontSize + 0.75
    113.                 If psngFontSize = .FontSize Then .FontSize = .FontSize + 1
    114.                 If psngFontSize = .FontSize Then Exit Do
    115.             Loop Until lngScreenHeight \ .TextHeight(Spacer) < lngLines
    116.         End If
    117.         ' Commit to the new font size
    118.         .FontSize = psngFontSize
    119.     End With
    Last edited by Ellis Dee; May 21st, 2008 at 10:50 PM.

  8. #8

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Main Function - Part 2

    Here's the rest of the function:
    vb Code:
    1. '
    2.     ' Do nothing if font size hasn't changed
    3.     If pfrm.FontSize <> sngOriginalFontSize Then
    4.         With pfrm
    5.             ' Calculate ratios based on change in font size
    6.             sngX = .TextWidth(Spacer) / lngOldWidth
    7.             sngY = .TextHeight(Spacer) / lngOldHeight
    8.             ' Resize form
    9.             lngWidth = .ScaleWidth * sngX + lngExtraWidth
    10.             lngHeight = .ScaleHeight * sngY + lngExtraHeight
    11.             ' Center form if it was already centered, otherwise don't move it
    12.             If .Left <> (Screen.Width - .Width) \ 2 Then lngLeft = .Left Else lngLeft = (Screen.Width - lngWidth) \ 2
    13.             If .Top <> (Screen.Height - .Height) \ 2 Then lngTop = .Top Else lngTop = (Screen.Height - lngHeight) \ 2
    14.             .Move lngLeft, lngTop, lngWidth, lngHeight
    15.             ' Identify TabIndex order
    16.             iMax = .Controls.Count - 1
    17.         End With
    18.         If iMax >= 0 Then
    19.             ReDim lngTabIndex(iMax)
    20.             For Each ctl In pfrm.Controls
    21.                 ' Resize lines & shapes now because they don't have a TabIndex
    22.                 With ctl
    23.                     Select Case TypeName(ctl)
    24.                         Case "Line"
    25.                             ' Identify left offset (used for controls on an inactive SSTab tab)
    26.                             If TypeName(.Container) = "SSTab" And .X1 < -1500 Then lngSSTab = 75000 Else lngSSTab = 0
    27.                             .X1 = (.X1 + lngSSTab) * sngX - lngSSTab
    28.                             .X2 = (.X2 + lngSSTab) * sngX - lngSSTab
    29.                             .Y1 = .Y1 * sngY
    30.                             .Y2 = .Y2 * sngY
    31.                             iMax = iMax - 1
    32.                         Case "Shape", "Image"
    33.                             ' Identify left offset (used for controls on an inactive SSTab tab)
    34.                             If TypeName(.Container) = "SSTab" And .Left < -1500 Then lngSSTab = 75000 Else lngSSTab = 0
    35.                             .Move (.Left + lngSSTab) * sngX - lngSSTab, .Top * sngY, .Width * sngX, .Height * sngY
    36.                             iMax = iMax - 1
    37.                         Case Else
    38.                             On Error Resume Next
    39.                             lngTabIndex(.TabIndex) = i
    40.                             If Err.Number <> 0 Then iMax = iMax - 1
    41.                             On Error GoTo 0
    42.                             ' Identify ComboBox height
    43.                             If TypeOf ctl Is ComboBox And lngComboHeight = 0 Then
    44.                                 .FontSize = pfrm.FontSize
    45.                                 lngComboHeight = ctl.Height
    46.                             End If
    47.                     End Select
    48.                 End With
    49.                 i = i + 1
    50.             Next
    51.             ' Identify standard textbox height now to speed up loop
    52.             If lngComboHeight = 0 Then lngComboHeight = pfrm.TextHeight(Spacer) + 4 * Screen.TwipsPerPixelY
    53.             ' Iterate controls in TabIndex order
    54.             For i = 0 To iMax
    55.                 Set ctl = pfrm.Controls(lngTabIndex(i))
    56.                 Select Case TypeName(ctl)
    57.                     Case "OptionButton", "CheckBox": strCaption = Replace(Replace(Replace(ctl.Caption, "&&", "~"), "&", ""), "~", "&")
    58.                 End Select
    59.                 If i <> 0 Then
    60.                     Set ctlPrev = pfrm.Controls(lngTabIndex(i - 1))
    61.                     Select Case TypeName(ctlPrev)
    62.                         Case "OptionButton", "CheckBox": strCaptionPrev = Replace(Replace(Replace(ctlPrev.Caption, "&&", "~"), "&", ""), "~", "&")
    63.                     End Select
    64.                     If ctl.Tag = "Etched" Then Set ctlEtched = pfrm.Controls(lngTabIndex(i - 1))
    65.                 End If
    66.                 With ctl
    67.                     ' Identify left offset (used for controls on an inactive SSTab tab)
    68.                     If TypeName(.Container) = "SSTab" And .Left < -1500 Then lngSSTab = 75000 Else lngSSTab = 0
    69.                     ' Identify current dimensions
    70.                     lngLeft = .Left + lngSSTab
    71.                     lngTop = .Top
    72.                     lngWidth = .Width
    73.                     lngHeight = .Height
    74.                     ' LEFT
    75.                     Select Case .Tag
    76.                         Case "Left"
    77.                             Select Case TypeName(ctlPrev)
    78.                                 Case "OptionButton", "CheckBox": lngLeft = ctlPrev.Left + CaptionLeftOffset * Screen.TwipsPerPixelX + pfrm.TextWidth(CaptionLeftChar)
    79.                                 Case Else: lngLeft = ctlPrev.Left
    80.                             End Select
    81.                         Case "Right"
    82.                             Select Case TypeName(ctlPrev)
    83.                                 Case "OptionButton", "CheckBox": lngLeft = ctlPrev.Left + (CaptionLeftOffset + 1) * Screen.TwipsPerPixelX + pfrm.TextWidth(strCaptionPrev) + pfrm.TextWidth(OptionSpacer)
    84.                                 Case Else: lngLeft = ctlPrev.Left + ctlPrev.Width + pfrm.TextWidth(Spacer)
    85.                             End Select
    86.                         Case "Etched": lngLeft = ctlPrev.Left + Screen.TwipsPerPixelX
    87.                         Case Else: lngLeft = lngLeft * sngX
    88.                     End Select
    89.                     ' TOP
    90.                     Select Case .Tag
    91.                         Case "Etched": lngTop = ctlPrev.Top + Screen.TwipsPerPixelY
    92.                         Case Else: lngTop = lngTop * sngY
    93.                     End Select
    94.                     ' WIDTH
    95.                     Select Case .Tag
    96.                         Case "Fixed"
    97.                         Case "MultiLine": lngWidth = lngWidth * sngX
    98.                         Case "Etched": lngWidth = ctlPrev.Width
    99.                         Case Else
    100.                             Select Case TypeName(ctl)
    101.                                 Case "OptionButton", "CheckBox": lngWidth = CaptionLeftOffset * Screen.TwipsPerPixelX + 2 * pfrm.TextWidth(CaptionLeftChar) + pfrm.TextWidth(strCaption)
    102.                                 Case "TextBox": If .MaxLength <> 0 Then lngWidth = pfrm.TextWidth("8") * (.MaxLength + 1) Else lngWidth = lngWidth * sngX
    103.                                 Case Else: lngWidth = lngWidth * sngX
    104.                             End Select
    105.                     End Select
    106.                     ' HEIGHT
    107.                     Select Case .Tag
    108.                         Case "Fixed"
    109.                         Case "MultiLine": lngHeight = lngHeight * sngY
    110.                         Case "Etched": lngHeight = ctlPrev.Height
    111.                         Case Else
    112.                             Select Case TypeName(ctl)
    113.                                 Case "OptionButton", "CheckBox": lngHeight = lngComboHeight
    114.                                 Case "ListBox"
    115.                                     lngLines = ctl.Height \ lngOldHeight
    116.                                     lngHeight = pfrm.TextHeight(Spacer) * lngLines + ctl.Height - (lngLines * lngOldHeight)
    117.                                 Case "TextBox": lngHeight = lngComboHeight
    118.                                 Case Else: lngHeight = lngHeight * sngY
    119.                             End Select
    120.                     End Select
    121.                     ' Apply new formatting
    122.                     On Error Resume Next
    123.                     .Font.Size = pfrm.FontSize
    124.                     On Error GoTo 0
    125.                     Select Case TypeName(ctl)
    126.                         Case "Label"
    127.                             Select Case .Tag
    128.                                 Case "MultiLine", "Etched"
    129.                                 Case Else
    130.                                     .AutoSize = True
    131.                                     lngHeight = .Height
    132.                                     Select Case .Alignment
    133.                                         Case vbRightJustify: If lngWidth < .Width Then lngLeft = lngLeft - (.Width - lngWidth)
    134.                                         Case vbCenter: If lngWidth < .Width Then lngLeft = lngLeft - (.Width - lngWidth) \ 2
    135.                                     End Select
    136.                                     lngWidth = .Width
    137.                             End Select
    138.                             .Move lngLeft, lngTop, lngWidth, lngHeight
    139.                         Case "ComboBox"
    140.                             lngComboHeight = .Height
    141.                             .Move lngLeft, lngTop, lngWidth
    142.                         Case Else
    143.                             .Move lngLeft, lngTop, lngWidth, lngHeight
    144.                     End Select
    145.                     ' Check for vertical align
    146.                     If i <> 0 Then
    147.                         If TypeOf ctlPrev Is Label Then
    148.                             Select Case .Tag
    149.                                 Case "Label", "Right"
    150.                                     ' If previous control is an Etched label, move both labels
    151.                                     If ctlPrev.Tag = "Etched" Then
    152.                                         ctlEtched.Top = ctl.Top + 3 * Screen.TwipsPerPixelY
    153.                                         ctlPrev.Top = ctlEtched.Top + Screen.TwipsPerPixelY
    154.                                     Else
    155.                                         ctlPrev.Top = ctl.Top + 3 * Screen.TwipsPerPixelY
    156.                                     End If
    157.                             End Select
    158.                         End If
    159.                     End If
    160.                 End With
    161.                 Set ctl = Nothing
    162.             Next
    163.             Set ctlPrev = Nothing
    164.             Set ctlEtched = Nothing
    165.         End If
    166.     End If
    167.     ' Reset ScaleMode to original settings
    168.     With pfrm
    169.         If enScaleMode = vbUser Then
    170.             .ScaleLeft = lngScaleLeft
    171.             .ScaleTop = lngScaleTop
    172.             .ScaleWidth = lngScaleWidth
    173.             .ScaleHeight = lngScaleHeight
    174.         Else
    175.             .ScaleMode = enScaleMode
    176.         End If
    177.     End With
    178. End Sub
    Last edited by Ellis Dee; May 21st, 2008 at 10:50 PM.

  9. #9

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    <reserved>

  10. #10

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    Comments, questions, corrections, and requests are welcome.

  11. #11
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Scaling your form independent of screen resolution

    Wow, looks like you spent a good deal of time on this, not just the bas module but also your posts explaining it. A working example (with a form) would probably help beginners.

    Good stuff.

  12. #12
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: Scaling your form independent of screen resolution

    Getting a Variable not defined: glngHeight

    Public Function GetFontSize,
    @ line, If glngHeight <> 0 Then lngHeight = glngHeight

  13. #13

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    Quote Originally Posted by Edgemeal
    Getting a Variable not defined: glngHeight

    Public Function GetFontSize,
    @ line, If glngHeight <> 0 Then lngHeight = glngHeight
    Oops, my bad. You can just delete that line; it shouldn't be in there.

    It's a public variable used for debugging purposes only. That line allows you to see how it will look in other screen resolutions by setting it to the height in pixels of the resolution you want to test.

    So if you set it to 768, it'll resize as if it's in 1024x768 resolution, 1024 will give you the results for 1280x1024, etc...

    I'll reattach the module with the correction.

  14. #14
    Software Carpenter dee-u's Avatar
    Join Date
    Feb 2005
    Location
    Pinas
    Posts
    11,123

    Re: Scaling your form independent of screen resolution

    Hi Ellis, any demo with sample form? If I designed my form in 800x600 screen then what should I do for it to work in 1024x768 screen?
    Regards,


    As a gesture of gratitude please consider rating helpful posts. c",)

    Some stuffs: Mouse Hotkey | Compress file using SQL Server! | WPF - Rounded Combobox | WPF - Notify Icon and Balloon | NetVerser - a WPF chatting system

  15. #15

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    Try putting FormLayout Me in the Form_Load() event and see how it looks. You can play around with the font size by specifying the (negative) number of lines to fit on the screen. The default is 46. Meaning the following two lines are identical:

    FormLayout Me
    FormLayout Me, -46

    If you specify a positive number it will use the number itself for the font size, which isn't what you want. Instead, use a negative number to specify the number of lines to fit on a screen:

    FormLayout Me, -44 ' a little bigger
    FormLayout Me, -48 ' a little smaller

  16. #16
    Software Carpenter dee-u's Avatar
    Join Date
    Feb 2005
    Location
    Pinas
    Posts
    11,123

    Re: Scaling your form independent of screen resolution

    I cannot find the difference when I used the method. Have a look at the attached zip file, I used my own function, the form is supposed to have been design in 800x600 resolution and it will scale to that size when it is used in larger resolutions. I supposed that is how your method should work?
    Attached Files Attached Files
    Regards,


    As a gesture of gratitude please consider rating helpful posts. c",)

    Some stuffs: Mouse Hotkey | Compress file using SQL Server! | WPF - Rounded Combobox | WPF - Notify Icon and Balloon | NetVerser - a WPF chatting system

  17. #17

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    The problem is that MS Sans Serif doesn't scale very well. If you look at its valid sizes, there is a much smaller range than there is with other more robust fonts. I prefer Verdana myself.

    MS Sans Serif sizes: 8, 10, 12, 14, 18, 24
    Verdana sizes: 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72

    The problem (when using MS Sans Serif) is in the font scaling section, which is at the end of the first code box upthread. This section of code is:
    Code:
                Do
                    psngFontSize = .FontSize
                    ' Font sizes have erratic increments; identify the next size up
                    .FontSize = .FontSize + 0.25
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 0.5
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 0.75
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 1
                    If psngFontSize = .FontSize Then Exit Do
                Loop Until lngScreenHeight \ .TextHeight(Spacer) < lngLines
    The problem is that it never adds more than 1 at a time, and if that doesn't register a change the function aborts and does nothing. Since the jump from 8 (8.25) to 10 (9.75) is more than 1, nothing ever happens. The fix is to add a couple more lines to that loop like so:
    Code:
                Do
                    psngFontSize = .FontSize
                    ' Font sizes have erratic increments; identify the next size up
                    .FontSize = .FontSize + 0.25
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 0.5
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 0.75
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 1
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 1.5
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 2
                    If psngFontSize = .FontSize Then .FontSize = .FontSize + 3
                    If psngFontSize = .FontSize Then Exit Do
                Loop Until lngScreenHeight \ .TextHeight(Spacer) < lngLines
    This should probably be in there always, but I'm comfortable not updating the original code because IMO using a sparsely-sized font like MS Sans Serif is contraindicated when designing scalable forms.

  18. #18
    Addicted Member
    Join Date
    Aug 2008
    Posts
    136

    Re: Scaling your form independent of screen resolution

    i'm sorry i don't understand this..
    what do you mean ellis?
    do you mean my app which i made on my 1280x960 screen resolution will look ugly on other screen resolution?
    i test my app on my brother's laptop which the screen resolution is 1366x768, and everything looks fine..

    what am i missing here?

  19. #19

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    Those are basically the same resolutions. How does it look on 800x600?

    If you use MS Sans Serif, there are very few different sizes you can use, meaning when you switch to radically different resolutions it won't look very good. A more scalable font like Verdana or Tahoma would be better.

  20. #20
    New Member
    Join Date
    Feb 2010
    Posts
    1

    Re: Scaling your form independent of screen resolution

    Does your function work with MDI forms?

  21. #21

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Scaling your form independent of screen resolution

    Great question. I've never worked with MDI forms so I can't say for sure either way.

  22. #22
    New Member
    Join Date
    Oct 2012
    Posts
    1

    Re: Scaling your form independent of screen resolution

    I know this thread is dead and sorry for bothering you all but could someone please help or preferably post a working example of this code, because I try integrating the code 'FormLayout Me' in each form and it simply does not affect the form.

    thanks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width