SftTabs/OCX 6.5 FAQs

Can I hide the built-in scroll buttons and use my own buttons instead, but still have a scrollable tab control?

Sure! You can accomplish this by setting the SftTabsScrolling.Style property to scrollSftTabsHide (5). This will hide the built-in scroll buttons.  You can now supply your own buttons on the form (or how about our SftButton/OCX control?). In the event handlers of your own buttons, you can use the Scrolling.Scroll method to scroll left/right (or up/down).

The Scrolling.LeftButton and Scrolling.RightButton properties can be used to keep your buttons enabled and disabled as needed.

Can I add controls to a tab page dynamically?

Adding controls dynamically is easily done. However, individual tab pages don't each have their own container. Instead, all new objects are added to SftTabs as the container. Any controls added dynamically become part of the tab page that is active at that time. The tab page can be changed using the Current property.

For a simple sample, create a new VB project. On a blank form, add a SftTabs tab control named SftTabs and a button named Command1. Copy the following code:

Dim ButtonCount As Integer

Private Sub Command1_Click()
    Dim cmdObject As CommandButton
    ButtonCount = ButtonCount + 1
    Set cmdObject = Form1.Controls.Add("VB.CommandButton", _
            "Button" & ButtonCount)
    Set cmdObject.Container = SftTabs1
    cmdObject.Left = 500 * Count
    cmdObject.Top = 500 * Count
    cmdObject.Visible = True
    cmdObject.ZOrder 0
End Sub

Each time the button (Command1) is clicked, a blank button control is added to the current tab page.

Why do controls that I resize at runtime not keep the size I define?

When resizing controls at run-time, you may observe that controls are positioned incorrectly on the form as you switch between tabs, or they may disappear altogether.

Typically, this occurs when controls are resized at run-time, in the tab control's Resized event for example.

SftTabs/OCX uses a simple and foolproof mechanism to keep track of control positions as tab pages are hidden. When a tab page is not the current page, the controls on that page are hidden by moving them outside of the form. Rather than saving each control's position (the Left, Top, Width, Height properties), the controls are simply repositioned using the following formula:

(Hidden)Left = -1000-Left-Width
(Hidden)Top = -1000-Top-Height

To recover the original position when the tab page becomes active again, the following is used:

Left = -1000 - (Hidden)Left - Width
Top = -1000 - (Hidden)Top - Height

This scheme is quite simple and SftTabs does not have to save or maintain any control positions or other information. Each control maintains its own information which is reflected in its present position. Any Left/Top properties <= -1000 indicate that a control is hidden and the original position can be extracted using the above formula.  Left/Top properties > -1000 are left as-is.

This scheme does have the side effect that changes to a control's width and height or position (while it is hidden) will cause the control to be positioned incorrectly when it becomes visible.

There are two possible methods to avoid incorrect positioning:

  • Only resize visible controls while the tab page is the current page (indicated by a control's Left/Top properties > -1000)
  • Resize a hidden control, but at the same time adjust its Left/Top properties, so the above formulas will position it correctly. Basically this means any addition to the Height or Width property has to be offset by subtracting the same amount from the Top or Left property. (A hidden control is a control with Left/Top properties <=  -1000).
How does the Switching event work?

The Switching event is invoked whenever a new tab is about to become active.

The main function of this event is to validate any input data on the current page (about to be replaced by a new page). The Allow parameter can be set to True to allow the next page to become active or False to stay on the current page.

If a message box is displayed or the input focus shifts away from the tab control while the Switching event is being processed, tab switching is aborted and the current tab remains the active tab (i.e. Allow is implicitly set to False and any value specified by the application is ignored).

In most cases, this default processing is exactly what is intended.  However, there may be cases where the new tab should become active (even if validation fails).  For example, a message box is displayed such as "Are you sure?" or similar.  The message box (by definition) cancels tab switching.  After the message box, setting Allow to True has no effect, as tab switching has already been canceled (due to the input focus shifting away from the tab control).

There is an easy way to "force" the tab control to switch to the new tab.  The key is to perform the switch after the Switching event has completed (of course, the "old" tab page is still displayed).  This can be easily accomplished using a Timer control.  In the Switching event, a timer is set which will fire as soon as tab switching (the Switching event) has ended.  The following is a sample Switching event.  A timer control (Timer1) has been added to the form. Some properties are explicitly set at run-time to show that they are being used.  These can of course also be set at design-time.

Option Explicit

Private Sub Form_Load()
    ' disable the timer
    Timer1.Enabled = False
    ' make it a very fast timer
    Timer1.Interval = 1
    ' mark the Tag property as "no next page"
    Timer1.Tag = -2
End Sub

Private Sub SftTabs1_Switching(NextTab As Integer, Allow As _
           Boolean, Refresh As Boolean)
    Dim result As Integer

    ' check if this is a Switching event caused by the timer event
    If Timer1.Tag < -1 Then
        ' The user is switching the tab page
        result = MsgBox("Are you sure?", vbYesNoCancel)
        ' tab switching has just been canceled because of the message 
        ' box
        ' now analyze the user's response, we may have to explicitly
        ' switch
        If result = vbYes Then
            ' The following won't work, as the Current property is
            '  not available during the Switching event
            'SftTabs1.Tabs.Current = NextTab
            ' SftTabs/OCX 3.0: the CurrentTab property also cannot
            ' be used

            ' Set up the timer, so we can switch right after this  
            ' event ends save the next tab index in the Tag property
            Timer1.Tag = NextTab
            ' enable the timer
            Timer1.Enabled = True
            ' actually already cancelled, this really isn't needed 
            ' for SftTabs/ATL 3.5
            ' however, if you're using SftTabs/OCX 3.0 you must set 
            ' Allow to False
            Allow = False
        End If
        ' The timer event is causing this tab switch
        ' simply allow it
        Allow = True
    End If
End Sub

Private Sub Timer1_Timer()
    ' we need to switch to a new tab
    ' disable the timer so it won't happen again
    Timer1.Enabled = False
    ' switch to the new tab, we saved the index in the Tag property
    ' use CurrentTab for SftTabs/OCX 3.0
    SftTabs1.Tabs.Current = Timer1.Tag
    ' we're done switching, "forget" the next tab
    Timer1.Tag = -2
End Sub