Home · All Commands · First Steps · Tutorials · Demos · FAQ
 

Remote Interface Documentation

First Steps

Introduction

On this page we will describe the principles of including the remote interface into your application and show you how to communicate with it.

Basics

The remote interface communicates with the client via window messages, so you should be familiar with these.
The navigation software acts as a server and your application is a client who "talks" to this server. You can send and receive messages to and from the navigator and there is the possibility to exchange data between the applications (the data will be transfered over shared memory).

What you need

What you can do

Including the remote interface

To use the interface, add the following to your code:

#define USE_LOADLIBRARY
#include "TNSRemoteInterfaceDll.h"

The USE_LOADLIBRARY define causes the dll to be loaded automatically, no other steps will be needed to start.

What are commands

Throughout the help, we use the term command for the process of sending the navigator information and getting information from the navigator.
Because of the message based system of the interface, it's not a function or a method like in other interfaces, but a combination of a message and optional data which will belong to this message.
These messages are standard Windows Messages which will be handled in a message loop and therefore the interface is not synchronous. Be sure to have this in mind when sending commands to the navigator !
Every command has a distinct message to send, and some have optional functions to read or write the data.
You will find an overview and further explanation of all commands in All Commands.

Sending and receiving commands

First, be sure that the navigator software is running and you are at least in the main menu (see picture below) of the navigator.

mainmenu.jpg

The procedure of sending commands and receiving the acknowledgement answer is always the same:

ri_processing.jpg

You send a message to the interface (e.g. "RI_MESSAGE_SYSTEMINFO" to get some system information). To know if the request succeeded, check in your WindowProc()-procedure for the same message you sent (the navigator will sent this message back after executing the request). When the message arrives, the wParam of WindowProc() will be RI_NOERROR on success or an error value if the request failed.
It is essential to check the acknowledgement message in the WindowProc to know if the command succeeded.

The messages you can send are described in the Commands-Description (see All commands).

Before sending a message to the remote interface, you have to take care that the interface is active and loaded.
This is done by the method RI_GetTNS() which returns a window-handle to the interface.

In the Tutorials, you will find this code to check for the interface:

if ( !IsWindow( RI_GetTNS() ) )
                return RI_NAVIGATIONNOTACTIVE;

With this handle, you can use the PostMessage() method to send the message to the interface:

PostMessage( RI_GetTNS(), request, WPARAM(h_client), id );

Each message sent must have a unique identifier, see parameter 'id' in the above example.

For the tutorials and for general use, we wrote two little convenience functions:

Types of commands

There are two types of RI-commands:

Commands without data-transfer are the simplest way to communicate with the interface. Just use the above mentioned RI_MESSAGE function to send the request to the navigator, check in WindowProc() if the message succeeded (the navigator will always send a message back to your app to signalize the proper processing of the request and for error handling) and your done.

Commands with data-transfer can send and receive data from the interface. For this purpose, every command with data-transfer capability has it's own functions to read and write the data.
As an example, the read-function for the SearchAddress-Command is called "RI_SearchAddress_ReadData()", the write-function is called "RI_SearchAddress_WriteData()".
The data for the transfer is stored in a struct, in the SearchAddress example it's called "RI_CSearchAddress".
(See All Commands for details).

To send data, first fill the struct with the appropriate content, then write the data to the interface and at last, send the command:

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

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

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

Again, you have to create a unique id. This time, you must use the same id for writing the data and sending the message (the id is needed to relate the data to the message).

To receive data, check in wndproc for your message and read the data with the reader-function:

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

Restrictions when sending commands

Avoid mixing remote interface calls with user interaction, this can result in undefined behaviour.

A problem that sometimes occurs is that the client sends a remote command and the user of the navigation software presses a button (e.g. sending a station will automatically switch to the stationlist dialog, and some users press the "calculate" button while the navigator is adding some other station). To avoid these situations the best way is to disable the user interface by the client before sending such commands and enable it afterwards. If the client doesn't block the user interaction, the remote interface will autoblock it for certain commands.

These commands are:

In these routines, the remote interface will disable user interaction with the navigator before executing the call and enable it after the call, if there was no explicit BlockUserInteraction-command sent by the client.
This will not help in situations like adding multiple stations to the navigator. In this case, if you don't block the interface, we block it, but we can do this only an a command basis, so the result would be:
block interface -> add station -> unblock -> block -> addstation -> unblock and so on.
This is most time not what you expect and doesn't avoid all user interaction.

We recommend to explicitly block the user interface always by calling BlockUserInteraction before sending commands where the user may have interaction possibilities.

Calling BlockUserInteraction will disable the internal block/allow mechanism.

Next steps

To find out more, see the Tutorials page.


© PTV AG 2011 Generated on Fri Oct 14 2011 10:17:32 for RI by doxygen 1.7.1