How to programmatic disable C# Console Application's Quick Edit mode?

前端 未结 5 1002
庸人自扰
庸人自扰 2020-11-27 14:34

I,ve tried several solutions found, like the one ->

http://www.pcreview.co.uk/forums/console-writeline-hangs-if-user-click-into-console-window-t1412701.html

相关标签:
5条回答
  • 2020-11-27 15:05

    Having read above answers, GetConsoleWindow() can not be used. Instead GetStdHandle() must be used.

    So here's a copy and paste class for enabling/disabling QuickEditMode. Call ConsoleWindow.QuickEditMode(false); to disable quick edit mode for the console window.

    using System;
    using System.Runtime.InteropServices;
    
    public static class ConsoleWindow
    {
        private static class NativeFunctions
        {
            public enum StdHandle : int
            {
                STD_INPUT_HANDLE = -10,
                STD_OUTPUT_HANDLE = -11,
                STD_ERROR_HANDLE = -12,
            }
    
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern IntPtr GetStdHandle(int nStdHandle); //returns Handle
    
            public enum ConsoleMode : uint
            {
                ENABLE_ECHO_INPUT = 0x0004,
                ENABLE_EXTENDED_FLAGS = 0x0080,
                ENABLE_INSERT_MODE = 0x0020,
                ENABLE_LINE_INPUT = 0x0002,
                ENABLE_MOUSE_INPUT = 0x0010,
                ENABLE_PROCESSED_INPUT = 0x0001,
                ENABLE_QUICK_EDIT_MODE = 0x0040,
                ENABLE_WINDOW_INPUT = 0x0008,
                ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200,
    
                //screen buffer handle
                ENABLE_PROCESSED_OUTPUT = 0x0001,
                ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002,
                ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004,
                DISABLE_NEWLINE_AUTO_RETURN = 0x0008,
                ENABLE_LVB_GRID_WORLDWIDE = 0x0010
            }
    
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
    
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
        }
    
        public static void QuickEditMode(bool Enable)
        {
            //QuickEdit lets the user select text in the console window with the mouse, to copy to the windows clipboard.
            //But selecting text stops the console process (e.g. unzipping). This may not be always wanted.
            IntPtr consoleHandle = NativeFunctions.GetStdHandle((int)NativeFunctions.StdHandle.STD_INPUT_HANDLE);
            UInt32 consoleMode;
    
            NativeFunctions.GetConsoleMode(consoleHandle, out consoleMode);
            if (Enable)
                consoleMode |= ((uint)NativeFunctions.ConsoleMode.ENABLE_QUICK_EDIT_MODE);
            else
                consoleMode &= ~((uint)NativeFunctions.ConsoleMode.ENABLE_QUICK_EDIT_MODE);
    
            consoleMode |= ((uint)NativeFunctions.ConsoleMode.ENABLE_EXTENDED_FLAGS);
    
            NativeFunctions.SetConsoleMode(consoleHandle, consoleMode);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 15:16

    By used combination of codes on below, I'm be able to enable or disable the Quick Edit mode.

    const int 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 int lpMode);
    
    [DllImport("kernel32.dll")]
    static extern bool SetConsoleMode(IntPtr hConsoleHandle, int dwMode);
    

    To enable, simple do currentConsoleMode &= ENABLE_QUICK_EDIT;

    And to disable, do currentConsoleMode &= ~ENABLE_QUICK_EDIT

    And then call SetConsoleMode.

    0 讨论(0)
  • 2020-11-27 15:23

    For those like me that like no-brainer code to copy/paste, here is the code inspired from the accepted answer:

    using System;
    using System.Runtime.InteropServices;
    
    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;
       }
    }
    
    0 讨论(0)
  • 2020-11-27 15:27

    If you want to disable quick edit mode, you need to call GetConsoleMode to get the current mode. Then clear the bit that enables quick edit, and call SetConsoleMode. Assuming you have the managed prototypes for the unmanaged functions, you would write:

    const int ENABLE_QUICK_EDIT = 0x0040;
    
    IntPtr consoleHandle = GetConsoleWindow();
    UInt32 consoleMode;
    
    // get current console mode
    if (!GetConsoleMode(consoleHandle, out consoleMode))
    {
        // Error: Unable to get console mode.
        return;
    }
    
    // Clear the quick edit bit in the mode flags
    mode &= ~ENABLE_QUICK_EDIT;
    
    // set the new mode
    if (!SetConsoleMode(consoleHandle, consoleMode))
    {
        // ERROR: Unable to set console mode
    }
    

    If you want to disable mouse input, you want to clear the mouse input bit.

    const int ENABLE_MOUSE_INPUT = 0x0010;
    
    mode &= ~ENABLE_MOUSE_INPUT;
    
    0 讨论(0)
  • 2020-11-27 15:31

    I just happened to stumble over the same problem with quick edit mode enabled in my console application, which is written in C, and has been working under windows 7 32 bit for ages. After porting (well not really porting, but adapting some code lines) it to windows 10 64 Bit (still being a 32 bit application), I observed the same behaviour. So I searched for a solution.

    But for a reason unknown to me, the code works the other way round, i.e setting the bit ENABLE_QUICK_EDIT_MODE in the mode parameter actually disables quick edit mode. And resetting the bit enables the quick edit mode...???

    Here is my code:

        /// <summary>
    /// This flag enables the user to use the mouse to select and edit text. To enable
    /// this option, you must also set the ExtendedFlags flag.
    /// </summary>
    const int QuickEditMode = 64;
    
    // ExtendedFlags must be combined with
    // InsertMode and QuickEditMode when setting
    /// <summary>
    /// ExtendedFlags must be enabled in order to enable InsertMode or QuickEditMode.
    /// </summary>
    const int ExtendedFlags = 128;
    
    BOOLEAN EnableQuickEdit()
    {
        HWND conHandle = GetStdHandle(STD_INPUT_HANDLE);
        int mode;
        DWORD dwLastError = GetLastError();
        if (!GetConsoleMode(conHandle, &mode))
        {
            // error getting the console mode. Exit.
            dwLastError = GetLastError();
            return (dwLastError == 0);
        }
        else 
            dwLastError = 0;
        mode = mode & ~QuickEditMode;
    
        if (!SetConsoleMode(conHandle, mode | ExtendedFlags))
        {
            // error setting console mode.
            dwLastError = GetLastError();
        }
        else
            dwLastError = 0;
        return (dwLastError == 0);
    }
    
    BOOLEAN DisableQuickEdit()
    {
        HWND conHandle = GetStdHandle(STD_INPUT_HANDLE);
        int mode;
        DWORD dwLastError = GetLastError();
    
        if (!GetConsoleMode(conHandle, &mode))
        {
            // error getting the console mode. Exit.
            dwLastError = GetLastError();
            return (dwLastError == 0);
        }
        else
            dwLastError = 0;
    
        mode = mode | QuickEditMode;
    
        if (!SetConsoleMode(conHandle, mode))
        {
            // error getting the console mode. Exit.
            dwLastError = GetLastError();
        }
        else
            dwLastError = 0;
        return (dwLastError == 0);
    }
    

    Greetings Wolfgang

    0 讨论(0)
提交回复
热议问题