You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows 10下控制台鼠标事件C代码无响应问题排查与适配

解决Windows 10下控制台鼠标交互无响应问题

不存在缺失库或Windows API兼容问题,问题源于Windows 10控制台的默认行为和原代码的几个疏漏,具体修改如下:

  • 禁用快速编辑模式:Windows 10控制台默认开启快速编辑模式,会拦截鼠标输入事件。需要在设置控制台模式时,添加ENABLE_EXTENDED_FLAGS并排除ENABLE_QUICK_EDIT_MODE,确保鼠标事件能被程序捕获。
  • 补充ErrorExit函数实现:原代码调用了ErrorExit但未定义该函数,导致编译失败或运行崩溃,必须补充实现。
  • 实时刷新输出缓冲:printf的输出可能因系统缓冲无法即时显示,每次输出后调用fflush(stdout)强制刷新。
  • 处理所有读取到的输入事件:原代码仅处理第一个输入事件,应循环遍历ReadConsoleInput返回的所有事件(cNumRead个),避免遗漏鼠标操作。
  • 可选:支持鼠标移动事件:若需要响应鼠标移动,可在MouseEventProc中处理MOUSE_MOVED事件标志。

修改后的完整代码:

#include <windows.h>
#include <stdio.h>
#include <conio.h>

HANDLE hStdin;                     
DWORD fdwSaveOldMode;               

DWORD cNumRead, fdwMode, i;         
INPUT_RECORD irInBuf[128];

// 补充实现ErrorExit函数
VOID ErrorExit(LPCSTR lpszMessage)
{
    fprintf(stderr, "%s: error %lu\n", lpszMessage, GetLastError());
    ExitProcess(1);
}

VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
    switch(mer.dwEventFlags)
    {
        case 0: // 鼠标按钮按下/释放
            if(mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
            {
                printf("左键按下   X坐标: %d\n", mer.dwMousePosition.X);
                fflush(stdout); // 刷新输出缓冲
            }
            else if(mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
            {
                printf("右键按下\n");
                fflush(stdout);
            }
            else
            {
                printf("按钮按下\n");
                fflush(stdout);
            }
            break;
        case MOUSE_MOVED: // 可选:处理鼠标移动
            printf("鼠标移动   X坐标: %d, Y坐标: %d\n", mer.dwMousePosition.X, mer.dwMousePosition.Y);
            fflush(stdout);
            break;
        default:
            break;
    }
}

int main(VOID)
{
    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    if (hStdin == INVALID_HANDLE_VALUE) ErrorExit("GetStdHandle");
    
    if (!GetConsoleMode(hStdin, &fdwSaveOldMode)) ErrorExit("GetConsoleMode");
    
    // 修改控制台模式:启用窗口和鼠标输入,同时禁用快速编辑模式
    fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS;
    fdwMode &= ~ENABLE_QUICK_EDIT_MODE;
    if (!SetConsoleMode(hStdin, fdwMode)) ErrorExit("SetConsoleMode");

    while(1)
    {
        if (!ReadConsoleInput(
                hStdin,      
                irInBuf,     
                128,         // 一次读取最多128个事件,而非1个
                &cNumRead)) ErrorExit("ReadConsoleInput");

        // 遍历所有读取到的输入事件
        for(i=0; i < cNumRead; i++)     
        {
            switch(irInBuf[i].EventType)
            {
                case MOUSE_EVENT: // 处理鼠标输入
                    MouseEventProc(irInBuf[i].Event.MouseEvent);
                    break;
                // 可选:处理其他输入类型,如键盘事件
                case KEY_EVENT:
                    // 按ESC退出程序
                    if(irInBuf[i].Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
                    {
                        SetConsoleMode(hStdin, fdwSaveOldMode);
                        return 0;
                    }
                    break;
                default:
                    break;
            }
        }
    }

    SetConsoleMode(hStdin, fdwSaveOldMode);
    return 0;
}

内容的提问来源于stack exchange,提问作者Jonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:05:14