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

#c #input #keyboard #mouse

#c #ввод #клавиатура #мышь

Вопрос:

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

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

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

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

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

Спасибо.

Комментарии:

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

Ответ №1:

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

 #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,
                         amp;InRec,
                         1,
                         amp;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;
}
  

Комментарии:

1. Мне было интересно, не могли бы вы показать мне, как я мог бы проверить, когда клавиша нажата / отпущена по отдельности, а не ключевые события в целом?

Ответ №2:

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

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

С помощью «консольных приложений» операционная система обрабатывает эти события (в частности, клавиатуру), заполняя буфер ввода (по существу, 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 …

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

Комментарии:

1. Большое спасибо ^^. Это действительно помогает, когда дело доходит до теории, лежащей в основе этого.

2. Полезно и, я думаю, необходимо для OP.

Ответ №3:

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

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

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

Комментарии:

1. Извините, я забыл упомянуть, что я пытаюсь принять ввод, не прерывая программу. Я отредактировал свой первоначальный вопрос, чтобы отразить это сейчас. Спасибо, что нашли время ответить

Ответ №4:

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

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

 std::cin >> myVar;
  

Комментарии:

1. Извините, я забыл упомянуть, что я пытаюсь принять ввод, не прерывая программу. Я отредактировал свой первоначальный вопрос, чтобы отразить это сейчас. Спасибо, что нашли время ответить.