Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1529

[VB6] UserControl Ambient.UserMode workaround

$
0
0
For you usercontrol (UC) creators out there. Everyone else -- won't apply to you.

Ambient.UserMode tells us whether the UC's container is in design mode or user mode/run-time. Unfortunately, this isn't supported in all containers. Word, IE may not report what you expect. Some containers may not implement that property.

VB always implements the Ambient.UserMode property. However, that can be misleading. If you have a UC on a form in design view, UC says Ambient.UserMode = False; great. But if you are creating a new UC and inside that new UC, you add an existing/different UC, that inner UC will report False also; great because this new UC is in design view. Here's the kicker. Now you add that new UC to the form. The inner UC now reports Ambient.UserMode as True, even though the form is in design view

Is this a problem for you? Maybe, only if you are actually testing that property. Let's say you use that property to determine whether or not to start subclassing, whether to start some image animation, maybe start API timers, whatever. You designed your control to not do that if the UC's container is in design view. Works well until your control is placed in another control that is placed on some other container. When your control (compiled or not) is a grandchild, container-wise, it will report Ambient.UserMode as True within VB. Other containers may report different things. The suggestion below allows your customer/user to override and properly set that property.

Let me use a real world example. I designed an image control. That control has a property to begin animation when the UC is in run-time. Well, someone wanted to add my control to a custom UC they were designing. They wanted the animation to occur when their new UC was in run-time. Animation started when their UC was placed on a form in design-time. Not what they wanted. Since my control had a property to start/stop animation, the simple solution was to default not to start animation and also for their UC to check its own Ambient.UserMode and depending on its value, start animation.

This worked well. But what if my UC began doing stuff when its Ambient.UserMode was True, but had no way for the containing control to tell it to stop or don't start at all? That containing control is out of luck.

The following is a workaround that if became a template for all your UCs, you can avoid this problem in any UC you create. Any paying customers for your UC can be educated to the new property and how to use it for their purposes.

Here is a sample of the 'template'. It exposes a Public UserMode property that allows the UC's container to dictate/tell the UC what UserMode it should use. This could be ideal for other non-VB6 containers that either report incorrectly or don't report at all the Ambient.UserMode.

Code:

Public Enum AmbientUserModeENUM
    aumDefault = 0
    aumDesignTime = 1
    aumRuntime = 2
End Enum
Private m_UserMode As AmbientUserModeENUM

Public Property Let UserMode(newVal As AmbientUserModeENUM)
    If Not (newVal < aumDefault Or newVal > aumRuntime) Then
        m_UserMode = newVal
        Call pvCheckUserMode
        PropertyChanged "UserMode"
    End If
End Property
Public Property Get UserMode() As AmbientUserModeENUM
    UserMode = m_UserMode And &HFF
End Property

Private Sub pvCheckUserMode()
    Select Case (m_UserMode And &HFF)
    Case aumDefault
        m_UserMode = (m_UserMode And &HFF) Or UserControl.Ambient.UserMode * &H100&
    Case aumRuntime
        m_UserMode = (m_UserMode And &HFF) Or &H100
    Case Else
        m_UserMode = m_UserMode And &HFF
    End Select
   
    If (m_UserMode And &H100) Then  ' user mode is considered True
        ' do whatever is needed. Maybe set the UserMode property of any child usercontrols

    Else                            ' user mode is considered False
        ' do whatever is needed. Maybe set the UserMode property of any child usercontrols

    End If

End Sub


Private Sub UserControl_InitProperties()
    ' set any new control, initial properties
   
    ' apply any actions needed for UserMode
    Call pvCheckUserMode
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    ' read all written properties

    ' apply any actions needed for UserMode
    m_UserMode = PropBag.ReadProperty("AUM", aumDefault)
    Call pvCheckUserMode
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    PropBag.WriteProperty "AUM", (m_UserMode And &HFF), aumDefault
End Sub

Though the call to pvCheckUserMode is placed in Init/ReadProperties, it could be moved to UserControl_Show if desired, depending on your needs.

Viewing all articles
Browse latest Browse all 1529

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>