Skip to content

Tutorial

The tutorial will show you how to integrate the remote interface in your application and how to communicate with the navigator. In the following examples you will learn how to:

  • Start the navigation software in tracking mode
  • Retrieve the coordinates of a given address
  • Read the station list

As described in First Steps there are two types of commands, the ones without data and the others with data-transfer. The commands with data-transfer can be splitted in two subgroups:

  • commands with one package of data received (this type was introduced in First Steps)
  • commands with multipackage data return

For every type of command, we have created a small tutorial to show how the control flow works. We also have two convenience functions which will be used in our examples:

Every message needs a unique id to be sent, so we create one by this function:

LPARAM GetUniqueID()
{
    static LPARAM id = 0;
    if (++id == 0) ++id; // do not use 0 !!!!!
    return id;
}

Furthermore we need a function to get a handle from the remote interface and send the request to it:

inline LRESULT RI_MESSAGE( const UINT request, HWND h_client, LPARAM id )
{
    if ( !IsWindow( RI_GetTNS() ) )
    return RI_NAVIGATIONNOTACTIVE;
    PostMessage( RI_GetTNS(), request, WPARAM(h_client), id );
    return RI_NOERROR;
}

The return value of the above function is set to RI_NAVIGATIONNOTACTIVE or RI_NOERROR only to check if the command itself could be posted, it does not indicate that the request to the interface was successful. To check for successful execution of the command wait for the message you sent in the WindowProc to arrive.


Start in tracking mode

This Example shows how to switch the navigator into tracking mode. We do not need to send data for this request, so the only thing we do is sending the correspondent message:

LPARAM id = GetUniqueID();
if ( RI_MESSAGE( RI_MESSAGE_STARTNAVIGATION, GetSafeHwnd(), id ) == RI_NOERROR )
{
}

This will cause the navigation software to switch to the tracking mode. In the WindowProc-function, we wait for the answer. The navigator will send the same message back and sets the wParam to the error code. In this case, if wParam = RI_NOTADDED, the navigator switched successfully to the tracking mode:

LRESULT CDlgMFC_StartTracking::WindowProc ( UINT  message , WPARAM  wParam , LPARAM  lParam )
{
    if ( message == RI_MESSAGE_STARTNAVIGATION )
    {
        if ( (LRESULT)wParam == RI_NOTADDED )
        {
            //succeeded
        }
    .
    .
    .
    }
}

The complete code:

#define USE_LOADLIBRARY
#include "TNSRemoteInterfaceDll.h"

LPARAM GetUniqueID()
{
    //generate unique ID
    static LPARAM id = 0;
    if (++id == 0) ++id; // do not use 0 !!!!!
    return id;
}

inline LRESULT RI_MESSAGE( const UINT request, HWND h_client, LPARAM id )
{
    //check if RI handle is valid
    if ( !IsWindow( RI_GetTNS() ) )
        return RI_NAVIGATIONNOTACTIVE;
    PostMessage( RI_GetTNS(), request, WPARAM(h_client), id );
    return RI_NOERROR;
}

LRESULT CDlgMFC_StartTracking::WindowProc ( UINT  message , WPARAM  wParam , LPARAM  lParam )
{
    //check messages for answer from RI
    if ( message == RI_MESSAGE_STARTNAVIGATION )
    {
        if ( (LRESULT)wParam == RI_NOERROR )
            //Navigation succeeded. errorcode (0)
        else if ( (LRESULT)wParam == RI_USER)
            //Navigation not succeeded, User abort Navigation. errorcode (20)
        else if ( (LRESULT)wParam == RI_NOTADDED)
            //Tracking Modus succeeded. errorcode (11)
        else if ( (LRESULT)wParam == RI_NOFIX)
            //Navigation not succeeded, no GPS Fix. errorcode (18)
        else if ( (LRESULT)wParam == RI_NOTRUN)
            //Navigation not succeeded, Route calculation failed. errorcode (17)
        else if ( (LRESULT)wParam == RI_START_RETRACTED )
            //Navigation succeeded. Start was retracted. errorcode (21)
        else if ( (LRESULT)wParam == RI_TARGET_RETRACTED )
            //Navigation succeeded. Target was retracted. errorcode (22)
        else if ( (LRESULT)wParam == RI_START_TARGET_RETRACTED )
            //Navigation succeeded. Start and Target was retracted.errorcode (23)
        else 
            //Navigation not succeeded. errorcode (-1)
    }
    return CDialog::WindowProc( message, wParam, lParam );
}

void CDlgMFC_StartTracking::foo()
{
    LPARAM id = GetUniqueID();
    if ( RI_MESSAGE( RI_MESSAGE_STARTNAVIGATION, GetSafeHwnd(), id ) == RI_NOERROR )
        //message sending succeeded
    else
        //navigation software not running
}

Get coordinates of an address

This Example will show you how to get a coordinate from an address string. This time, we do not only send a message, we also have to pass data (the address string) to the navigator and we will read the result. Every command that can read or write data has it's own functions to do this and a struct in which the data is stored. In case of the SearchAddress-Command they are called:

First, we create and fill the struct with the search string:

RI_CSearchAddress data;
wcscpy(data.m_address, L"D,76131,Karlsruhe,Stumpfstrasse,1");

Then, we write the data into the shared memory:

LPARAM id = GetUniqueID();
LRESULT sharing_ret = RI_SearchAddress_WriteData( id, data );

No we can send the message to search the address. The id for reading and writing the data the will be also used for RI_MESSAGE:

if ( RI_MESSAGE( RI_MESSAGE_SEARCHADDRESS, GetSafeHwnd(), id ) == RI_NOERROR )
{
}

After sending the request, we wait in windowproc for the returned answer. The wParam-value will indicate the error code.

if ( message == RI_MESSAGE_SEARCHADDRESS )
{
    if ( (LRESULT)wParam == RI_NOERROR )
    {
        RI_CSearchAddress data;
        LRESULT read_suc = RI_SearchAddress_ReadData( lParam, data );
    }
}

If the message is the one we sent, we read the data with RI_SearchAddress_ReadData(). The lParam value is the id we sent before, the struct will be filled with the result.

The complete code:

#define USE_LOADLIBRARY
#include "TNSRemoteInterfaceDll.h"

LPARAM GetUniqueID()
{
    //generate unique ID
    static LPARAM id = 0;
    if (++id == 0) ++id; // do not use 0 !!!!!
    return id;
}

inline LRESULT RI_MESSAGE( const UINT request, HWND h_client, LPARAM id )
{
    //check if RI handle is valid
    if ( !IsWindow( RI_GetTNS() ) ) 
        return RI_NAVIGATIONNOTACTIVE;
    //send the request
    PostMessage( RI_GetTNS(), request, WPARAM(h_client), id );
    return RI_NOERROR;
}

LRESULT CDlgMFC_GeoCoding::WindowProc ( UINT  message , WPARAM  wParam , LPARAM  lParam )
{
    //check messages for answer from RI
    if ( message == RI_MESSAGE_SEARCHADDRESS )
    {
        if ( (LRESULT)wParam == RI_NOERROR )
        {
            //SearchAddress succeeded. errorcode (0)
            //get the data from the shared memory
            RI_CSearchAddress data;
            LRESULT read_suc = RI_SearchAddress_ReadData( lParam, data );
            if ( read_suc != RI_NOERROR )
                //...data was overwritten. errorcode (-2)<BR>
            else
            {
                TRACE(TEXT("X-Koordinate: %i\n"), data.m_mercator_x);
                TRACE(TEXT("Y-Koordinate: %i\n"), data.m_mercator_y);
                TRACE(TEXT("Result Address: %s\n"), data.m_result_address);
            }
        }
        else if ( (LRESULT)wParam == RI_NOTAV )
        {
            //SearchAddress has no street found. errorcode (19)
            //get the data from the shared memory
            RI_CSearchAddress data;
            LRESULT read_suc = RI_SearchAddress_ReadData( lParam, data );
            if ( read_suc != RI_NOERROR )<BR>
                //...data was overwritten. errorcode (-2)
            else
            {
                TRACE(TEXT("X-Koordinate: %i\n"), data.m_mercator_x);
                TRACE(TEXT("Y-Koordinate: %i\n"), data.m_mercator_y);
                TRACE(TEXT("Result Address: %s\n"), data.m_result_address);
            }
        }
        else
            //SearchAddress not succeeded. errorcode (-1)
    }
    return CDialog::WindowProc( message, wParam, lParam );
}

void CDlgMFC_GeoCoding::foo()
{
    //*** copy data ***
    RI_CSearchAddress data;
    wcscpy(data.m_address, L"D,76131,Karlsruhe,Stumpfstrasse,1");

    //*** write data in shared memory ***
    LPARAM id = GetUniqueID();
    LRESULT sharing_ret = RI_SearchAddress_WriteData( id, data );
    if ( sharing_ret != RI_NOERROR )
        return;
    if ( RI_MESSAGE( RI_MESSAGE_SEARCHADDRESS, GetSafeHwnd(), id ) == RI_NOERROR )
        //message sending succeeded
    else
        //navigation software not running
}

Read the station list

In this example we will show how to read the station list from the navigator. This introduces a request which returns multiple packages. The sending of the request is similar to the tutorials we saw before, so we do not explain it here anymore. In the windowproc, we check for our message as in the tutorials before:

LRESULT CDlgMFC_ReadStationList::WindowProc ( UINT  message , WPARAM  wParam , LPARAM  lParam )
{
    if ( message == RI_MESSAGE_GETSTOPOFFPOINTLIST )
    {
        if ( (LRESULT)wParam == RI_NOERROR )
        {
            RI_CGetStopOffPointList data;
            LRESULT read_suc = RI_GetStopOffPointList_ReadData( lParam, data );

In this case, the received a data struct that has a field m_listcount. This field holds the number of stations available. If you want to read all stations, you have to increase the m_index field in this received struct, write it with the writer function back to the shared memory and resend the message. So the next time, we receive the message, the second package will be transfered, and so on until there are no more packages available.

if (data.m_index < data.m_listcount )
{
    data.m_index = data.m_index + 1;
    LRESULT sharing_ret = RI_GetStopOffPointList_WriteData( data.m_ID, data );
    RI_MESSAGE( RI_MESSAGE_GETSTOPOFFPOINTLIST, GetSafeHwnd(), data.m_ID );
}

The complete code:

#define USE_LOADLIBRARY
#include "TNSRemoteInterfaceDll.h"

LPARAM GetUniqueID()
{
    //generate unique ID
    static LPARAM id = 0;
    if (++id == 0) ++id; // do not use 0 !!!!!
    return id;
}

inline LRESULT RI_MESSAGE( const UINT request, HWND h_client, LPARAM id )
{
    //check if RI handle is valid
    if ( !IsWindow( RI_GetTNS() ) ) 
        return RI_NAVIGATIONNOTACTIVE;
    //send the request
    PostMessage( RI_GetTNS(), request, WPARAM(h_client), id );
    return RI_NOERROR;
}

LRESULT CDlgMFC_ReadStationList::WindowProc ( UINT  message , WPARAM  wParam , LPARAM  lParam )
{
    //check messages for answer from RI
    if ( message == RI_MESSAGE_GETSTOPOFFPOINTLIST )
    {
        if ( (LRESULT)wParam == RI_NOERROR )
        {
            RI_CGetStopOffPointList data;
            LRESULT read_suc = RI_GetStopOffPointList_ReadData( lParam, data );
            if ( read_suc != RI_NOERROR )
                //...data was overwritten. errorcode (-2)
            else
            {   
                //examine whether the current station-index is smaller than the stationcount
                if (data.m_index < data.m_listcount )
                {
                    //show data:
                    TRACE(TEXT("Caption: %s\n"),data.m_Caption);
                    TRACE(TEXT("Description: %s\n"), data.m_Description);
                    TRACE(TEXT("X-Koorinate: %i\n"), data.m_mercator_x);
                    TRACE(TEXT("Y-Koordinate: %i\n"), data.m_mercator_y);
                    TRACE(TEXT("ID: %i"),data.m_StationID);
                    //advance station counter 1
                    data.m_index = data.m_index + 1;
                    //write data
                    LRESULT sharing_ret = RI_GetStopOffPointList_WriteData( data.m_ID, data );
                    //get next station from the list
                    RI_MESSAGE( RI_MESSAGE_GETSTOPOFFPOINTLIST, GetSafeHwnd(), data.m_ID );
                }
            }

        }
        else 
            //Get Stop of Point List not succeeded. errorcode (-1)
    }
    return CDialog::WindowProc( message, wParam, lParam );
}

void CDlgMFC_ReadStationList::foo()
{
    //*** copy data ***
    RI_CGetStopOffPointList data;
    //write flag and index
    data.m_index = 0;

    //*** write data in shared memory ***
    LPARAM id = GetUniqueID();
    LRESULT sharing_ret = RI_GetStopOffPointList_WriteData( id, data );
    if ( sharing_ret != RI_NOERROR )
            return;
    if ( RI_MESSAGE( RI_MESSAGE_GETSTOPOFFPOINTLIST, GetSafeHwnd(), id ) == RI_NOERROR )
        //message sending succeeded
    else
        //navigation software not running
}