C++中的键盘/鼠标输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7798242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:30:15  来源:igfitidea点击:

Keyboard / Mouse input in C++

c++inputkeyboardmouse

提问by Rohit

I'm wondering how to accept keyboard and mouse input in C++, using Visual Studio 2010, for Windows 7 32-bit.

我想知道如何在 Windows 7 32 位上使用 Visual Studio 2010 在 C++ 中接受键盘和鼠标输入。

--EDIT: I forgot to mention that I need keyboard / mouse input without interrupting the flow of the program. Something like a listener. I don't want to have to pause the program and ask for input, and then have the user type it out and press enter. What I'm looking for is more like:

--编辑:我忘了提到我需要键盘/鼠标输入而不中断程序流程。有点像倾听者。我不想暂停程序并要求输入,然后让用户输入并按回车键。我正在寻找的更像是:

If user presses W, S, A, D -> something happens.

如果用户按下 W、S、A、D -> 会发生一些事情。

Or: If user presses leftmousebutton in -> something happens.

或者:如果用户按下鼠标左键 -> 会发生一些事情。

I have to mention that I'm still very new to programming as a whole. I know basic OOP programming but that's about it. I'm definitely sure that this will involve things I don't know about yet, and I don't mind, I just ask that you explain it thoroughly, and possibly give an example so I know how to use it.

我不得不提一下,我对整个编程仍然很陌生。我知道基本的 OOP 编程,但仅此而已。我肯定这会涉及我还不知道的事情,我不介意,我只是要求你彻底解释它,并可能举个例子,这样我就知道如何使用它。

Thanks.

谢谢。

回答by Software_Designer

keyboard / mouse input without interrupting the flow

键盘/鼠标输入不中断流程

#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;
}

回答by Emilio Garavaglia

There are a number of related concepts behind this.

这背后有许多相关的概念。

At the very low level, the keyboard and the mouse are hardware devices that generates some "interrupts" (in the form of electric signals) to the CPU. The operating system provides some driversthat handle such interrupts by decoding the device communication specific protocol, and "standardizing" (at OS level) those signals in the form of events.

在非常低的层次上,键盘和鼠标是向 CPU产生一些“中断”(以电信号的形式)的硬件设备。操作系统提供了一些驱动程序,通过解码设备通信特定协议来处理此类中断,并以事件的形式“标准化”(在操作系统级别)这些信号。

With "console applications", the operating system handles those events (the keyboard in particular) by filling up an input buffer (essentially a char[]) that is made accessible as a "virtually infinite sequence of characters" (complicated name for "file") named "CON", thus mimicking the "infinite teletype model" of the early days computers. In a C++ program, the standard library -at program startup- associates to that "file" the std::cinand std::coutstreamobjects, so you can read the input character sequence using the std::istreamfunctions and operators.

使用“控制台应用程序”,操作系统通过填充输入缓冲区(本质上是一个字符 [])来处理这些事件(特别是键盘),该缓冲区可以作为“几乎无限的字符序列”(“文件”的复杂名称)访问”)命名为“CON”,从而模仿早期计算机的“无限电传模型”。在 C++ 程序中,标准库 - 在程序启动时 - 将std::cinstd::cout对象关联到该“文件” ,因此您可以使用std::istream函数和运算符读取输入字符序列。

With "graphical applications", unfortunately, there is no "early days model" to mimic, and "events" are left available as the operating system native structure. Different operating system differs in the way such events are represented and handled, but certain similitude can be seen. For Windows (since your question is about), a typical program retrieves those events in sequence with a "message loop" in which calling certain OS APIs. In that loop, the typical program will also give call another OS API to dispatch those event to appropriate "call-back" procedure, associated to a previously created "window". That callback procedure has to detect the event code, cast the parameter as appropriate and manage them doing the action required.

不幸的是,对于“图形应用程序”,没有可以模仿的“早期模型”,并且“事件”作为操作系统的本机结构可用。不同的操作系统在表示和处理此类事件的方式上有所不同,但可以看出某些相似之处。对于 Windows(因为您的问题是关于),典型的程序使用“消息循环”按顺序检索这些事件,其中调用某些操作系统 API。在该循环中,典型程序还将调用另一个 OS API,以将这些事件分派到与先前创建的“窗口”相关联的适当“回调”过程。该回调过程必须检测事件代码,适当地转换参数并管理它们执行所需的操作。

A more precise detail can be seen with a WIN32 programming tutorial like http://www.winprog.org/tutorial/. The most of the code is essentially C, since C is the language the API are formalized. For C++, a number of libraries have then been written to represent OS objects is the form of C++ classes, and mapping the OS APIs to those classes members. These libraries can be either OS specific (like MFC, WTL ...) or "multi-platform" (they exist in different version, mapping the API of various OSs into a same C++ interface) like WxWidget, Qt, Gtk, Fltk ...

可以使用 WIN32 编程教程(如http://www.winprog.org/tutorial/)查看更精确的细节。大多数代码本质上是 C,因为 C 是 API 被形式化的语言。对于 C++,随后编写了许多库来表示 OS 对象,这些库以 C++ 类的形式表示,并将 OS API 映射到这些类成员。这些库可以是特定于操作系统的(如 MFC、WTL ...)或“多平台”(它们存在于不同版本中,将各种操作系统的 API 映射到相同的 C++ 接口中),如 WxWidget、Qt、Gtk、Fltk。 ..

Hope this can give you more hints to think about.

希望这能给你更多思考的提示。

回答by Triton Man

Windows or Console?

Windows 还是控制台?

If console, use:

如果是控制台,请使用:

std::cin >> myVar;

回答by Colen

If you're writing a console application, you can use scanf or cin to get keyboard input. Console applications don't have any support for the mouse.

如果您正在编写控制台应用程序,您可以使用 scanf 或 cin 来获取键盘输入。控制台应用程序不支持鼠标。

If you're writing a GUI application, you'll build the app out of standard windows controls that have built-in behaviors for mouse and keyboard input. You can use these re-usable controls as is, or you can augment them to make them behave exactly how you want for your application.

如果您正在编写 GUI 应用程序,您将使用具有鼠标和键盘输入的内置行为的标准 Windows 控件构建应用程序。您可以按原样使用这些可重复使用的控件,也可以扩充它们以使它们的行为与您的应用程序完全一致。

For example, in a GUI application, there's a standard edit control you can use that the user can type into. Your program receives messages when the user enters text into it, and based on those messages, or on other events, you can retrieve the text and do things with it as required by your program.

例如,在 GUI 应用程序中,您可以使用一个标准的编辑控件,用户可以输入该控件。当用户在其中输入文本时,您的程序会收到消息,并且基于这些消息或其他事件,您可以检索文本并根据程序的要求对其进行处理。