Windows,MSDN,Console Input Buffer

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682079(v=vs.85).aspx

Each console has an input buffer that contains a queue of input event records. When a console's window has the keyboard focus, a console formats each input event (such as a single keystroke, a movement of the mouse, or a mouse-button click) as an input record that it places in the console's input buffer.

Applications can access a console's input buffer indirectly by using the high-level console I/O functions, or directly by using the low-level console input functions. The high-level input functions filter and process the data in the input buffer, returning only a stream of input characters. The low-level input functions enable applications to read input records directly from a console's input buffer, or to place input records into the input buffer. To open a handle to a console's input buffer, specify the CONIN$ value in a call to the CreateFile function.

An input record is a structure containing information about the type of event that occurred (keyboard, mouse, window resizing, focus, or menu event) as well as specific details about the event. The EventType member in an INPUT_RECORDstructure indicates which type of event is contained in the record.

Focus and menu events are placed in a console's input buffer for internal use by the system and should be ignored by applications.


INPUT_RECORD structure

Describes an input event in the console input buffer. These records can be read from the input buffer by using theReadConsoleInput or PeekConsoleInput function, or written to the input buffer by using the WriteConsoleInputfunction.

typedef struct _INPUT_RECORD {
  WORD  EventType;
  union {
    KEY_EVENT_RECORD          KeyEvent;
    MOUSE_EVENT_RECORD        MouseEvent;
    WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
    MENU_EVENT_RECORD         MenuEvent;
    FOCUS_EVENT_RECORD        FocusEvent;
  } Event;
} INPUT_RECORD;

Members

EventType

A handle to the type of input event and the event record stored in the Event member.

This member can be one of the following values.

ValueMeaning
FOCUS_EVENT
0x0010

The Event member contains a FOCUS_EVENT_RECORD structure. These events are used internally and should be ignored.

KEY_EVENT
0x0001

The Event member contains a KEY_EVENT_RECORD structure with information about a keyboard event.

MENU_EVENT
0x0008

The Event member contains a MENU_EVENT_RECORD structure. These events are used internally and should be ignored.

MOUSE_EVENT
0x0002

The Event member contains a MOUSE_EVENT_RECORD structure with information about a mouse movement or button press event.

WINDOW_BUFFER_SIZE_EVENT
0x0004

The Event member contains a WINDOW_BUFFER_SIZE_RECORD structure with information about the new size of the console screen buffer.

Event

The event information. The format of this member depends on the event type specified by the EventTypemember.



Keyboard Events

Keyboard events are generated when any key is pressed or released; this includes control keys. However, the ALT key has special meaning to the system when pressed and released without being combined with another character, and it is not passed through to the application. Also, the CTRL+C key combination is not passed through if the input handle is in processed mode.

If the input event is a keystroke, the Event member in INPUT_RECORD is a KEY_EVENT_RECORD structure containing the following information:

  • A Boolean value indicating whether the key was pressed or released.
  • A repeat count that can be greater than one when a key is held down.
  • The virtual-key code, identifying the given key in a device-independent manner.
  • The virtual-scan code, indicating the device-dependent value generated by the keyboard hardware.
  • The translated Unicode™ or ANSI character.
  • A flag variable indicating the state of the control keys (the ALT, CTRL, SHIFT, NUM LOCK, SCROLL LOCK, and CAPS LOCK keys) and indicating whether an enhanced key was pressed. Enhanced keys for the IBM® 101-key and 102-key keyboards are the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad and the divide (/) and ENTER keys in the numeric keypad.
  • http://msdn.microsoft.com/en-us/library/windows/desktop/ms684166(v=vs.85).aspx

  • KEY_EVENT_RECORD structure

  • Describes a keyboard input event in a console INPUT_RECORD structure.

    Syntax

     
    typedef struct _KEY_EVENT_RECORD {
      BOOL  bKeyDown;
      WORD  wRepeatCount;
      WORD  wVirtualKeyCode;
      WORD  wVirtualScanCode;
      union {
        WCHAR UnicodeChar;
        CHAR  AsciiChar;
      } uChar;
      DWORD dwControlKeyState;
    } KEY_EVENT_RECORD;
    
    

    Members

    bKeyDown

    If the key is pressed, this member is TRUE. Otherwise, this member is FALSE (the key is released).

    wRepeatCount

    The repeat count, which indicates that a key is being held down. For example, when a key is held down, you might get five events with this member equal to 1, one event with this member equal to 5, or multiple events with this member greater than or equal to 1.

    wVirtualKeyCode

    virtual-key code that identifies the given key in a device-independent manner.

    wVirtualScanCode

    The virtual scan code of the given key that represents the device-dependent value generated by the keyboard hardware.

    uChar

    A union of the following members.

    UnicodeChar

    Translated Unicode character.

    AsciiChar

    Translated ASCII character.

    dwControlKeyState

    The state of the control keys. This member can be one or more of the following values.

    ValueMeaning
    CAPSLOCK_ON
    0x0080

    The CAPS LOCK light is on.

    ENHANCED_KEY
    0x0100

    The key is enhanced.

    LEFT_ALT_PRESSED
    0x0002

    The left ALT key is pressed.

    LEFT_CTRL_PRESSED
    0x0008

    The left CTRL key is pressed.

    NUMLOCK_ON
    0x0020

    The NUM LOCK light is on.

    RIGHT_ALT_PRESSED
    0x0001

    The right ALT key is pressed.

    RIGHT_CTRL_PRESSED
    0x0004

    The right CTRL key is pressed.

    SCROLLLOCK_ON
    0x0040

    The SCROLL LOCK light is on.

    SHIFT_PRESSED
    0x0010

    The SHIFT key is pressed.

    Remarks

    Enhanced keys for the IBM® 101- and 102-key keyboards are the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and direction keys in the clusters to the left of the keypad; and the divide (/) and ENTER keys in the keypad.

    Keyboard input events are generated when any key, including control keys, is pressed or released. However, the ALT key when pressed and released without combining with another character, has special meaning to the system and is not passed through to the application. Also, the CTRL+C key combination is not passed through if the input handle is in processed mode (ENABLE_PROCESSED_INPUT).

    Examples

    For an example, see Reading Input Buffer Events.


Mouse Events

Mouse events are generated whenever the user moves the mouse or presses or releases one of the mouse buttons. Mouse events are placed in the input buffer only if the following conditions are met:

  • The console input mode is set to ENABLE_MOUSE_INPUT (the default mode).
  • The console window has the keyboard focus.
  • The mouse pointer is within the borders of the console's window.

If the input event is a mouse event, the Event member in INPUT_RECORD is a MOUSE_EVENT_RECORD structure containing the following information:

  • The coordinates of the mouse pointer in terms of the character-cell row and column in the console screen buffer's coordinate system.
  • A flag variable indicating the state of the mouse buttons.
  • A flag variable indicating the state of the control keys (ALT, CTRL, SHIFT, NUM LOCK, SCROLL LOCK, and CAPS LOCK) and indicating whether an enhanced key was pressed. Enhanced keys for the IBM 101-key and 102-key keyboards are the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad and the divide (/) and ENTER keys in the numeric keypad.
  • A flag variable indicating whether the event was a normal button-press or button-release event, a mouse movement event, or the second click of a double-click event.

Note  The mouse position coordinates are in terms of the console screen buffer, not the console window. The screen buffer may have been scrolled with respect to the window, so the upper left corner of the window is not necessarily the (0,0) coordinate of the console screen buffer. To determine the coordinates of the mouse relative to the coordinate system of the window, subtract the window origin coordinates from the mouse position coordinates. Use theGetConsoleScreenBufferInfo function to determine the window origin coordinates.

The dwButtonState member of the MOUSE_EVENT_RECORD structure has a bit corresponding to each mouse button. The bit is 1 if the button is down and 0 if the button is up. A button-release event is detected by a 0 value for thedwEventFlags member of MOUSE_EVENT_RECORD and a change in a button's bit from 1 to 0. TheGetNumberOfConsoleMouseButtons function retrieves the number of buttons on the mouse.


http://msdn.microsoft.com/en-us/library/windows/desktop/ms684239(v=vs.85).aspx

MOUSE_EVENT_RECORD structure

Describes a mouse input event in a console INPUT_RECORD structure.

Syntax

 
typedef struct _MOUSE_EVENT_RECORD {
  COORD dwMousePosition;
  DWORD dwButtonState;
  DWORD dwControlKeyState;
  DWORD dwEventFlags;
} MOUSE_EVENT_RECORD;

Members

dwMousePosition

COORD structure that contains the location of the cursor, in terms of the console screen buffer's character-cell coordinates.

dwButtonState

The status of the mouse buttons. The least significant bit corresponds to the leftmost mouse button. The next least significant bit corresponds to the rightmost mouse button. The next bit indicates the next-to-leftmost mouse button. The bits then correspond left to right to the mouse buttons. A bit is 1 if the button was pressed.

The following constants are defined for the first five mouse buttons.

ValueMeaning
FROM_LEFT_1ST_BUTTON_PRESSED
0x0001

The leftmost mouse button.

FROM_LEFT_2ND_BUTTON_PRESSED
0x0004

The second button from the left.

FROM_LEFT_3RD_BUTTON_PRESSED
0x0008

The third button from the left.

FROM_LEFT_4TH_BUTTON_PRESSED
0x0010

The fourth button from the left.

RIGHTMOST_BUTTON_PRESSED
0x0002

The rightmost mouse button.

dwControlKeyState

The state of the control keys. This member can be one or more of the following values.

ValueMeaning
CAPSLOCK_ON
0x0080

The CAPS LOCK light is on.

ENHANCED_KEY
0x0100

The key is enhanced.

LEFT_ALT_PRESSED
0x0002

The left ALT key is pressed.

LEFT_CTRL_PRESSED
0x0008

The left CTRL key is pressed.

NUMLOCK_ON
0x0020

The NUM LOCK light is on.

RIGHT_ALT_PRESSED
0x0001

The right ALT key is pressed.

RIGHT_CTRL_PRESSED
0x0004

The right CTRL key is pressed.

SCROLLLOCK_ON
0x0040

The SCROLL LOCK light is on.

SHIFT_PRESSED
0x0010

The SHIFT key is pressed.

dwEventFlags

The type of mouse event. If this value is zero, it indicates a mouse button being pressed or released. Otherwise, this member is one of the following values.

ValueMeaning
DOUBLE_CLICK
0x0002

The second click (button press) of a double-click occurred. The first click is returned as a regular button-press event.

MOUSE_HWHEELED
0x0008

The horizontal mouse wheel was moved.

If the high word of the dwButtonState member contains a positive value, the wheel was rotated to the right. Otherwise, the wheel was rotated to the left.

MOUSE_MOVED
0x0001

A change in mouse position occurred.

MOUSE_WHEELED
0x0004

The vertical mouse wheel was moved.

If the high word of the dwButtonState member contains a positive value, the wheel was rotated forward, away from the user. Otherwise, the wheel was rotated backward, toward the user.

Remarks

Mouse events are placed in the input buffer when the console is in mouse mode (ENABLE_MOUSE_INPUT).

Mouse events are generated whenever the user moves the mouse, or presses or releases one of the mouse buttons. Mouse events are placed in a console's input buffer only when the console group has the keyboard focus and the cursor is within the borders of the console's window.



Buffer-Resizing Events

A console window's menu enables the user to change the size of the active screen buffer; this change generates a buffer-resizing event. Buffer-resizing events are placed in the input buffer if the console's input mode is set toENABLE_WINDOW_INPUT (that is, the default mode is disabled).

If the input event is a buffer-resizing event, the Event member of INPUT_RECORD is aWINDOW_BUFFER_SIZE_RECORD structure containing the new size of the console screen buffer, expressed in character-cell columns and rows.

If the user reduces the size of the console screen buffer, any data in the discarded portion of the buffer is lost.

Changes to the console screen buffer size as a result of application calls to the SetConsoleScreenBufferSize function are not generated as buffer-resizing events.


Describes a change in the size of the console screen buffer.

Syntax

 
typedef struct _WINDOW_BUFFER_SIZE_RECORD {
  COORD dwSize;
} WINDOW_BUFFER_SIZE_RECORD;

Members

dwSize

COORD structure that contains the size of the console screen buffer, in character cell columns and rows.

Remarks

Buffer size events are placed in the input buffer when the console is in window-aware mode (ENABLE_WINDOW_INPUT).




#include <windows.h>
#include <stdio.h>

HANDLE hStdin; 
DWORD fdwSaveOldMode;

VOID ErrorExit(LPSTR);
VOID KeyEventProc(KEY_EVENT_RECORD); 
VOID MouseEventProc(MOUSE_EVENT_RECORD); 
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD); 
 
int main(VOID) 
{ 
    DWORD cNumRead, fdwMode, i; 
    INPUT_RECORD irInBuf[128]; 
    int counter=0;
 
    // Get the standard input handle. 
 
    hStdin = GetStdHandle(STD_INPUT_HANDLE); 
    if (hStdin == INVALID_HANDLE_VALUE) 
        ErrorExit("GetStdHandle"); 
 
    // Save the current input mode, to be restored on exit. 
 
    if (! GetConsoleMode(hStdin, &fdwSaveOldMode) ) 
        ErrorExit("GetConsoleMode"); 

    // Enable the window and mouse input events. 
 
    fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT; 
    if (! SetConsoleMode(hStdin, fdwMode) ) 
        ErrorExit("SetConsoleMode"); 
 
    // Loop to read and handle the next 100 input events. 
 
    while (counter++ <= 100) 
    { 
        // Wait for the events. 
 
        if (! ReadConsoleInput( 
                hStdin,      // input buffer handle 
                irInBuf,     // buffer to read into 
                128,         // size of read buffer 
                &cNumRead) ) // number of records read 
            ErrorExit("ReadConsoleInput"); 
 
        // Dispatch the events to the appropriate handler. 
 
        for (i = 0; i < cNumRead; i++) 
        {
            switch(irInBuf[i].EventType) 
            { 
                case KEY_EVENT: // keyboard input 
                    KeyEventProc(irInBuf[i].Event.KeyEvent); 
                    break; 
 
                case MOUSE_EVENT: // mouse input 
                    MouseEventProc(irInBuf[i].Event.MouseEvent); 
                    break; 
 
                case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing 
                    ResizeEventProc( irInBuf[i].Event.WindowBufferSizeEvent ); 
                    break; 
 
                case FOCUS_EVENT:  // disregard focus events 
 
                case MENU_EVENT:   // disregard menu events 
                    break; 
 
                default: 
                    ErrorExit("Unknown event type"); 
                    break; 
            } 
        }
    } 

    // Restore input mode on exit.

    SetConsoleMode(hStdin, fdwSaveOldMode);
 
    return 0; 
}

VOID ErrorExit (LPSTR lpszMessage) 
{ 
    fprintf(stderr, "%s
", lpszMessage); 

    // Restore input mode on exit.

    SetConsoleMode(hStdin, fdwSaveOldMode);

    ExitProcess(0); 
}

VOID KeyEventProc(KEY_EVENT_RECORD ker)
{
    printf("Key event: ");

    if(ker.bKeyDown)
        printf("key pressed
");
    else printf("key released
");
}

VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
#ifndef MOUSE_HWHEELED
#define MOUSE_HWHEELED 0x0008
#endif
    printf("Mouse event: ");
    
    switch(mer.dwEventFlags)
    {
        case 0:

            if(mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
            {
                printf("left button press 
");
            }
            else if(mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
            {
                printf("right button press 
");
            }
            else
            {
                printf("button press
");
            }
            break;
        case DOUBLE_CLICK:
            printf("double click
");
            break;
        case MOUSE_HWHEELED:
            printf("horizontal mouse wheel
");
            break;
        case MOUSE_MOVED:
            printf("mouse moved
");
            break;
        case MOUSE_WHEELED:
            printf("vertical mouse wheel
");
            break;
        default:
            printf("unknown
");
            break;
    }
}

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr)
{
    printf("Resize event
");
    printf("Console screen buffer is %d columns by %d rows.
", wbsr.dwSize.X, wbsr.dwSize.Y);
}
原文地址:https://www.cnblogs.com/threef/p/3201631.html