Previous | Index | Next 

[PRB] Assignments to Font properties generate runtime errors in late-bound mode

Most VB6 controls expose the Font property, which in turn returns a StdFont object whose properties (Name, Size, Italic, Bold, Underline, etc.) are writable. The corresponding .NET Font object is very similar to the VB6 Font, however its properties are read-only.

If the control is referenced in early-bound mode, VB Migration Partner correctly recognizes this potential issue and generates a reference to a helper method, such as FontChangeName6 or FontChangeSize6, as in this case:

        ' original VB6 code
        Text1.Font.Bold = True
  
        ' migrated VB.NET code
        SetFontBold6(Text1.Font, True)

However, if the control is accessed in late-bound mode, VB Migration Partner cannot detect that a replacement is necessary, and leaves the code unmodified. In this case, when the assignment is attempted at runtime, an exception occurs. An example of late-bound access occurs when iterating on all the controls of a form

        Dim ctrl As Object 
        For Each ctrl In Me.Controls
            ctrl.Font.Bold = True
        Next

There are a couple ways to modify VB Migration Partner’s default behavior.

First, you can let VB Migration Partner know that the ctrl is actually a control, by means of the AssumeType pragma, as in this example:

        '## ctrl.AssumeType TextBox
        Dim ctrl As Object
        For Each ctrl In Me.Controls
            ctrl.Font.Bold = True
        Next

Notice that here we use TextBox, but any control class name will do to solve the problem. The result is:

        Dim ctrl As Object
        For Each ctrl In Me.Controls6
            ChangeFontBold6(ctrl.Font, True)
        Next 

Second, if there are just too many occurrences of late-bound control references and you don’t want to insert one AssumeType pragma for each occurrence, you can try a PostProcess pragma that automatically replaces all assignments in current project:

        ' this comment goes in a single line
        '## PostProcess "\b(?<ctrl>.+?)\.Font\.(?<prop>Name|Size|Bold|Italic|Underline)\s*
              =\s*(?<value>.+?)(?=\r\n)",
              "FontChange${prop}6(${ctrl}.Font, ${value})"

Notice that this pragma doesn’t work for the Strikethrough property, for which you require a separate pragma:

        '## PostProcess "\b(?<ctrl>.+?)\.Font\.Strikethrough\s*=\s*(?<value>.+?)(?=\r\n)",
              "FontChangeStrikeout6(${ctrl}.Font, ${value})"

 

Previous | Index | Next