控制台应用程序在鼠标点击时卡死

5

我有一个非常简单的C#控制台应用程序,它显示一些文本并循环等待输入,直到按下Escape键或超时期满。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;

namespace SampleApp
{
    public static class Program
    {
        public static void Main (string [] args)
        {
            var key = new ConsoleKeyInfo();
            var watch = Stopwatch.StartNew();
            var timeout = TimeSpan.FromSeconds(5);

            Console.WriteLine("Press escape to return to the previous screen...");
            Console.WriteLine();

            do
            {
                Console.WriteLine("This screen will automatically close in " + ((timeout + TimeSpan.FromSeconds(1)) - watch.Elapsed).ToString(@"hh\:mm\:ss") + ".");

                if (Console.KeyAvailable) { key = Console.ReadKey(true); }
                else { Thread.Sleep(TimeSpan.FromSeconds(0.10D)); }
            }
           while ((key.Key != ConsoleKey.Escape) && (timeout > (watch.Elapsed - TimeSpan.FromSeconds(0.5D))));

            watch.Stop();
        }
    }
}

这个程序正常工作,但是如果我用鼠标点击控制台应用程序(例如为了获取焦点),屏幕上的所有活动都会冻结,直到我右键单击或按下Esc键。在此期间,控制台的标题也会更改为"选择AppName",假设"AppName"是之前的标题。
如果我先在控制台上右键单击,do {...} while ();循环似乎变得疯狂并打印出许多额外的行。
由于我不知道控制台的这种行为,不确定该问什么。这种情况是否可以预料?如果可以,我能否更改此行为?如果不能,希望能提供解决方法的建议。

6
听起来好像您已经不知何故激活了控制台窗口的标记和粘贴命令。通常是通过系统菜单(Alt + Space,编辑,标记/粘贴)来激活。当然,这与这段代码无关。 - Hans Passant
谢谢@HansPassant。我没有想到过那个。显然,在控制台默认设置中设置了快速编辑模式(Alt + Space,默认值,选项,编辑选项,快速编辑模式)的原因。取消选择后解决了这个问题。你应该把你的评论发表为一个答案。 - Raheel Khan
2个回答

21

通过 Hans 上面的评论解决了问题。

看起来你在某种情况下激活了控制台窗口的标记和粘贴命令。通常是通过系统菜单(Alt+Space,编辑,标记/粘贴)激活。当然这与这段代码无关。

显然,由于某些原因,在控制台默认设置中启用了快速编辑模式(Alt+Space,默认值,选项,编辑选项,快速编辑模式)。取消选中该选项即可解决问题。


3
//call this class to disable quick edit mode.

public static void Main()
{
//disable console quick edit mode
 DisableConsoleQuickEdit.Go();

}



using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;


static class DisableConsoleQuickEdit
{

    const uint ENABLE_QUICK_EDIT = 0x0040;

    // STD_INPUT_HANDLE (DWORD): -10 is the standard input device.
    const int STD_INPUT_HANDLE = -10;

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr GetStdHandle(int nStdHandle);

    [DllImport("kernel32.dll")]
    static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);

    [DllImport("kernel32.dll")]
    static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

    internal static bool Go()
    {

        IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);

        // get current console mode
        uint consoleMode;
        if (!GetConsoleMode(consoleHandle, out consoleMode))
        {
            // ERROR: Unable to get console mode.
            return false;
        }

        // Clear the quick edit bit in the mode flags
        consoleMode &= ~ENABLE_QUICK_EDIT;

        // set the new mode
        if (!SetConsoleMode(consoleHandle, consoleMode))
        {
            // ERROR: Unable to set console mode
            return false;
        }

        return true;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接