首页 > 解决方案 > 如何使用 Turbo C++ 并行运行两个功能,一个用于键盘,一个用于鼠标?

问题描述

我正在尝试使用 Turbo-C++ 同时获得鼠标和键盘输入。

我想使用两个功能。第一个函数是main可以接受键盘输入或调用delay函数dos.h以暂时停止正常运行的函数main()

第二个函数处理鼠标输入:

void mouse()
 {
    union REGS in,out;
    in.x.ax=1; // Show mouse pointer
    int86(0x33,&in,&out); //interrupt call
    while(1)
     {
       //print the location whenever it changes (not required)
     }
 }

标签: c++interruptlow-levelturbo-c++

解决方案


语境

如果我正确理解了这个问题,那么您正在编写一个将在 DosBox 内的 16 位 MS-DOS 下运行的程序。该程序预计将响应鼠标和键盘输入。它可能还希望在等待输入时执行一些计算。

轮询

最简单和最直接的解决方案是使用polling,这意味着您坐在一个循环中,询问键盘和鼠标是否有新的输入要响应。在伪代码中:

  while (true) {
    while (keyboard_has_activity()) {
      process_keyboard_input();
    }
    while (mouse_has_activity()) {
      process_mouse_input();
    }
    do_other_computation_for_a_short_time();
  }

怎么写keyboard_has_activity?你在评论中提到kbhitconio.h;那应该工作。您还可以使用较低级别的中断(尽管我不知道有什么理由不使用kbhit)。

注意:process_keyboard_input应该只读取当前可用的尽可能多的字符。如果您的程序涉及等待用户按 Enter,那么您必须将输入的字符存储在(比如说)一个数组中,直到您真正看到 Enter 键,然后一次处理所有输入。

怎么写mouse_has_activity?据我所知,您必须使用INT 0x33例程来查询当前鼠标状态并将其与上次调用时的状态进行比较。

怎么写do_other_computation_for_a_short_time?您必须在算法中设计某种时间限制。例如,如果您正在编写一个国际象棋引擎,它会在每次(例如)棋盘评估后检查时钟,并在必要时停止,以便您可以轮询输入。当算法停止时,它必须在数据结构中记住它所在的位置,以便以后可以从该点恢复。一种常见的策略是维护一份工作清单:一份列出所有仍需完成的计算部分的清单。这是合作多任务的一种形式。

在任何情况下,您都希望时间限制不超过 10 毫秒,否则您可能会错过鼠标点击(用户可以在您注意到之前按下并释放按钮)。

此解决方案很简单,但不一定是最有效的,并且由于上述问题,如果时间限制太长,可能会丢失鼠标点击,因此可能不可靠。

中断

另一种方法是挂钩低级键盘和鼠标中断。这样,您安装的代码仅在触摸输入设备时运行,效率更高。但是,由于各种原因,要正确处理也更加困难,包括您几乎无法控制一段代码在被中断时正在做什么。

非答案:线程

在这种环境中,尝试将程序组织为两个线程(鼠标和键盘)同时运行两个功能是不切实际的。DOS没有线程设施,我不知道有什么方法可以在不重写操作系统的情况下添加它们。相反,您需要从一个控制线程完成所有操作。


推荐阅读