Querying Scheduled Notifications
While scheduling the different notifications is often all that applications need, additional functions allow applications to query the notifications currently scheduled in the system. Here's the function that queries the notifications:
BOOL CeGetUserNotificationHandles (HANDLE *rghNotifications,
DWORD cHandles, LPDWORD pcHandlesNeeded);
This function returns an array filled with handles to all notifications currently scheduled in the system. The first parameter is the pointer to a handle array. The second parameter, cHandles, should be filled with the number of entries in the array. The third parameter should contain the address of a DWORD that will be filled with the number of entries in the array filled with valid notification handles.If the array is large enough to hold all the handles, the function returns TRUE and provides the number of handles returned in the variable pointed to by pcHandlesNeeded. If the array is too small, the function fails. You can query the number of handles the system will return by passing NULL in the rghNotifications parameter and 0 in the cHandles parameter. The function will then return the number of handles in the variable pointed to by pcHandlesNeeded.After you have queried all the handles, you can determine the details of each notification by passing each handle to the function:
BOOL CeGetUserNotification (HANDLE hNotification, DWORD cBufferSize,
LPDWORD pcBytesNeeded, LPBYTE pBuffer);
The first parameter is the handle to the notification in which you're interested. The second parameter is the size of the buffer you're providing the function to return the data about the notification. The third parameter is the address of a DWORD that will receive the size of the data returned. The final parameter is the address of a buffer that will receive the details about the notification.The size of the required buffer changes depending on the notification. The buffer begins with a CE_NOTIFICATION_INFO_HEADER structure. The buffer also contains a CE_NOTIFICATION_TRIGGER structure and, depending on the type of notification, an optional CE_USER_NOTIFICATION structure. Because these structures contain pointers to strings for application names and command lines, these strings must also be stored in the buffer.To determine how big the buffer needs to be, you can call CeGetUserNotification with cBufferSize set to 0 and pBuffer set to NULL. The function returns the number of bytes required by the buffer in the variable that pcBytesNeeded points to. However, calling the function this way takes just as much time as retrieving the data itself, so it would be better to assume a size for the buffer and call the function. Only if the call fails because the buffer is too small do you then reallocate the buffer so that it's large enough to hold the data.
Now on to the data returned. The CE_NOTIFICATION_INFO_HEADER structure is defined this way:
typedef struct UserNotificationInfoHeader {
HANDLE hNotification;
DWORD dwStatus;
CE_NOTIFICATION_TRIGGER *pcent;
CE_USER_NOTIFICATION *pceun;
} CE_NOTIFICATION_INFO_HEADER;
The first field is the handle of the event you are querying. The second field contains the status of the notification. This field contains 0 if the notification hasn't fired or CNS_SIGNALLED if it has. The next two fields are pointers to the same structures discussed earlier in the chapter. The pointer to the CE_NOTIFICATION_TRIGGER structure points to an address in the buffer in which that structure is defined. Depending on the type of notification, the pointer to the CE_USER_NOTIFICATION structure could be NULL.The combination of the two structures, CE_NOTIFICATION_TRIGGER and CE_USER_NOTIFICATION along with the status flag, completely describes the notification. By examining the trigger structure, you can determine the application that's scheduled to run as a result of the notification, its command line, and of course, the type of notification itself.The Notification API is a handy way to monitor events in a Windows CE system. The ability to have the operating system launch your application instead of having to lurk around in memory waiting for the event significantly reduces the memory requirements for a well-designed system. User notifications give you a convenient and uniform way to alert the user of events that need attention.Now that we've looked at the Notification API, we've covered the basics of Windows CE applications. The next section of this book turns from the basics to one of the more important areas of Windows CE applications, communication. This next section covers everything from basic serial communication to networking, both wired and wireless.