Ввод клавиатуры / мыши в C ++ - PullRequest
       62

Ввод клавиатуры / мыши в C ++

6 голосов
/ 17 октября 2011

Мне интересно, как принять ввод с клавиатуры и мыши в C ++, используя Visual Studio 2010, для Windows 7 32-разрядная версия.

- РЕДАКТИРОВАТЬ: я забыл упомянуть, что мне нужно ввод с клавиатуры / мыши, не прерывая поток программы. Что-то вроде слушателя. Я не хочу останавливать программу и запрашивать ввод, а затем попросить пользователя ввести его и нажать клавишу ввода. То, что я ищу, больше похоже на:

Если пользователь нажимает W, S, A, D -> что-то происходит.

Или: если пользователь нажимает левую кнопку -> что-то происходит.

Я должен отметить, что я все еще очень плохо знаком с программированием в целом. Я знаю основы программирования ООП, но это все. Я определенно уверен, что это будет связано с вещами, о которых я пока не знаю, и я не возражаю, я просто прошу вас объяснить это подробно и, возможно, привести пример, чтобы я знал, как его использовать.

Спасибо.

Ответы [ 4 ]

13 голосов
/ 17 октября 2011

ввод с клавиатуры / мыши без прерывания потока

#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
    HANDLE hIn;
    HANDLE hOut;
    COORD KeyWhere;
    COORD MouseWhere;
    COORD EndWhere;
    bool Continue = TRUE;
    int KeyEvents = 0;
    int MouseEvents = 0;
    INPUT_RECORD InRec;
    DWORD NumRead;

    hIn = GetStdHandle(STD_INPUT_HANDLE);
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    cout << "Key Events   : " << endl;
    cout << "Mouse Events : " << flush;

    KeyWhere.X = 15;
    KeyWhere.Y = 0;
    MouseWhere.X = 15;
    MouseWhere.Y = 1;
    EndWhere.X = 0;
    EndWhere.Y = 3;

    while (Continue)
    {
        ReadConsoleInput(hIn,
                         &InRec,
                         1,
                         &NumRead);

        switch (InRec.EventType)
        {
        case KEY_EVENT:
            ++KeyEvents;
            SetConsoleCursorPosition(hOut,
                                     KeyWhere);
            cout << KeyEvents << flush;
            if (InRec.Event.KeyEvent.uChar.AsciiChar == 'x')
            {
                SetConsoleCursorPosition(hOut,
                                         EndWhere);
                cout << "Exiting..." << endl;
                Continue = FALSE;
            }
            break;

        case MOUSE_EVENT:
            ++MouseEvents;
            SetConsoleCursorPosition(hOut,
                                     MouseWhere);
            cout << MouseEvents << flush;
            break;
        }
    }

    return 0;
}
8 голосов
/ 17 октября 2011

За этим стоит ряд связанных понятий.

На очень низком уровне клавиатура и мышь являются аппаратными устройствами, которые генерируют некоторые " прерывания " (в формеэлектрические сигналы) к процессору.Операционная система предоставляет некоторые драйверы , которые обрабатывают такие прерывания, декодируя специальный протокол связи устройства и "стандартизируя" (на уровне ОС) эти сигналы в виде событий .

В «консольных приложениях» операционная система обрабатывает эти события (в частности, клавиатуру), заполняя входной буфер (по существу, char []), который становится доступным как «практически бесконечная последовательность символов» (сложное имядля «файла») с именем «CON», таким образом имитируя «модель бесконечного телетайпа» компьютеров первых дней.В программе на C ++ стандартная библиотека - при запуске программы - связывает с этим «файлом» объекты std::cin и std::cout stream , поэтому вы можете прочитать входную последовательность символов с помощью функций std::istreamи операторы.

К сожалению, в случае с «графическими приложениями» не существует «модели ранних дней» для имитации, и «события» остаются доступными в качестве собственной структуры операционной системы.Различные операционные системы отличаются тем, как такие события представляются и обрабатываются, но можно увидеть определенное сходство.Для Windows (поскольку ваш вопрос о том, что), типичная программа извлекает эти события в последовательности с «циклом сообщений», в котором вызывают определенные API-интерфейсы ОС.В этом цикле типичная программа также будет вызывать API-интерфейс другой ОС для отправки этого события в соответствующую процедуру «обратного вызова», связанную с ранее созданным «окном».Эта процедура обратного вызова должна обнаружить код события, привести соответствующий параметр и управлять им, выполнив требуемое действие.

Более точные детали можно увидеть в руководстве по программированию WIN32, например http://www.winprog.org/tutorial/. Наиболеекода по сути C, так как C является языком, API-интерфейс формализован.Для C ++ было написано несколько библиотек, представляющих объекты ОС в форме классов C ++ и отображающих API-интерфейсы ОС для этих классов.Эти библиотеки могут быть либо специфичными для ОС (например, MFC, WTL ...) или «мультиплатформенными» (они существуют в разных версиях, отображающих API разных ОС в один и тот же интерфейс C ++), например WxWidget, Qt, Gtk, Fltk...

Надеюсь, это даст вам больше советов для размышлений.

0 голосов
/ 17 октября 2011

Если вы пишете консольное приложение, вы можете использовать scanf или cin для ввода с клавиатуры.Консольные приложения не поддерживают мышь.

Если вы пишете приложение с графическим интерфейсом, вы создадите приложение из стандартных элементов управления Windows, которые имеют встроенные функции для ввода с клавиатуры и мыши.Вы можете использовать эти повторно используемые элементы управления как есть или дополнить их, чтобы они работали так, как вы хотите для своего приложения.

Например, в приложении с графическим интерфейсом пользователя есть стандартный элемент редактирования, который вы можете использоватьчто пользователь может ввести в.Ваша программа получает сообщения, когда пользователь вводит в нее текст, и на основе этих сообщений или других событий вы можете извлекать текст и делать с ним какие-либо действия, как того требует ваша программа.

0 голосов
/ 17 октября 2011

Windows или Консоль?

Если консоль, используйте:

std::cin >> myVar;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...