Before making RAPI calls, you must call the CeRapiInit or CeRapiInitEx function. These functions perform routine initialization and set up the communications link between the desktop computer and the Windows CE platform.
The CeRapiInit call is a synchronous operation. It does not return control to the application until a connection is made or an error occurs. In contrast, the CeRapiInitEx call is an asynchronous operation and it returns immediately. CeRapiInitEx continues the initialization until a connection is made, an error occurs, or there is a call to CeRapiUninit. Although CeRapiInitEx avoids blocking any threads, it is a more complicated method of initialization.
If an error is returned, exit.
Check the hrRapiInit member of the RAPIINIT structure for the final return value.
When you are finished with RAPI, call CeRapiUninit to terminate the connection and perform any necessary cleanup. Because creating and terminating connections are fairly expensive operations, establish and terminate the link only once per session, and not on a per-call basis.
The following code example shows how to use the CeRapiInitEx function. Following the CeRapiInitEx call, the MsgWaitForMultipleObjects function is used to wait on one of two events. The first event is when the event handle is passed back through the heRapiInit member of the RAPIINIT structure. The second event is when a user terminates a connection.
#define ARRAYSIZE(hArray) sizeof (hArray) / sizeof (HANDLE)
enum
{
WAD_ALLINPUT = 0x0000,
WAD_SENDMESSAGE = 0x0001,
};
DWORD WaitAndDispatch (DWORD nCount, HANDLE *phWait, DWORD dwTimeout,
UINT uFlags)
{
DWORD dwObj;
DWORD dwStart = GetTickCount ();
DWORD dwTimeLeft = dwTimeout;
for (;;)
{
dwObj= MsgWaitForMultipleObjects (nCount, phWait, FALSE, dwTimeLeft,
(uFlags & WAD_SENDMESSAGE) ? QS_SENDMESSAGE : QS_ALLINPUT);
if (dwObj == (DWORD)-1)
{
dwObj = WaitForMultipleObjects (nCount, phWait, FALSE, 100);
if (dwObj == (DWORD)-1)
break;
}
else
{
if (dwObj == WAIT_TIMEOUT)
break;
}
if ((UINT)(dwObj - WAIT_OBJECT_0) < nCount)
break;
MSG msg;
if (uFlags & WAD_SENDMESSAGE)
PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
else
{
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
DispatchMessage (&msg);
}
if (INFINITE != dwTimeout)
{
dwTimeLeft = dwTimeout - (GetTickCount () - dwStart);
if ((int)dwTimeLeft < 0)
break;
}
}
return dwObj;
}
HRESULT InitRapi (HANDLE hExit)
{
RAPIINIT rapiinit = {sizeof (RAPIINIT)};
HRESULT hResult = CeRapiInitEx (&rapiinit);
if (FAILED(hResult))
return hResult;
HANDLE hWait[] = {hExit, rapiinit.heRapiInit};
enum {WAIT_EXIT=WAIT_OBJECT_0, WAIT_INIT};
DWORD dwObj = WaitAndDispatch (ARRAYSIZE(hWait), hWait, 1000, 1);
// Event signaled by RAPI
if (WAIT_INIT == dwObj)
{
// If the connection failed, uninitialize the
// Windows CE RAPI.
if (FAILED(rapiinit.hrRapiInit))
CeRapiUninit ();
return rapiinit.hrRapiInit;
}
// Either event signaled by user or a time-out occurred.
CeRapiUninit ();
if (WAIT_EXIT == dwObj)
return HRESULT_FROM_WIN32(ERROR_CANCELLED);
return E_FAIL;
}