【问题标题】:Non-blocking ReadConsoleInput非阻塞 ReadConsoleInput
【发布时间】:2018-03-21 08:56:55
【问题描述】:

我正在编写一个与鼠标交互的 Win32 控制台应用程序。我正在使用ReadConsoleInput 来像这样获得与窗口相关的鼠标移动。这是我的问题的简化版本:

int main(void)
{
    HANDLE hStdin;
    DWORD cNumRead;
    INPUT_RECORD irInBuf[128];
    hStdin = GetStdHandle(STD_INPUT_HANDLE);

    SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);

    while (1)
    {
        mouse_position_changed = 0;
        ReadConsoleInput(hStdin, irInBuf, 128, &cNumRead);

        /* input handler here: changes the cursor position if the mouse position changed;
             clears screen if mouse position changed;
             sets mouse_position_changed (self-explanatory).
             (this part of the code is irrelevant to the quesiton at hand) */

        if (!mouse_position_changed)
            putchar('0');
    }
}

(我已经删除了大部分代码,包括错误检查。这是我正在做的一个简单的、淡化的版本;它比使 0 远离光标的范围要大得多。)

我希望在移动鼠标时清除屏幕并将光标设置为鼠标坐标。这部分工作

我希望在鼠标移动时将0打印在屏幕上。这将产生 0 远离鼠标光标的效果。这不起作用,因为ReadConsoleInput 将阻塞直到它收到输入。

在收到更多输入之前,不会打印0。除非用户不断敲击键盘,否则不会打印任何内容,因为只要移动鼠标,屏幕就会被清除。

问题

即使没有输入,我也希望循环继续。 ReadConsoleInput 等待输入被读取,这意味着循环将暂停,直到敲击键盘或移动鼠标。

我正在寻找ReadConsoleInput 的替代方案,或使其成为非阻塞的方法。

【问题讨论】:

    标签: c windows winapi console mouse


    【解决方案1】:

    这一切都记录在ReadConsoleInput 中。您可以使用GetNumberOfConsoleInputEvents 确定是否有控制台输入。并且您可以使用PeekConsoleInput 来确定控制台输入事件的类型。

    所以GetNumberOfConsoleInputEvents 就是你所需要的。

    您还可以使用WaitForSingleObject 和控制台句柄来等待下一个可用输入。这也记录在ReadConsoleInput

    【讨论】:

    • 只是为了突出问题,小心WaitForSignleObject 或任何其他函数,如ReadConsole 内部阻塞逻辑。您甚至不应该调用这些函数,因为基本上您应该将数据通过管道传输到输出句柄,这意味着当您被输入阻塞时,句柄可能已经关闭/损坏/分离。即使没有输入数据,您也必须始终测试输出。 WaitForSingleObjectReadConsole 无法通过设计处理。这是 Window 控制台中的一个已知设计缺陷。
    猜你喜欢
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 2010-09-09
    • 2013-04-10
    相关资源
    最近更新 更多