C - Используйте мышь и клавиатуру в консоли приложения без ожидания, чтобы нажать любую клавишу

0

(Извините за мой плохой английский) Ну, я пробовал с PeekConsoleInput() и работает. Но, если я не нажимаю клавишу, это возвращает мне нули, включая шнуры и ключ ASCII. Я хочу, чтобы это возвращало фактическое положение курсора мыши без нажатия любой клавиши или перемещения мыши и без "нулей" и без паузы кода. Это фрагмент основной программы (потому что это очень большой):

void inputhit(void)
{
#ifndef ENABLE_QUICK_EDIT_MODE
#define ENABLE_QUICK_EDIT_MODE 0x0040
#endif

    //static DWORD old_mode;
    static DWORD new_mode;
    static DWORD readed;
    static INPUT_RECORD ir[1];
    static int clic;
    static int key;
    screen.in = GetStdHandle(STD_INPUT_HANDLE);
  //  GetConsoleMode(screen.in, &old_mode);

    /* keep current configuration,
     * but enable mouse input,
     * disable quick edit mode,
     * disable ctrl+c
     */
    new_mode =
    (DWORD) (( ENABLE_MOUSE_INPUT) & ~ENABLE_QUICK_EDIT_MODE
         & ~ENABLE_PROCESSED_INPUT);
    SetConsoleMode(screen.in, new_mode);

  mouse_in_hit:

    PeekConsoleInput(screen.in, ir, 1, &readed);
    if (ir[0].EventType == KEY_EVENT) {
        key = ir[0].Event.KeyEvent.uChar.AsciiChar;
        if (key == 0) key = ir[0].Event.KeyEvent.wVirtualKeyCode + 255;
        }

    clic = (int) (ir[0].Event.MouseEvent.dwButtonState);

        printf("%d %d %d %d", (int) ir[0].Event.MouseEvent.dwMousePosition.Y,
           (int) ir[0].Event.MouseEvent.dwMousePosition.X,
           (int) clic,
           (int) key,
           );
    FlushConsoleInputBuffer(screen.in);
}

В результате:

Когда вы открываете программу из командной консоли в цикле, я перемещаю мышь и возвращает большой список коордов, например:

[Y  X  Mouseclick Key ]
10 10  1 0 <--- this result when the press or moves the mouse
0  0   0 0 <--- this result when is not pressed or moved the mouse
21 13  2 0 
...

И я хочу:

[Y  x  MouseClick Key ]
 10 23 0 0 <-- this result when the mouse is in this position on the window (without moving it)
 12 9  1 0 <-- this result when click
Теги:
console-application
command-line
mouse

1 ответ

0

Я бы не использовал PeekConsoleInput для этого, я бы использовал комбинацию GetNumberOfConsoleInputEvents чтобы решить, есть ли доступный вход и ReadConsoleInput для извлечения и обработки.

Я немного изменил пример MSDN, чтобы читать/обрабатывать, когда есть доступный вход, и делать другие вещи, когда их нет. Я предполагаю, что вы проводите опрос для ввода, и вы можете адаптировать его так же, как и к работе.

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

#ifndef MOUSE_HWHEELED
#define MOUSE_HWHEELED 0x0008
#endif

HANDLE hStdin;
DWORD fdwSaveOldMode;

void ErrorExit(LPSTR lpszMessage)
{
    fprintf(stderr, "%s\n", lpszMessage);
    SetConsoleMode(hStdin, fdwSaveOldMode);
    ExitProcess(0);
}

bool KeyEventProc(const KEY_EVENT_RECORD& ker)
{
    printf("key %s: %c\n", ker.bKeyDown ? "pressed" : "released", ker.uChar.AsciiChar);
    return ker.uChar.AsciiChar == 'q';
}

void MouseEventProc(const MOUSE_EVENT_RECORD& mer)
{
    const int X = mer.dwMousePosition.X;
    const int Y = mer.dwMousePosition.Y;
    const int dir = static_cast<int>(mer.dwButtonState) >> 16;
    switch(mer.dwEventFlags)
    {
        case 0:
            if(mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
            {
                printf("left button press @ %d %d\n", X, Y);
            }
            else if(mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
            {
                printf("right button press @ %d %d\n", X, Y);
            }
            else
            {
                //You'd need more code here to track releases or more buttons.
                printf("other button press/release @ %d %d\n", X, Y);
            }
            break;
        case DOUBLE_CLICK:
            printf("double click @ %d %d\n", X, Y);
            break;
        case MOUSE_HWHEELED:
            printf("horizontal mouse wheel %s\n", dir >= 0 ? "right" : "left");
            break;
        case MOUSE_WHEELED:
            printf("vertical mouse wheel %s\n", dir >= 0 ? "up" : "down");
            break;
        case MOUSE_MOVED:
            printf("mouse moved: %d %d\n", mer.dwMousePosition.X, mer.dwMousePosition.Y);
            break;
        default:
            printf("unknown mouse event\n");
            break;
    }
}

int main()
{
    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    if(hStdin == INVALID_HANDLE_VALUE)
        ErrorExit("GetStdHandle");

    if(!GetConsoleMode(hStdin, &fdwSaveOldMode))
        ErrorExit("GetConsoleMode");

    DWORD fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
    if(!SetConsoleMode(hStdin, fdwMode))
        ErrorExit("SetConsoleMode");

    std::vector<INPUT_RECORD> irInBuf;
    DWORD numEventsAvailable;
    DWORD lastTickCount = GetTickCount();
    bool finished = false;
    while(!finished)
    {
        GetNumberOfConsoleInputEvents(hStdin, &numEventsAvailable);
        if(numEventsAvailable)
        {
            irInBuf.resize(numEventsAvailable);
            DWORD cNumRead;
            ReadConsoleInput(hStdin, &irInBuf[0], irInBuf.size(), &cNumRead);
            for(DWORD i = 0; i < cNumRead; i++)
            {
                switch(irInBuf[i].EventType)
                {
                    case KEY_EVENT:
                        finished = KeyEventProc(irInBuf[i].Event.KeyEvent);
                        break;
                    case MOUSE_EVENT:
                        MouseEventProc(irInBuf[i].Event.MouseEvent);
                        break;
                    default:
                        break;
                }
            }
        }
        else
        {
            if(GetTickCount() - lastTickCount > 1000)
            {
                lastTickCount = GetTickCount();
                printf("Press 'q' to exit\n");
            }
        }
    }
    SetConsoleMode(hStdin, fdwSaveOldMode);
    return 0;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню