Device Management


User interface devices include keyboards and mouse devices, tablets, touchpads , and other devices. The most used devices in many applications are the mouse and the keyboard.

Capturing Mouse Events

There are more than 30 mouse input messages. These are broken into two cases: client-area mouse messages and nonclient-area mouse messages. A window receives client-area mouse messages when a mouse event occurs in that window s client area. The file Winuser.h (included by Windows .h) defines these message values, as shown in Table 11.3.

Table 11.3: Mouse Event Definitions

Message

Meaning

WM_LBUTTONDBLCLK

The left mouse button was double-clicked.

WM_LBUTTONDOWN

The left mouse button was pressed.

WM_LBUTTONUP

The left mouse button was released.

WM_MBUTTONDBLCLK

The middle mouse button was double-clicked.

WM_MBUTTONDOWN

The middle mouse button was pressed.

WM_MBUTTONUP

The middle mouse button was released.

WM_RBUTTONDBLCLK

The right mouse button was double-clicked.

WM_RBUTTONDOWN

The right mouse button was pressed.

WM_RBUTTONUP

The right mouse button was released.

WM_XBUTTONDBLCLK

Windows 2000 or Windows XP: An X mouse button was double-clicked.

WM_XBUTTONDOWN

Windows 2000 or Windows XP: An X mouse button was pressed.

WM_XBUTTONUP

Windows 2000 or Windows XP: An X mouse button was released.

Nonclient-Area Mouse Messages

A window receives nonclient-area mouse messages when a mouse event occurs in the window but outside the client area. The nonclient area includes the border, the title bar, any scroll bars, a menu, and minimize or maximize buttons . Each client-area message has a corresponding nonclient-area message. A nonclient-area message is defined by including NC in its name , for example, WM_NCLBUTTONUP.

The lParam member of the MSG structure consists of two SHORT values representing the POINTS structure shown in the following code. This can give the current location of the mouse pointer. For client-area messages, the (x,y) pair is relative to the window s client area. For nonclient-area messages, the (x,y) pair is relative to the upper left corner of the screen.

 typedef struct tagPOINTS {    SHORT x;    SHORT y;  } POINTS, *PPOINTS; 

The following code shows a message loop in WinMain() that captures client-area mouse messages and then determines the (x,y) coordinates of the mouse pointer. (This example shows only the code relevant to the message loop.)

 int APIENTRY WinMain(HINSTANCE hInstance,                       HINSTANCE hPrevInstance,                       LPSTR     lpCmdLine,                       int       nCmdShow) {   MSG  msg;  POINT mouseXY;   while (GetMessage(&  msg  , NULL, 0, 0))  {       switch (  msg.message  ) {       case WM_LBUTTONDOWN:       case WM_LBUTTONUP:         mouseXY.x = (SHORT) (LOWORD(  msg.lParam  ));         mouseXY.y = (SHORT) (HIWORD(  msg.lParam  ));         break;       default :         break;       }              TranslateMessage(&msg);       DispatchMessage(&msg);   }   } 

The following code shows how to process client-area mouse messages in the WndProc() function. (This example includes only the code that shows where to retrieve the mouse event information.)

 LRESULT CALLBACK WndProc(HWND hWnd,                            UINT  message  ,                            WPARAM wParam,                            LPARAM  lParam  ) {   POINT mouseXY;   switch (  message  ) {   case WM_LBUTTONDOWN:   case WM_LBUTTONUP:     //+     //   The windowsx.h header must be included to use the     //   GET_X_LPARAM and GET_Y_LPARAM     //   macros     //-       mouseXY.x = GET_X_LPARAM(  lParam  );      mouseXY.y = GET_Y_LPARAM(  lParam  );             break;   } 

The process for handling client-area mouse messages in XII is very similar, as shown in the following code:

 void main() {          Display *xdisplay;   XEvent   xEvent;   int mouseX;   int mousey;   while (1) {  /* wait for next event */  XNextEvent (xdisplay, &xevent);        switch (xevent.type) {     case ButtonPress:       mouseX = xevent.xbutton.x;       mousey = xevent.xbutton.y;       break;  } 

Capturing Keyboard Events

A scan code identifies each physical key on the keyboard. The device driver responsible for servicing the keyboard maps this number to a virtual-key code. The include file Winuser.h defines these virtual key codes. After mapping the scan code, the system places a message that includes the scan code and virtual key code along with other information in the system message queue. Some additional system processing takes place, and then the system sends the keyboard message to the process that has the keyboard focus.

Pressing a key causes a WM_KEYDOWN or WM_SYSKEYDOWN message to be placed in the thread message queue attached to the window that has the keyboard focus. Releasing a key causes a WM_KEYUP or WM_SYSKEYUP message to be placed in the queue.

The system posts a WM_CHAR message to the window with the keyboard focus when the TranslateMessage() function translates a WM_KEYDOWN message. The WM_CHAR message contains the character code of the key that was pressed.

The following code shows how to manually catch and process keystrokes:

 //+ //  contrived union used only to show how the bits of the  //  lParam parameter are arranged //  when handling WM_KEYDOWN messages //- typedef union {   struct {     unsigned long repeatCount   :16;     unsigned long scanCode      :8;     unsigned long extendedChar  :1;     unsigned long reserved      :4;     unsigned long altKeyDown    :1;     unsigned long previousState :1;     unsigned long transition    :1;   }bits;   LPARAM lParam; }tyKeyData; //+ //  Win32 Application Window Proc //- LRESULT CALLBACK WndProc(HWND   hWnd,                            UINT   message,                            WPARAM wParam,                            LPARAM lParam)      {   tyKeyData keyData;   TCHAR     characterCode;   switch (message) {   case WM_SYSKEYDOWN :   case WM_KEYDOWN    :     //+     // just for clarity showing what is in      // the wParam parameter when WM_KEYDOWN is     // sent to the window proc     //-     characterCode  = ((TCHAR)(wParam));      //+     //  the tyKeyData union is defined above     //  this union displays how the bits are defined     //-     keyData.lParam = lParam;     if (keyData.bits.altKeyDown) {       //+       //  using the keyboard hardware scan code        //  to determine what key was pressed       //-       switch (keyData.bits.scanCode) {       case 0x3B : // <Alt-F1>           break;       case 0x3C : // <Alt-F2>         break;       default :         break;       }     }     else {       //+       //  VK_XX Key Codes are found in winuser.h       //       //  These are not the keyboard hardware scan codes!!!       //        //  using the wParam to determine       //  what key was pressed        //-       switch (characterCode) {       case VK_F1 : // <F1>           break;                                          case VK_F2 : // <F2>         break;       default :         break;       }     }     break;      case WM_CHAR    :     characterCode  = ((TCHAR)(wParam));      switch (characterCode) {     //+     //  VK_XX codes can be used here     //  VK_XX Key Codes are found in winuser.h     //-     case 0x08:  // backspace      case 0x0A:  // linefeed      case 0x1B:  // escape        break;     case VK_LEFT   :  // left arrow     case VK_UP     :  // up arrow     case VK_INSERT :  // the insert key       break;     //+     //    convert TAB to Spaces     //-     case 0x09:  // tab          for (int i = 0; i < 4; i++)          SendMessage(hWnd, WM_CHAR, 0x20, 0);        return 0; 

Keyboard Focus

Keyboard focus is a temporary property of a window or widget. At any given time, only one component can listen to the keyboard for events. The window or widget that is listening is said to have the current focus, keyboard focus, or just focus.

Processing focus in a Win32-based application involves processing the WM_KILLFOCUS and WM_SETFOCUS Windows Messages. This is similar to using XmNfocusCallback and XmNlosingFocusCallback for focus callbacks set up within X/Motif.

The following code shows the window procedure for a subclassed button that is handling focus messages:

 LRESULT CALLBACK CSoftKeyProc(HWND hWnd,UINT iMsg, WPARAM wParam,LPARAM lParam) {    LRESULT   lResult    = FALSE;   //+   //    this is a trick to retrieve data (in this case a pointer) that is attached    //    to this window object. SetWindowLongPtr() was used to initially attach this    //    data to the window. The reason for this being used here is that this function    //    may be the callback for any number of these type objects and this data is "state"    //    for this particular instance     //-   CvtSoftKey *pSoftKey   = (CvtSoftKey *)GetWindowLongPtr(hWnd, 0);   switch (iMsg) {   default :     break;   //+   //  this window (button in this case) is receiving the focus   //  so we can do whatever processing we like   //  Draw a new border  Highlight the text  whatever!   //-   case WM_SETFOCUS   :     lResult  = pSoftKey->OnSetFocus(hWnd,iMsg,wParam,lParam);     break;      //+   //  this window (button in this case) is losing focus   //-   case WM_KILLFOCUS  :     lResult  = pSoftKey->OnKillFocus(hWnd,iMsg,wParam,lParam);     break;   }    return DefWindowProc(hWnd,iMsg,wParam,lParam); } 

Table 11.4 shows functions to use for getting current focus.

Table 11.4: Functions for Getting Current Focus

X Windows

Win32

No equivalent

GetActiveWindow()

XGetInputFocus()

GetForegroundWindow()    

XmGetFocusWidget()

GetFocus()

Table 11.5 shows functions to use for setting current focus.

Table 11.5: Functions for Setting Current Focus

X Windows

Win32

No equivalent

SetFocus()

No equivalent

SetActiveWindow()

XSetInputFocus()

SetForegroundWindow()

Creating Keystrokes, Mouse Motions , and Button Click

A developer can simulate keystrokes, mouse motions, or button clicks by using the SendInput() function to serially insert events into the mouse or keyboard stream.

For more information about handling the keyboard, search the MSDN Web site (http://msdn.microsoft.com/) for keybd_event , GetRawInputData , GetKeyState , GetAsyncKeyState , GetKeyboardState , and MapVirtualKey() .




UNIX Application Migration Guide
Unix Application Migration Guide (Patterns & Practices)
ISBN: 0735618380
EAN: 2147483647
Year: 2003
Pages: 134

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net