oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Building Palm Conduits, Part 2
Pages: 1, 2, 3

Let's look at our implementation of this interface function; it is really quite simple. Example 4-3 shows the code for CfgConduit.

Example 4-3: Listing for SyncNotify.CfgConduit

Private Sub IPDClientNotify_CfgConduit(ByVal nCreatorId As Long, _
                                       ByVal nUserId As Long, _
                                       ByVal bstrUserName As String, _
                                       ByVal bstrPathName As String, _
                                       ByVal nSyncPerm As ESyncTypes, _
                                       ByRef nSyncTemp As ESyncTypes, _
                                       ByRef nSyncNew As ESyncTypes, _
                                       ByRef nSyncPref As ESyncPref)
    ' Set up the form: type of sync to perform, user directory
    SyncForm.SetFields nSyncNew
    ' Let the user make choices, then retrieve them from the form. The
    ' form must be modal, this is required by COM.
    SyncForm.Show vbModal
    SyncForm.GetFields nSyncNew, nSyncTemp, nSyncPerm, nSyncPref
End Sub

The project includes a form called SyncForm, through which the user makes changes. The first thing we do is to call SetFields, a public function in the form module. It sets private form variables that are used in the Load event to initialize the controls. Without it, we'd have to interact with the form elements directly. This is risky because accessing a form element usually causes the form to be shown before you are ready.

Next, we show the form and let the user interact with the dialog. Note that the form must be shown modally: a COM object cannot display a non-modal form without a lot of extra steps. The form will fail to load if you do not supply the VBModal parameter:

SyncForm.Show vbModal


Since this is a mirror-image conduit, our custom user interface is designed to look just like the Palm native applications.

The form is simple, consisting of a group of radio buttons for the sync types, a checkbox for making the selected sync preference the default, and OK and Cancel buttons. We added an image control, to depict graphically what each type of synchronization does. The control's bitmap is taken from a screen shot of the Palm Address conduit.

The form user interface was shown earlier, in Figure 4-2. In our example, the form name is SyncForm, and it is saved as Ch4aForm.frm.

Your conduit might not need to support all these synchronization types, so feel free to remove choices. For example, we have disabled the PCtoHH option in our sample conduit (see Figure 4-2). But you should always include an option for your conduit to do nothing. We guarantee that this option will be used more often than you think!

And if your conduit has special requirements or extra configuration options, this is the place to expose them.

Here is the implementation of SetFields, which was discussed earlier:

Public Sub SetFields(ByVal nSyncPerm As Long)
    m_nSyncType = nSyncPerm
End Sub

The code for the form Load event is shown in Example 4-4. Load assumes that the private form variables have already been set to appropriate values--so be sure to call SetFields before loading the form. In Load, we set the radio buttons and checkbox to the states indicated by the public form variable values.

Example 4-4: Listing for SyncForm.Load

Private Sub Form_Load(  )
    ' Set the radio buttons based on the HotSync information
    optSync.Value = False
    optHHToPC.Value = False
    optPCToHH.Value = False
    optDoNothing.Value = False
    Select Case m_nSyncType
    Case eHHtoPC
        optHHToPC.Value = True
    Case ePCtoHH
        optPCToHH.Value = True
    Case eDoNothing
        optDoNothing.Value = True
    Case Else
        optSync.Value = True
    End Select
    ' Set the preference check box - default to temporary by convention
    m_nSyncPref = eTemporaryPreference
    chkDefault.Value = Unchecked
    ' Assume the user will cancel
    m_bCancel = True
End Sub

The only remarkable thing about Load is that it assumes any user changes will be temporary, unless explicitly made permanent. This is the conventional behavior for the Palm native conduits, and it is a good idea for your user interface to follow suit:

m_nSyncPref = eTemporaryPreference
chkDefault.Value = Unchecked

The user can exit the form a variety of ways. For this reason, the values in the form controls are only transferred to the form variables in the OK button's Click event (see Example 4-5). At this time, the cancellation flag is set to false, the form is unloaded, and control returns to CfgConduit.

Example 4-5: Listing for SyncForm.btn_OK.Click

Private Sub btnOk_Click(  )
    ' Transfer form variables to
    If optSync.Value Then
        m_nSyncType = ESyncTypes.eFast
    ElseIf optPCToHH.Value Then
        m_nSyncType = ESyncTypes.ePCtoHH
    ElseIf optHHToPC.Value Then
        m_nSyncType = ESyncTypes.eHHtoPC
    ElseIf optDoNothing.Value Then
        m_nSyncType = ESyncTypes.eDoNothing
    End If
    If chkDefault.Value = Checked Then m_nSyncPref = ePermanentPreference
    ' Flag used in GetFields(  ) to see if the variables are valid
    m_bCancel = False
    Unload Me
End Sub

If the user exits the form, either by pushing the Cancel button directly or pressing the ESC key, control is transferred to the Cancel button's Click event. We don't show that routine here, but in it, the cancellation flag is set to true, the form is unloaded, and control is returned to CfgConduit.

At this point, the user has dismissed the form. Now we retrieve the new variable settings using the GetFields routine (which is smart enough not to overwrite any values if the user canceled rather than applied the changes). The code for GetFields is shown in Example 4-6.

Example 4-6: Listing for SyncForm.GetFields

Public Sub GetFields(ByRef nSyncNew As Long, _
                     ByRef nSyncTemp As Long, _
                     ByRef nSyncPerm As Long, _
                     ByRef nSyncPref As Long)
    If m_bCancel Then Exit Sub
    ' Retrieve the "default" setting from the check box
    nSyncPref = m_nSyncPref
    ' Retrieve the action setting from the radio buttons
    nSyncNew = m_nSyncType
    nSyncTemp = m_nSyncType
    nSyncPerm = m_nSyncType
End Sub

If the user has canceled, then none of the form variables are transferred in GetFields. And note that all three sync-type parameters are set to the same user-configured value, despite the Conduit Reference documentation, for the reasons discussed earlier.


This interface function is used by versions of the HotSync manager prior to release 3.0.1. For later releases of the HotSync manager, this function is only called if your conduit doesn't implement the CfgConduit interface. Table 4-9 lists the parameters for SyncNotify.ConfigureConduit.

Table 4-9: Parameters for SyncNotify.ConfigureConduit





[IN] String

User folder in HotSync directory


[IN] String

Numeric ID of current user


[IN/OUT] EsyncPref

Tell HotSync manager that changes are permanent or temporary


[IN/OUT] EsyncTypes

The kind of synchronization to perform

The code for ConfigureConduit simply returns default values for the two output parameters:

Private Sub IPDClientNotify_ConfigureConduit(ByVal bstrPathName As String, _
                                             ByVal bstrRegistry As String, _
                                             ByRef nSyncPref As ESyncPref, _
                                             ByRef nSyncType As ESyncTypes)
    nSyncType = PDdirectlib.eFast
    nSyncPref = PDdirectlib.ePermanentPreference
End Sub


The HotSync manager calls the interface function BeginProcess when an actual synchronization should occur. At this point, you can assume that the Palm device is in the cradle and the user has pressed the HotSync button.

Our implementation of BeginProcess is intentionally minimal; we delegate all the real work of synchronization to a private class. The code for BeginProcess is shown in Example 4-7.

Example 4-7: Listing for SyncNotify.BeginProcess

Private Function IPDClientNotify_BeginProcess(  ) As Boolean
    ' Create our sync object and do the work
    Dim Worker As New SyncLogic
    ' Return false to signal completion!
    IPDClientNotify_BeginProcess = False
End Function

BeginProcess should return False when it has completed. That signals the HotSync manager that it can skip to the next conduit. Returning False doesn't indicate that your conduit was successful; instead, it means that it is finished executing. Later, we will see how to return status information to the user in the HotSync log.

The real work of synchronization occurs in these lines:

Dim Worker As New SyncLogic

Right away, you should notice that the Worker.Synchronize method doesn't take any arguments. It gets all the information it needs to synchronize from publicly creatable COM objects supplied by the Sync Suite API.

We have finished implementing the IPDClientNotify interface, including the user interface required to support configuring the conduit. The conduit is complete from the perspective of the HotSync manager: the conduit can identify itself and its properties, it can be configured, and it responds to synchronization requests.

Roger Knoell s a software developer with 10 years experience leveraging high-level language development tools and environments.

Patrick Burton has been programming in C/C++ for most of his career. His experience inlcludes algorithm development for embedded satellite receivers, Linux system programming, and Windows programming using the Win32 API and Microsoft Found Classes (MFC).

Matthew Holmes has been developing computer software for 15 years. He cherishs his liberal arts degree in Foreign Affairs from the University of Virginia, and he holds a graduate degree in Computer Science from George Mason University.

In the next installment, learn about synchronization logic.

Return to the .NET DevCenter