控制台输入缓冲区

每个控制台都有一个包含输入事件记录队列的输入缓冲区。 当主机的窗口具有键盘焦点时,控制台会将每个输入事件(例如单个击键、鼠标移动或鼠标按钮单击)设置为它放置在主机输入缓冲区中的输入记录。

应用程序可以使用 高级控制台 I/O 函数间接访问主机的输入缓冲区,或者直接使用 低级控制台输入函数访问控制台的输入缓冲区。 高级输入函数筛选并处理输入缓冲区中的数据,只返回输入字符流。 低级别输入函数使应用程序可以直接从控制台的输入缓冲区读取输入记录,或将输入记录放入输入缓冲区。 若要打开控制台输入缓冲区的句柄,请在对 CreateFile 函数的调用中指定 CONIN$ 值。

输入记录是一种结构,包含有关所发生事件的类型的信息(键盘、鼠标、窗口调整大小、焦点或菜单事件)以及有关事件的特定详细信息。 INPUT_RECORD结构中的 EventType 成员指示记录中包含哪种类型的事件。

焦点和菜单事件放置在控制台的输入缓冲区中,供系统内部使用,应用程序应忽略。

键盘事件

按下或释放任何键时,将生成键盘事件;这包括控制键。 但是,当按下并释放时,ALT 键对系统具有特殊意义,而不会与其他字符组合,并且不会传递到应用程序。 此外,如果输入句柄处于处理模式,则不会传递 Ctrl+C 键组合。

如果输入事件是击键,INPUT_RECORD中的事件成员是包含以下信息的KEY_EVENT_RECORD结构:

  • 一个布尔值,指示键是按下还是释放。
  • 当某个键被按住时,重复计数可以大于 1。
  • 虚拟密钥代码,以独立于设备的方式标识给定密钥。
  • 虚拟扫描代码,指示键盘硬件生成的设备依赖值。
  • 转换后的 Unicode™ 或 ANSI 字符。
  • 一个标志变量,指示控制键的状态(ALT、CTRL、SHIFT、NUM LOCK、SCROLL LOCK 和 CAPS LOCK 键)以及指示是否按下了增强键。 IBM® 101 键和 102 键键盘的增强键是数字键盘左侧的 INS、DEL、HOME、END、PAGE UP、PAGE DOWN 和箭头键,以及数字键盘左侧的除号(/)和 ENTER 键。

鼠标事件

每当用户移动鼠标或按下或释放其中一个鼠标按钮时,就会生成鼠标事件。 仅当满足以下条件时,鼠标事件才会放置在输入缓冲区中:

  • 控制台输入模式设置为 ENABLE_MOUSE_INPUT (默认模式)。
  • 控制台窗口具有键盘焦点。
  • 鼠标指针位于控制台窗口的边框内。

如果输入事件是鼠标事件,INPUT_RECORD中的事件成员是包含以下信息的MOUSE_EVENT_RECORD结构:

  • 鼠标指针的坐标,以控制台屏幕缓冲区的坐标系中的字符单元格行和列为单位。
  • 指示鼠标按钮状态的标志变量。
  • 一个标志变量,指示控制键的状态(ALT、CTRL、SHIFT、NUM LOCK、SCROLL LOCK 和 CAPS LOCK)以及指示是否按下了增强键。 IBM 101 键和 102 键键盘的增强键是数字键盘左侧的 INS、DEL、HOME、END、PAGE UP、PAGE DOWN 和箭头键,以及数字键盘左侧的除号(/)和 ENTER 键。
  • 一个标志变量,指示事件是普通按钮按下事件还是按钮释放事件、鼠标移动事件或双击事件的第二次单击。

注释

鼠标位置坐标以控制台屏幕缓冲区(而不是控制台窗口)为单位。 屏幕缓冲区可能已滚动到窗口,因此窗口左上角不一定是控制台屏幕缓冲区的 (0,0) 坐标。 若要确定鼠标相对于窗口坐标系的坐标,请从鼠标位置坐标中减去窗口原点坐标。 使用 GetConsoleScreenBufferInfo 函数确定窗口原点坐标。

MOUSE_EVENT_RECORD结构的 dwButtonState 成员与每个鼠标按钮对应一点。 如果按钮关闭,则位为 1;如果按钮已启动,则为 0。 按钮释放事件由 MOUSE_EVENT_RECORD dwEventFlags 成员的 0 值和按钮位从 1 到 0 的更改检测到。 GetNumberOfConsoleMouseButtons 函数检索鼠标上的按钮数。

Buffer-Resizing 事件

控制台窗口的菜单使用户能够更改活动屏幕缓冲区的大小;此更改生成缓冲区大小调整事件。 如果控制台的输入模式设置为 ENABLE_WINDOW_INPUT (即禁用默认模式),则缓冲区大小调整事件将放置在输入缓冲区中。

如果输入事件是缓冲区大小调整事件,则 INPUT_RECORD的事件成员是包含控制台屏幕缓冲区的新大小的WINDOW_BUFFER_SIZE_RECORD结构,以字符单元格列和行表示。

如果用户减小了控制台屏幕缓冲区的大小,则缓冲区的放弃部分中的任何数据都将丢失。

由于应用程序调用 SetConsoleScreenBufferSize 函数而对控制台屏幕缓冲区大小的更改不会生成为缓冲区大小调整事件。