【问题标题】:Keyboard / Mouse input in C++C++ 中的键盘/鼠标输入
【发布时间】:2011-12-09 12:57:22
【问题描述】:

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

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

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

或者:如果用户在 -> 中按下鼠标左键,就会发生某些事情。

我不得不提一下,我对整个编程还是很陌生。我知道基本的 OOP 编程,但仅此而已。我肯定这会涉及到我还不知道的东西,我不介意,我只是要求你解释清楚,并可能给出一个例子,以便我知道如何使用它。

谢谢。

【问题讨论】:

  • 如果您正在编写一个 C++ 控制台应用程序,这比您想象的要困难得多。您必须收听 Windows 消息泵以获取各种消息,并对其进行解释。这会打开一整罐蠕虫。

标签: c++ input keyboard mouse


【解决方案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,
                         &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;
}

【讨论】:

  • 非常感谢您的宝贵时间。我发现这真的很有帮助。
  • 我想知道你能否告诉我如何检查一个键何时被单独按下/释放,而不是作为一个整体来检查键事件?
【解决方案2】:

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

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

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

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

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

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

【讨论】:

  • 非常感谢^^。当涉及到这背后的理论时,这真的很有帮助。
  • 有用,我认为,对于 OP.++ 是必要的
【解决方案3】:

Windows 还是控制台?

如果是控制台,使用:

std::cin >> myVar;

【讨论】:

  • 对不起,我忘了说我正在尝试在不中断程序的情况下接受输入。我已经编辑了我原来的问题以反映这一点。感谢您花时间回答。
【解决方案4】:

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

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

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

【讨论】:

  • 对不起,我忘了说我正在尝试在不中断程序的情况下接受输入。我已经编辑了我原来的问题以反映这一点。感谢您抽出宝贵时间回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-18
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-01
  • 2021-07-01
相关资源
最近更新 更多