Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

But, i observed that mode in GetConsoleMode(IntPtr hConsoleHandle, out int mode) will be different for different console app. It is not constant.

Can I disable mouse clicks (right/left buttons) on a console application to achieve the same scenario. I found that it can be done with IMessageFilter but only for Window Form Application and not for console application.

Please guide.

like image 998
Himanshu Avatar asked Dec 01 '12 05:12

Himanshu


4 Answers

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;
   }
}
like image 191
Patrick from NDepend team Avatar answered Oct 30 '22 17:10

Patrick from NDepend team


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;
like image 28
Jim Mischel Avatar answered Oct 30 '22 16:10

Jim Mischel


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);
    }
}
like image 9
Mirco Babin Avatar answered Oct 30 '22 18:10

Mirco Babin


For those who use vb.net

Const ENABLE_QUICK_EDIT As UInteger = &H40
Const STD_INPUT_HANDLE As Integer = -10


   <DllImport("kernel32.dll", SetLastError:=True)>
Public Function GetStdHandle(ByVal nStdHandle As Integer) As IntPtr
End Function

<DllImport("kernel32.dll")>
Private Function GetConsoleMode(ByVal hConsoleHandle As IntPtr, <Out> ByRef lpMode As UInteger) As Boolean
End Function

<DllImport("kernel32.dll")>
Private Function SetConsoleMode(ByVal hConsoleHandle As IntPtr, ByVal dwMode As UInteger) As Boolean
End Function 

    Friend Function Go() As Boolean
    Dim consoleHandle As IntPtr = GetStdHandle(STD_INPUT_HANDLE)
    Dim consoleMode As UInteger

    If Not GetConsoleMode(consoleHandle, consoleMode) Then
        Return False
    End If

    consoleMode = consoleMode And Not ENABLE_QUICK_EDIT

    If Not SetConsoleMode(consoleHandle, consoleMode) Then
        Return False
    End If

    Return True
End Function

sub main()
go()
end sub
like image 1
asko Avatar answered Oct 30 '22 16:10

asko