【问题标题】:How to get Mouse input inside a C console program on Windows-10?如何在 Windows-10 上的 C 控制台程序中获取鼠标输入?
【发布时间】:2017-10-17 16:37:30
【问题描述】:

我需要在我的简单 C 控制台程序中与用户的鼠标输入进行交互。我做了一些研究,发现a related Microsoft's docs on their page here。首先,我复制了他们所有的示例代码并将其粘贴到我的编辑器中。编译后,它编译得很好,带有一个漂亮的小“.exe”,运行时,它会正确地告诉/打印所有“键事件”和“调整大小事件”,但没有鼠标事件!如何在 C 控制台程序中成功获取鼠标输入?我的MCVE 是微软网站上给定的sample-code here,因为我逐字使用了该示例代码!我使用的是 Windows 10 Pro (1703),以防万一。


编辑: - 这似乎不是我独有的问题。另一个 StackOverflow 用户 also reported the same problem here 在他的 Windows-10 系统上。 His provided MCVE 也在 Windows-7 上工作,但不在 Windows-10 上,就像我在 Microsoft 网站上引用的 MCVE 作为示例代码一样,可能在较旧的 Windows 版本上工作,但不在 Windows-10 上,其中 “快速编辑模式” 似乎在 “Console-Defaults” 中启用。

【问题讨论】:

  • 您是否在 IDE 中运行它?
  • 我已经使用 Windows 7 和 MSVC 2015 编译并运行了相同的代码示例,当从控制台或 GUI 文件查看器运行时,它会按预期打印出鼠标事件。我没有使用 IDE。
  • @stark 不。我在 IDE 之外独立运行编译后的“.exe”。在“原子”中键入(粘贴)代码。并使用命令“gcc inputwin.c -o mouse”在命令提示符下通过 GCC 编译源代码(inputwin.c 是我粘贴该示例的文件名,该命令生成名为“.exe”的鼠标)。然后,我从它所在的文件夹中的 Windows 资源管理器中运行该 mouse.exe。
  • @WeatherVane 我使用的是 Windows 10 专业版 (1703)。我的编译器是 GCC。在命令提示符处编译该示例。
  • @WeatherVane 阅读您的评论后,我继续安装包含 Micosoft Visual C++ 2017 的 Microsoft Visual Studio Community 2017 版本 15.3.3(安装版本:社区),并创建了“新项目(Windows 控制台应用程序) )'。逐字粘贴所有示例代码!运行“构建解决方案”,在其默认路径“C:\Users\FAQi\source\repos\ConsoleApplication1\Debug\ConsoleApplication1.exe”中生成具有默认项目名称(“ConsoleApplication1.exe”)的“.exe”。去了那里。跑那个。结果一样! “......正确地告诉/打印所有'键事件'和'调整大小事件',但没有鼠标事件!”

标签: c windows cmd windows-10 windows-console


【解决方案1】:

花了几个小时后,我找到了微软官方sample code here 引用我的问题失败的罪魁祸首。罪魁祸首就是控制台本身!实际上这是一个'设置',即'控制台窗口'的'快速编辑模式'

您可以通过以下方式访问它:

  1. 打开命令提示符并右键单击其标题栏,然后单击“默认值”
  2. 将出现一个对话框,标题为'Console Windows Properties'。在选项选项卡的编辑选项子标题下,您会发现'快速编辑模式'复选框!

我在下面附上了屏幕截图:

问题是由我的 Windows 10 上默认启用(选中复选框)的 '快速编辑模式' 选项引起的。在此启用状态下,此 '快速编辑模式' 消耗了所有鼠标事件并且没有向我的 '.exe' 发送任何事件。

当这个 '快速编辑模式' 选项'复选框未选中(禁用)时,程序会按照sample-code here 中的预期/编码正常运行,告诉/打印所有鼠标事件。 [呸! ]

注意:“控制台属性”中的更改需要重新启动控制台才能生效。


编辑:改进的“便携式”解决方案!

上述解决方案不是“便携”的。这仅适用于本地机器,当然,它也是“手动工作”。为了使sample-code 工作而不需要用户禁用 快速编辑模式 '手动'如上所述,我们可以禁用 快速编辑模式 以编程方式在 sample-code 中添加以下代码行

        /* 
           Step-1:
           Disable 'Quick Edit Mode' option programmatically
        */
        fdwMode = ENABLE_EXTENDED_FLAGS;
        if (! SetConsoleMode(hStdin, fdwMode) )
             ErrorExit("SetConsoleMode");
        /* 
           Step-2:
           Enable the window and mouse input events,
           after you have already applied that 'ENABLE_EXTENDED_FLAGS'
           to disable 'Quick Edit Mode'
        */
        fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
        if (! SetConsoleMode(hStdin, fdwMode) )
            ErrorExit("SetConsoleMode");

我在Microsoft's docs about SetConsoleMode() 上发现了“ENABLE_EXTENDED_FLAGS”选项

在我们在SetConsoleMode() 函数中应用ENABLE_EXTENDED_FLAGS 后,即使用户在控制台默认值 选项中启用了“快速编辑模式”选项,我们的程序也会接收/打印所有“鼠标事件” .在我们的程序完成它的工作(在这个超级简单的场景中接收鼠标事件)之后,用户的 Console Defaults 将不受干扰,因为在我们的程序退出之前,它会恢复用户的原始状态(保存在我们的程序)控制台模式如下:

         /* Restore original console mode before exit. */
         SetConsoleMode(hStdin, fdwSaveOldMode);

正如sample-code there 所做的那样,效果很好,但是如果用户在其控制台中启用了“快速编辑模式”,无法打印鼠标事件。因此,要使sample-code 在用户的控制台默认值 启用“快速编辑模式”的情况下工作,我们应该在sample-code 中包含/放入代码-sn-p(应用@ 987654339@) 如上面的 'EDIT' 部分所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 2010-09-16
    • 1970-01-01
    • 2018-11-23
    • 2015-12-31
    • 1970-01-01
    相关资源
    最近更新 更多