Before you use objects generated by one of the MobiLink synchronization wizards, you should examine them in the PocketBuilder painters to understand how they interact. Many of the function and event scripts contain comments that describe their purpose.
All the source code is provided so that you have total control of how your application manages synchronization. You can use the objects as they are, modify them, or use them as templates for your own objects.
MobiLink Synchronization for SQL Anywhere The nvo_appname_sync user object contains instance variables that represent specific dbmlsync arguments, including the publication name, the MobiLink server host name and port, the DSN used on the desktop, and the file DSN created for deployment to the Pocket PC.
UltraLite Synchronization The nvo_appname_ulsync user object contains instance variables that represent arguments passed to a structure object in the Synchronize call. Publication names, a script version, and the MobiLink server host name and port number are included in instance variables of the nonvisual user object.
For all synchronization wizards When you run the wizard, the values that you specify for these instance variables are set as default values in the script for the constructor event of the user object. They are also set in the Windows registry on the development computer in HKEY_CURRENT_USER\Software\Sybase\PocketBuilder\2.0\appname\MobiLink, where appname is the name of your application.
At runtime, the constructor event script gets the values of the instance variables from the Windows CE registry on the device. If they cannot be obtained from the registry, or if you override the registry settings, the default value supplied in the script is used instead and is written to the registry.
You can change the default values in the event script, and you can let the user change the registry values at runtime by providing a menu item that opens the w_appname_sync_options or the w_appname_ulsync_options window.
The user object’s uf_runsync and uf_runsync_with_window functions use the instance variables as arguments when they launch a dbmlsync process or Synchronize call.
To enable the user to launch a synchronization process, code a button or menu event script to call the gf_appname_sync (SQL Anywhere) or gf_appname_ulsync (UltraLite) global function. This function creates an instance of the nvo_appname_sync or nvo_appname_ulsync user object, and the user object’s constructor event script sets the appname\MobiLink key in the Windows CE registry.
If you specified in the wizard that the status window should display, the global function opens the status window, whose ue_postopen event calls the uf_runsync_with_window function; otherwise, the global function calls the uf_runsync function. Both uf_runsync functions launch dbmlsync for remote SQL Anywhere databases as an external process using a special function in the PocketBuilder VM. For UltraLite databases, both functions call Synchronize on the connection object.
The gf_appname_sync (SQL Anywhere) global function takes a MobiLink user name and password as arguments. The gf_appname_ulsync (UltraLite) global function also takes the name of the remote database connection object as an argument. The wizard does not set any default values for these arguments, so you generally need to provide them. If you pass valid arguments to the function, it sets the value of the is_mluser and is_mlpassword instance variables to the values supplied.
Example for a remote SQL Anywhere database You could code a menu item to open a response window with two single-line edit boxes, and pass the user-supplied values to the function in the script for an OK button:
if gf_myapp_sync (sle_usr.text, sle_pwd.text)<> 0 then MessageBox("Error", "MobiLink Error") end if
If you pass null values or empty strings to the global function, the uf_runsync functions use MobiLink user name and password values stored in the registry to provide arguments for the dbmlsync utility. If each user of your application typically uses a given MobiLink user name, providing a mechanism that stores values in the registry lets users start a synchronization without reentering the information. The options window (described in “Using the synchronization options window”) provides such a mechanism.
If no user name is supplied If there are no values in the registry and the publication has only one user associated with it, you can supply empty arguments to the global function, and dbmlsync will use the user name associated with the publication.
Example for a remote UltraLite database You could code a menu item to open a response window with two single-line edit boxes, and pass the user-supplied values to the function in the script for an OK button:
if gf_myapp_ulsync (sle_usr.text, sle_pwd.text, sqlca)& <> 0 then MessageBox("Error", "MobiLink Error") end if
If you pass null values or empty strings to the global function, the uf_runsync functions use MobiLink user name and password values stored in the registry to provide arguments to the structure object passed in the Synchronize call.
After synchronizing, you would typically test for synchronization errors, then retrieve data from the newly synchronized database. For example, for synchronization involving a remote SQL Anywhere database, you could code:
if gf_myapp_sync("", "") <> 0 then MessageBox("Error", "MobiLink error") else dw_1.Retrieve() end if
For synchronization with remote SQL Anywhere databases, the PocketBuilder VM traps messages from the dbmlsync process and triggers events in the nonvisual user object as the process runs. For remote UltraLite databases, synchronization messages are caught in a structure object, and the synchronization directly triggers events in the nonvisual user object generated by the UltraLite Synchronization wizard.
These events are triggered before synchronization begins as the upload stream is prepared:
ue_begin_logscan ( long rescan_log )
ue_progress_info ( long progress_index, long progress_max )
ue_end_logscan ( )
These events correspond to events on the synchronization server, as described in “Connection events”:
ue_begin_sync ( string user_name, string pub_names)
ue_connect_MobiLink ( )
ue_begin_upload ( )
ue_end_upload ( )
ue_begin_download ( )
ue_end_download ( long upsert_rows, long delete_rows )
ue_disconnect_MobiLink( )
ue_end_sync ( long status_code )
These events are triggered after ue_end_upload and before ue_begin_download:
ue_wait_for_upload_ack ( )
ue_upload_ack ( long upload_status )
These events are triggered when various messages are sent by the server:
ue_error_msg ( string error_msg )
ue_warning_msg ( string warning_msg )
ue_file_msg ( string file_msg )
ue_display_msg ( string display_msg )
The default event scripts created by a PocketBuilder synchronization wizard trigger corresponding events in the optional status window, if it exists. The window events write the status to the multiline edit control in the status window. Some window events also update a static text control that displays the phase of the synchronization operation that is currently running (log scan, upload, or download) and control a horizontal progress bar showing what percentage of the operation has completed.
You can also add code to the user object or window events that will execute at the point in the synchronization process when the corresponding MobiLink events are triggered. For synchronization with remote SQL Anywhere databases, the dbmlsync process sends the event messages to the controlling PowerBuilder application and waits until PowerBuilder event processing is completed before continuing. There is no external synchronization process called by an application for synchronizing a remote UltraLite database.
The Cancel button on the status window calls the uf_cancelsync user object function to cancel the synchronization process. If your application does not use the status window, you can call this function in an event script elsewhere in your application.