Roaming Events

The following code example demonstrates how to log on to the server with roaming features enabled. The operations in the Initialize RTC and Create the Roaming Profile code examples must be performed before using this example.

Note  This example does not contain error checking or releases appropriate for real code.

C++ Code Example 1: Event Sink

// Here is the event sink to attach.
HRESULT	Event(RTC_EVENT RTCEvent, IDispatch* pEvent)
{
    // RTC event sink of events shown in the sample
    switch(RTCEvent)
    {
	
        case RTCE_PROFILE:						
           HandleProfileEvent(pEvent); 
           break;

        case RTCE_ROAMING:						
           HandleRoamingEvents(pEvent); 
           break;

        // Add handlers for other events here. 
    }

    return S_OK;
}

C++ Code Example 2: Profile Event Handler

HRESULT HandleProfileEvent(IDispatch *pEvent)
{
    HRESULT hr = S_OK;
    IRTCProfileEvent2 *pPE2 = NULL;
    IRTCProfile2 *pProfile2 = NULL;
    RTC_PROFILE_EVENT_TYPE	enType;

    // Query for the IRTCProfileEvent interface. 
    hr = pEvent->QueryInterface(IID_IRTCProfileEvent2, 
                                (void **)&pPE2);
	
    // If (hr != S_OK), process the error here.
	
    // Get the profile from the event. 
    hr = pPE2->get_Profile((IRTCProfile **) 
                           &pProfile2);

    // If (hr != S_OK), process the error here.

    // Get the type of event from the profile event.
    hr = pPE2->get_EventType(&enType);
	
    // If (hr != S_OK), process the error here.
	
    // Release the reference to the profile event. 
    pPE2->Release();

    if (enType == RTCPFET_PROFILE_GET)
    {
        // Set the allowed authentication methods in the profile.
        hr = pProfile2->put_AllowedAuth(RTCAU_NTLM | RTCAU_KERBEROS);
		
        // If (hr != S_OK), process the error here.

        //Enable presence and local storage.
        IRTCClientPresence2 *pPresence;
        hr = m_pClient->QueryInterface(IID_IRTCClientPresence2, 
                                       (LPVOID *)&pPresence);	
	 
        // If (hr != S_OK), process the error here.

        VARIANT v;
        ::VariantInit(&v);
        v.bstrVal = ::SysAllocString(L"local_presence_file.xml");
        v.vt = VT_BSTR;
        hr = pPresence->EnablePresenceEx(pProfile2, v, 0);

        pPresence->Release();

        ::SysFreeString(v.bstrVal);
	
        // Register with the server.
        IRTCClientProvisioning2 *pProvisioning;
        hr = m_pClient->QueryInterface(IID_IRTCClientProvisioning2, 
                                       (LPVOID *)&pProvisioning);	
		
        // If (hr != S_OK), process the error here.
	
        hr = pProvisioning->EnableProfileEx(pProfile2, 
                                            RTCRF_REGISTER_ALL, 
                                            RTCRMF_BUDDY_ROAMING | 
                                            RTCRMF_PRESENCE_ROAMING | 
                                            RTCRMF_PROFILE_ROAMING | 
                                            RTCRMF_WATCHER_ROAMING);
		
        // If (hr != S_OK), process the error here.
		
        if (pProvisioning)
           pProvisioning->Release();
		
        if (pProfile2)
           pProfile2->Release();

    }
    else if (enType == RTCPFET_PROFILE_UPDATE)
    {
        // Our profile got updated from the server.
        // We may want to update the user interface based on this change.
    }

    return hr;
}

C++ Code Example 3: Roaming Events Handler

HRESULT HandleRoamingEvents(IDispatch *pEvent)
{
    HRESULT hr = S_OK;
    LONG lStatusCode = S_OK;
    RTC_ROAMING_EVENT_TYPE enEventType;
    IRTCRoamingEvent * pRE;

    // Query for the IRTCRoamingEvent interface. 
    hr = pEvent->QueryInterface(IID_IRTCRoamingEvent, 
                                (LPVOID *)&pRE);
	
    // If (hr != S_OK), process the error here.

    hr = pRE->get_EventType(&enEventType);
	
    // If (hr != S_OK), process the error here.

    hr = pRE->get_StatusCode(&lStatusCode);
	
    // If (hr != S_OK), process the error here.

    // Check the status code
    if (FAILED(lStatusCode))
    {
        // The status code is a failure HRESULT, signifying
        // that the roaming operation did not complete 
        // successfully. Roaming may not be enabled.
        // Handle the failure here.
    }

    // Process the event based on the event type.
    switch (enEventType)
    {
        case RTCRET_BUDDY_ROAMING:
           // Our list of buddies has been updated from the 
           // server. Update the user interface by
           // cycling through the buddy enumeration.
           break;

        case RTCRET_WATCHER_ROAMING:
           // Our watcher list has been updated from the 		
           // server. Update the user interface by 
           // cycling through the watcher enumeration.
           break;

        case RTCRET_PRESENCE_ROAMING:
           // We are on a roaming presence server. We can
           // publish our presence now with SetLocalPresenceInfo()
           // and other presence functions.
           break;

        case RTCRET_WPENDING_ROAMING:
           // This is the second roaming event type required to know 
           // that watcher roaming has completed successfully.
           break;

        case RTCRET_PROFILE_ROAMING:
           // Our profile has been updated from the server.
           break;

        default:
           // Handle failures or unknown cases.
           break;
    }

    if (pRE)
        pRE->Release();

    return S_OK;
}

Visual Basic Code Example: Event Sink

'
' In the roaming event handler
'
Dim lStatusCode As Long
Dim enEventType As Long
	
Dim pRE As IRTCRoamingEvent

' Add code here to set pRE to the Event object.
pRE = pEvent

enEventType = pRE.EventType
lStatusCode = pRE.StatusCode

if (lStatusCode <> S_OK) Then
    ' If the status code is a failure HRESULT, 
    ' this signifies that the roaming
    ' operation did not complete successfully. 
    ' Roaming may not be enabled.
    ' Handle failures here.
End If


' Process the event based on its type.
Select Case (enEventType)

    case RTCRET_BUDDY_ROAMING:
        ' The list of buddies has been updated from the server.
        ' Update the user interface by cycling through
        ' the buddy enumeration.

    case RTCRET_WATCHER_ROAMING:
        ' The watcher list has been updated from the server.
        ' Update the user interface by cycling through
        ' the watcher enumeration.

    case RTCRET_PRESENCE_ROAMING:
        ' We are on a roaming presence server. We can 
        ' publish our presence now with the 
        ' IRTCCLientPresence::SetLocalPresenceInfo method,
        ' or update other presence information, such as the 
        ' presence data, with IRTCClientPresence2::SetPresenceData.

    case RTCRET_WPENDING_ROAMING:
        ' This is the second roaming event type required 
        ' to know that watcher roaming has successfully completed.
    case RTCRET_PROFILE_ROAMING:
        ' Our profile has been updated from the server.

End Select