Part III - Implement the cControl_EventHandler_WebTabControl Class

In this part, we'll implement an event handler class to manage the custom events sourced in the cControl_WebTabControl class.


Step 1 - Create the EventHandler class

Step 2 - Source the OnShowPage() Event

Step 3 - Sink the OnShowPage() Event

Step 4 - Create the Custom Callback Class

Step 5 - Modify the Form-Level Code

Step 1 - Create the EventHandler class

  1. Right-click in the Project Explorer pane of the VBA Editor Window and select Insert -> Class Module.
  2. Rename the new class module to cControlEventHandlerWebTabControl.
  3. Open the class module, cControl_EventHandler_TEMPLATE.
  4. Select All text CTRL+A, and copy CTRL+C.
  5. Open the class module, cControl_EventHandler_WebTabControl.
  6. Select All text, and paste CTRL+V,

Make the following code changes:

1. In the following line in the declarations section, highlight SourceCtrlType_ and press CTRL+H:
Private WithEvents o As SourceCtrlType_ 'must replace with an event-capable object
2. In the dialog box, in the Replace All dropdown, type cControl_WebTabControl and select Replace All. Two replacements will be made.
3. With the Replace dialog still open, type ControlType_ in the Find What dropdown, and cControl_EventHandler_WebTabControl in the Replace With dropdown. Replace all occurences. Two replacements will be made. Close the Replace dialog
4. Then, change the following code in the Initialize() procedure:
    With asGeneric(m_oRef)
        If .ControlType = ccControl_Generic Then
            Set o = .Control                 'Control, Form, Report, Section
            Set .ParentEventHandler = Me
            Set o = ctl
        End If
    End With

Delete everything but the line Set o = ctl

6. Add the following code to the Select...Case...End Select logic of the GetHandler() function in the Support_CompositeControlManager module:
    Case ccControl_EventHandler_WebTabControl

           Set GetHandler = New cControl_EventHandler_WebTabControl

7. Add the enurmant for the cControl_EventHandler_WebTabControl to the cControlType enumeration in the Support_Globals function. By convention, the cControl_EventHandler enumerant is a value of 1000 great than it's corresponding cControl enumerant. Thus, the following line needs to be added:
ccControl_EventHandler_WebTabControl = 2500

8. Modify the creation function, CreateWebTabControl() in the Support_WebTabControl module by changing the line
.AttachToEventHandler CreateEventHandler(CreateGenericReference(.Control.Parent, ccForm), False)
to read
.AttachToEventHandler CreateEventHandler(WebTC)
Note that what we're doing is rather than attach the cControl_WebTabControl object directly to the form event handler, we're attaching it to it's own event handler - the class we just created. The CreateEventHandler() function will then, automatically, attach the cControl_EventHandler_WebTabControl object we're creating to the Form event handler object.

9. Save the project before continuing.


Step 2 - Source the OnShowPage() Event

Now we'll add a custom event, OnShowPage() to our control and trap it in the control's event handler.

1. First, we need to source the OnShowPage() event in our control class, cControl_WebTabControl. In the declarations section, add the line:
Public OnShowPage As String
Note that this is just a public property like the properties in most Access ActiveX controls. These properties are set to the value, "[Event Procedure]" to indicate the event is sunk in VBA code. While it is not strictly necessary in the case of a custom event, we provide this equivalent functionality because the event initialization routine in the cControlChild_Event class expects it.

2. Then add the line:
Public Event OnShowPage(PrevPage As Integer, NextPage As Integer)
in the declaration of our custom event, we're passing two parameters, PrevPage and NextPage. These values, as their names suggest, contain the PageIndex values of the visible pages before and after the page change.

3. Now, find the callback procedure, ShowPage() and add the RaiseEvent code to the procedure. The procedure should read as follows:
Public Sub ShowPage(handler As cControl_WebButton)

    Dim PageIndex As Integer
    PageIndex = handler.CommandButton.Tag
    RaiseEvent OnShowPage(o.Value, PageIndex)
    If PageIndex <> o.Value Then
        o.Value = PageIndex
    End If

End Sub

Note that in many cases, it is likely the RaiseEvent code would be added in an event trap for the ActiveX control, rather than in a callback function as we have done here. In fact, we could have trapped the TabControl's OnChange() event and done so here, but that would require an extra function call, and would not permit us to execute the OnShowPage() event before the actual page change took place. In this case, we have made it possible to trap the page changing before it is changed, allowing callback functions to be assigned that can prepare controls on the next page before the page is displayed. For greater granularity, we could have forgone the OnShowPage() event in lieu of two events, {BeforeShowPage()}} and AfterShowPage, which, of course, would get called before and after the assignment of o.Value.

4. Now save your work.


Step 3 - Sink the OnShowPage() Event

Finally, we'll sink the OnShowPage() event in our control event handler, cControl_EventHandler_WebTabControl

1. Open the event handler class module and in the declarations section, find the Public OnEvent As cControlChild_Event statement. Highlight "OnEvent" and replace all occurrences (CTRL+H) with "OnShowPage"

2. Select the dropdown at the top left of the VBA Editor's main window, and select the class member, "o". Then, in the top right dropdown, choose the "OnShowPage" event. The corresponding code will be automatically added to the module.

3. In the event procedure, add the following code:
Private Sub o_OnShowPage(nOldPage As Integer, nNewPage As Integer)

    If (OnShowPage.IsActive) Then
        RunCallbacks m_oRef, OnShowPage, nOldPage, nNewPage

    End If
End Sub

Note that the IsActive property tells us whether or not the OnShowPage() event has been initialized. In the Composite Controls Object Model, a control event is not initialized unless there is at least one callback function assigned to it, or the event initialization is forced by design.


Step 4 - Create the Custom Callback Class

Now that we've sourced our custom event to the cControl class and sunk it in the cControl_EventHandler class, we need to test it using a cCallbacks class.

1. Insert a new class and rename it cMyCallbacks.
2. Copy the code in the cCallbacks_TEMPLATE class module and paste it in the class module we just created. Be sure to overwrite the Option Explicit statement!
3. In the new class module, highlight the name of the first procedure, "MyFullsignatureCallback", and replace all occurrences with "ShowPageCallback".
4. In the ShowPageCallback() procedure, add the following code:
Private Sub ShowPageCallback(handler As iControl_Base, eventname As String, val1 As Variant, val2 As Variant, val3 As Variant, val4 As Variant)

    MsgBox "Handler: " & handler.Name & vbCrLf & _
    "Event: " & eventname & vbCrLf & vbCrLf & _
        "Previous Page Index: " & CStr(val1) & vbCrLf & _
        "Next Page Index: " & CStr(val2)

End Sub

Note that we are reporting the name of the handler which sourced the event (this is the cControl_WebTabControl object, not the cControl_EventHandler_WebTabControl object), the name of the source event, ("OnShowPage"), and the values which the event has passed. We established that two values would be passed - the page visible before the change (PrevPage) and the page visible after the change (NextPage).
5. Save your changes.


Step 5 - Modify the Form-Level Code

Now we need to modify the Form-level code. Open the _Form_Startup module and make the following changes to the Form_Open() event procedure:

1. Add the following declarations:
    Dim WebTabCtl As cControl_WebTabControl
    Dim WebTabCtlEH as cControl_EventHandler_WebTabControl
    Dim MyCallbacks As cMyCallbacks

Note that we have created a reference for one of each of the following objects: the WebTabControl object, the WebTabControl EventHandler object, the custom callback class, cMyCallbacks.

2. Instance the MyCallbacks variable:
Set MyCallbacks = New cMyCallbacks

3. Save the reference to the cControl_WebTabControl object by changing the CreateWebTabControl function call to read:
Set WebTabCtl = CreateWebTabControl(Me.TabCtl23)

4. Get the reference to the cControl_EventHandler_WebTabControl object:
{{ Set WebTabCtlEH = WebTabCtl.ParentEventHandler}

5. Add our custom callback function to the event handler's OnShowPage() event sink:
WebTabCtlEH.OnShowPage.AddCallback MyCallbacks, "ShowPageCallback", ccFullSignature
6. Save your changes. The code in the Form_Open() procedure should read as follows:
Private Sub Form_Open(Cancel As Integer)

    Dim WebTabCtl As cControl_WebTabControl
    Dim WebTabCtlEH as cControl_EventHandler_WebTabControl
    Dim myCallbacks As cMyCallbacks
    Set myCallbacks = New cMyCallbacks
    Set WebTabCtl = CreateWebTabControl(Me.TabCtl23)
    Set WebTabCtlEH = WebTabCtl.ParentEventHandler

    WebTabCtlEH.OnShowPage.AddCallback myCallbacks, "ShowPageCallback", ccFullSignature
End Sub

7. Now run the AutoExec macro. Click on one of the WebButton tabs to change the TabControl page. A message box should pop up identifying that the cControl_WebTabControl object's OnShowPage() event was triggered and the two pages the TabControl was switching between.


Now move on to the next part, NextPart

Last edited Feb 26, 2011 at 7:58 AM by vba_junkie, version 5


No comments yet.