|
NOTE: THIS HAS NOT BEEN UPDATED FOR V4 or V5 YET. | |||||||||||||||||||||||||||
|
Programming Pebbles MultiCursorFrom the Pittsburgh Pebbles PDA Projectby Brad Myers
PurposeMultiCursor is designed to investigate issues when each PDA user has their own cursor. The PDA side of MultiCursor looks and works just like Pebbles Remote Commander, but the PC side, instead of having all users share the same cursor as in Remote Commander, with MultiCursor, each user has their own separate cursor. Special applications are required to accept the multiple cursor messages, since the PC really has only a single cursor. One such special application is PebblesDraw, which we created using the Amulet user interface toolkit. This page describes (to some extent) how you can create your own multicursor application using the Pebbles multicursor applications. Downloading the MultiCursor Support SoftwareThe MultiCursor PDA side and DLL files are downloaded with the rest of the Pebbles applications in one big zip file. See the main downloading instructions. However, this does not include the software support for developing your own applications. That is in a separate file: Support Files for Programming MultiCursor ApplicationsThe zip file will expand to provide the following files:
Overview of MultiCursor ApplicationsIn the RemoteCommander application, all the PDA messages are inserted into the regular Windows event stream as if they were regular mouse and keyboard events, but this doesn't allow support for multiple streams of input. Therefore, in MultiCursor applications, the PDA messages are inserted into the Windows stream as a special type of message, which the application can then handle as appropriate. To get this started, the application must register with the MultiCursor dll the Windows window to which the messages should be sent. Since the dll is being used by two different processes: the PebblesPC process to handle events from the PDA, and your application, you must use a special mechanism to get the process started. The following code should be used (taken from find_dll_and_set_pebbles from gemW_pebbles.cc): #define DLL_NAME "MultiCursor" #define ENTRY_POINT "Init_Pebbles_MultiCursor" typedef void (CALLBACK*EntryPoint) (HWND); HWND hwnd = * main application window * ; HINSTANCE hDLL = LoadLibrary (DLL_NAME); if (!hDLL) cerr << "Can't find dll library " << DLL_NAME <<endl; EntryPoint proc = (EntryPoint)GetProcAddress(hDLL, ENTRY_POINT); if (!proc) cerr << "Can't find procedure " << ENTRY_POINT << " in dll library " << DLL_NAME <<endl << flush; proc (hwnd); One of the kinds of messages that arrive announce when a new user has attached to MultiCursor. You might want to find out what name this user was assigned. The Get_Pebbles_User_Name procedure does this. To get this procedure's handle, you would use the following: #define PEBBLES_USER_NAME "Get_Pebbles_User_Name" typedef char* (CALLBACK*GetPebblesUserNameType) (int); GetPebblesUserNameType GetPebblesUserName; GetPebblesUserName = (GetPebblesUserNameType)GetProcAddress(hDLL, PEBBLES_USER_NAME); if (!GetPebblesUserName) cerr << "Can't find procedure " << PEBBLES_USER_NAME << " in dll library " << DLL_NAME << endl << flush; Get_Pebbles_User_Name takes a user_id which is numbered from 0, and returns the user name if that user has ever run multicursor, or NULL if there is no such valid user. If the user gives no value in the name field when the register their COM port, then the name will be the empty string "", which is different from NULL. The user_ids correspond to the position of the user in the PebblesPC user list window, with 0 being the top item. The maximum user_id supported by MultiCursor is MAX_MULTICURSOR_USERS which is 20 (even though PebblesPC in general can support any number of users). For example, the following checks for all currently registered users, and might be done immediately after the initialization above: for (user_index = 0; user_index < MAX_MULTICURSOR_USERS; user_index++) { name = GetPebblesUserName(user_index); if (name) ** then this user is valid } When a user runs MultiCursor on the PDA and sends a mouse or keyboard event, the MultiCursor dll will send this event to the window hWnd registered in the initialization call as a message of type PEBBLESMULTICURSORMESSAGE. This might be handled as follows: #pragma warning(disable : 4759) //'segment lost' warning off LRESULT CALLBACK __export MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: //window create code case WM_LBUTTONDOWN: // window left button down code case ... // etc. case PEBBLESMULTICURSORMESSAGE: Am_Handle_Pebbles_Event(hWnd, wParam, lParam); break; } The Am_Handle_Pebbles_Event code for pebblesdraw is in the gemW_pebbles.cc sample file. In general, the lParam and wParam encode the contents of the message, as follows:
When the type is CMD_NEW_USER, this signifies that there has been a change of users: a user has started or stopped running the multicursor application on the PDA. Often, you can ignore when users stop running multicursor, since they will often switch back and forth among lots of applications on the PDA. Which user has changed status is in the wParam value, and whether the user has come or gone can be determined using GetPebblesUserName.
Back to the main MultiCursor PageBack to the Pebbles software PageBack to the Pebbles main PageMaintained by: Brad A. Myers |