Looping all controls in window and changing font

i am current using the following code to loop through all the controls in a window and setting the fonts. Is there an easier way to do this and making sure it does not do anything on control that does not have a fontetxt properties.

  j=vForm.controlcount - 1
  for i = 0 to j
    vctrl=vForm.Control(i)
    IF vCtrl IsA PushButton then
      //**********************
      // PushButton
      //**********************
      #IF TargetMacOS THEN
        PushButton(vctrl).TextFont=gFontTextMMac
      #ELSEIF TargetWin32 THEN
        PushButton(vctrl).TextFont=gFontTextMWin
      #ENDIF
    ELSEIF  vCtrl IsA Label then
      //**********************
      //Label
      //**********************
        #IF TargetMacOS THEN
          label(vCtrl).TextFont=gFontTextMMac
        #ELSEIF TargetWin32 THEN
          label(vCtrl).TextFont=gFontTextMWin
        #ENDIF
    ELSEIF vCtrl isa TextField then
      //**********************
      // TextField
      //**********************
      #IF TargetMacOS THEN
        TextField(vctrl).TextFont=gFontTextMMac
      #ELSEIF TargetWin32 THEN
        TextField(vctrl).TextFont=gFontTextMWin
      #ENDIF
   ELSEIF vCtrl isa Listbox then
      //**********************
      // Listbox
      //**********************
      #IF TargetMacOS THEN
        Listbox(vctrl).TextFont=gFontTextMMac
      #ELSEIF TargetWin32 THEN
        Listbox(vctrl).TextFont=gFontTextMWin
      #ENDIF
    ELSEIF vCtrl isa TextArea then
      #IF TargetMacOS THEN
        TextArea(vctrl).TextFont=gFontTextMMac
      #ELSEIF TargetWin32 THEN
        TextArea(vctrl).TextFont=gFontTextMWin
      #ENDIF
    ELSEIF vCtrl IsA ComboBox then
      //**********************
      // ComboBox
      //**********************
      #IF TargetMacOS THEN
        ComboBox(vctrl).TextFont=gFontTextMMac
      #ELSEIF TargetWin32 THEN
        ComboBox(vctrl).TextFont=gFontTextMWin
      #ENDIF
    ELSEIF vCtrl IsA CheckBox then
      //**********************
      // Checkbox
      //**********************
      #IF TargetMacOS THEN
        CheckBox(vctrl).TextFont=gFontTextMMac
      #ELSEIF TargetWin32 THEN
        CheckBox(vctrl).TextFont=gFontTextMWin
      #ENDIF
    end if
    
  Next

why duplicate this code so many times?

 #IF TargetMacOS THEN
        CheckBox(vctrl).TextFont=gFontTextMMac
      #ELSEIF TargetWin32 THEN
        CheckBox(vctrl).TextFont=gFontTextMWin
      #ENDIF

why not


  j=vForm.controlcount - 1
   #IF TargetMacOS THEN
      fnt==gFontTextMMac
      #ELSEIF TargetWin32 THEN
        fnt=gFontTextMWin
      #ENDIF
  for i = 0 to j
    vctrl=vForm.Control(i)
    IF vCtrl IsA PushButton then
      //**********************
      // PushButton
      //**********************
        PushButton(vctrl).TextFont=fnt
    ELSEIF  vCtrl IsA Label then
      //**********************
      //Label
      //**********************
          label(vCtrl).TextFont=fnt
    ELSEIF vCtrl isa TextField then
 

etc, etc, etc.
    end if
    
  Next

Rather than using the #if #then all over the place I would make a global method GetFont that returns the proper font (the global method would check to see what platform it is). All the #if statements make code harder to read (in my opinion).

If you are using containers, this loop won’t do anything for them.

I’m also wondering if it wouldn’t be better to subclass your controls and in their open event just have them select the right font for themselves. This has the advantage that they can be wherever (window/container) and still change accordingly.

Just wondering, but would a dynamic constant work?

Set the font property in the IDE to the constant, then use platform specific ability of the constant to return the proper font?

What a brilliant idea Bob… i already subclass the control anyway, i can simply do that instead.
Tim, i will try you suggestion.

Why didn’t i though of that???

or use introspection to do it in an extends method once :stuck_out_tongue:

how do i do that Norman???

Something like this

In a module define a global method as

Sub setFont(extends rc as rectcontrol, theFont as string)
  dim ti as Introspection.TypeInfo = Introspection.GetType( rc )
  
  if ti <> nil then
    
    dim pi() as Introspection.PropertyInfo = ti.GetProperties()
    
    for i as integer = 0 to pi.Ubound()
      
      if pi(i).Name = "TextFont" then
        pi(i).Value(rc) = theFont
      end if
      
    next
    
  end if
End Sub

Then on the window just loop over all the rectcontrols calling setfont with whatever the new font name is like

Sub setFont(theFontName as String)
  for i as integer = 0 to Window1.ControlCount - 1
    
    if Window1.control(i) isA RectControl then
      dim rc as RectControl = RectControl(Window1.Control(i))
      
      rc.SetFont(theFontName)
      
    end if
    
  next
End Sub

handles all rectcontrols that have a textfont property - base or subclasses

THANKS Norman, that work great… and so much easier.

can this work on SegmentedControl??