使控制台窗口脱离“选择模式”以防止崩溃

时间:2019-02-09 07:52:45

标签: c# windows console

在C#应用程序中,我试图防止应用程序崩溃,基本上,我将控制台窗口用作日志显示窗口。我已经通过禁用关闭窗口解决了“关闭按钮”问题,并且通过“显示”和“隐藏”调用显示/隐藏菜单,所有这些都很好。

我最后的麻烦是,如果“文本选择”处于活动状态并且试图隐藏窗口。

我要么需要:

A。将窗口退出选择模式。 (不知道我该怎么做,因为选择会暂停所有输出。)

B。禁用“编辑”菜单的方式与禁用“关闭”菜单的方式相同,希望它也会禁用鼠标选择,但是我还没有找到任何方法来删除“编辑”菜单,我甚至不确定这样会阻止鼠标选择。

C。这似乎是最明显的,禁用鼠标选择,这是我当前在我的代码中选择的鼠标,但是它不起作用,所以我不确定我缺少什么。

有问题的代码

[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
 ....
[DllImport("Kernel32.dll", ExactSpelling = true)]
private static extern int SetConsoleMode(IntPtr hWnd, int wFlag);
 ....
public static void HideConsoleLog () {
    if (handle != IntPtr.Zero) {
        SetConsoleMode(handle, 0x0080);  // ENABLE_EXTENDED_FLAGS 0x0080
        ShowWindow(handle, (int)WinCntrlOpt.SW_HIDE);
        LogVisible = false;
    }
}

根据Documentation

  

ENABLE_EXTENDED_FLAGS 0x0080启用或禁用扩展   标志。请参阅ENABLE_INSERT_MODE和ENABLE_QUICK_EDIT_MODE。

然后...

  

ENABLE_QUICK_EDIT_MODE 0x0040此标志使用户可以使用   鼠标以选择和编辑文本。

     

要启用此模式,请使用ENABLE_QUICK_EDIT_MODE |   ENABLE_EXTENDED_FLAGS。要禁用此模式,请使用ENABLE_EXTENDED_FLAGS   没有此标志。

因此,看来我做得正确,并且确实可以运行,但是并不能防止鼠标选择。我确实知道,Microsoft tinkered with Consoles不久以前,而且我不知道是否已经打破了这个规定。

在堆栈交换上有一个similar question,但是那个地狱给出了一个可行的解决方案,并且实际上与我尝试使用C或C ++进行的操作相反。我可以插值,但这基本上就是我已经在这里尝试的内容。

这似乎是相同的建议,使用ENABLE_EXTENDED_FLAGS而不使用任何其他标志来禁用该选项,这就是我所拥有的。但这不起作用。

所以,我要么是在寻找错误的解决方案,要么是没有正确地做其他事情。

效果是,在打开控制台窗口的同时,您可以使用鼠标选择文本,该文本会自动将控制台置于Microsoft修补添加的“选择模式”中。这不是问题,但是是在该模式下,然后选择“显示日志”(主应用程序窗口中的选中标记的切换菜单选项),控制台窗口确实隐藏了,但是主窗口锁定并应用程序崩溃。 (我的猜测是,该窗口被该选择模式阻止。)当“选择模式”未激活时,它不会崩溃。

我也想从同一文档中尝试一下:

  

ENABLE_MOUSE_INPUT 0x0010如果鼠标指针在边框内   控制台窗口的窗口,并且该窗口具有键盘焦点,鼠标   鼠标移动和按钮按下产生的事件被放置在   输入缓冲区。这些事件被ReadFile或   即使启用了此模式,也可以使用ReadConsole。

问题是,它说:

  

创建控制台后,除ENABLE_WINDOW_INPUT之外的所有输入模式   默认情况下启用。

那么,如何禁用它?

对于任何将其退出选择模式或阻止其开始的解决方案,我都很好,这里我已经尝试过。

1 个答案:

答案 0 :(得分:2)

选择“显示日志”菜单选项时,窗口将最小化。 在窗口最小化之前,您必须检查用户是否选择了任何输入以防止崩溃。您可以使用GetConsoleSelectionInfo检查用户是否选择了任何内容。

CONSOLE_SELECTION_INFO out参数应等于0x00,否则,您需要处理选择。正如GetConsoleMode / SetConsoleMode中的文档所示,您需要调用ReadFileReadConsole来丢弃可能正在进行的选择事件。

实施此操作后,它不应再崩溃。