(view source code of mause.cs as plain text)
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using static ConsoleLib.NativeMethods;
namespace RobvanderWoude
{
class Mause
{
static string progver = "1.06";
const string defaultprompt = "Press any key or mouse button or wheel to continue . . .";
const int defaulttimeout = 0;
static IntPtr inHandle = IntPtr.Zero;
static uint initialmode = 0;
static string prompt = defaultprompt;
static int timeout = defaulttimeout;
static bool flushkeyboardbuffer = true;
private static System.Timers.Timer timer;
static void Main( string[] args )
{
foreach ( string arg in args )
{
if ( arg == "/?" )
{
ShowHelp( );
}
if ( arg.Length > 3 && arg.ToUpper( ).Substring( 0, 3 ) == "/T:" )
{
if ( timeout != defaulttimeout )
{
ShowHelp( "Duplicate timeout switch /T" );
}
try
{
timeout = Convert.ToInt32( arg.Substring( 3 ) );
if ( timeout < 1 || timeout > 3600 )
{
ShowHelp( "Specified timeout out of 1..3600 seconds range" );
}
}
catch
{
ShowHelp( "Invalid timeout \"{0}\"", arg );
}
}
else if ( arg.ToUpper( ) == "/N" )
{
if ( !flushkeyboardbuffer )
{
ShowHelp( "Duplicate timeout switch /N" );
}
flushkeyboardbuffer = false;
}
else
{
if ( prompt != defaultprompt )
{
ShowHelp( "Too many command line arguments" );
}
prompt = arg;
}
}
// Flush keyboard buffer unless /N switch is used
if ( flushkeyboardbuffer )
{
FlushKeyboardBuffer( );
}
// Temporarily enable mouse input and disable Quick-Edit mode
inHandle = GetStdHandle( STD_INPUT_HANDLE );
GetConsoleMode( inHandle, ref initialmode );
uint tempmode = initialmode | ENABLE_EXTENDED_FLAGS; // enable
tempmode |= ENABLE_MOUSE_INPUT; // enable
tempmode &= ~ENABLE_QUICK_EDIT_MODE; // disable
tempmode &= ~ENABLE_LINE_INPUT; // disable
tempmode &= ~ENABLE_ECHO_INPUT; // disable
tempmode &= ~ENABLE_WINDOW_INPUT; // disable
SetConsoleMode( inHandle, tempmode );
// Set event listeners for keyboard and mouse input
ConsoleLib.ConsoleListener.MouseEvent += ConsoleListener_MouseEvent;
ConsoleLib.ConsoleListener.KeyEvent += ConsoleListener_KeyEvent;
ConsoleLib.ConsoleListener.Start( );
// Start timeout timer if requested
if ( timeout > 0 )
{
timer = new System.Timers.Timer( );
timer.Interval = 1000 * timeout;
timer.Elapsed += Timer_Elapsed;
timer.Start( );
}
// Show the prompt
if ( !string.IsNullOrWhiteSpace( prompt ) )
{
Console.Write( prompt );
}
// Temporarily hide the cursor
Console.CursorVisible = false;
}
static void FlushKeyboardBuffer( )
{
// Code to flush keyboard buffer by gandjustas
// https://stackoverflow.com/a/3769828
bool hidekey = true;
while ( Console.KeyAvailable )
{
Console.ReadKey( hidekey );
}
}
static void Quit( int rc )
{
// If a prompt was shown, append a newline
if ( !string.IsNullOrWhiteSpace( prompt ) )
{
Console.WriteLine( );
}
// Stop the timeout timer, if active
if ( timeout > 0 )
{
timer.Stop( );
timer.Dispose( );
}
// Restore the cursor
Console.CursorVisible = true;
// Restore the console's initial Quick-Edit mode
SetConsoleMode( inHandle, initialmode );
// Exit with appropriate return code
Environment.Exit( rc );
}
private static void ConsoleListener_KeyEvent( KEY_EVENT_RECORD r )
{
// Keyboard input
Quit( 1 );
}
private static void ConsoleListener_MouseEvent( MOUSE_EVENT_RECORD r )
{
if ( r.dwEventFlags != 1 ) // ignore mouse movement events
{
// Mouse input
Quit( 2 );
}
}
private static void Timer_Elapsed( object sender, System.Timers.ElapsedEventArgs e )
{
// Timeout elapsed
Quit( 3 );
}
#region Error handling
static void ShowHelp( params string[] errmsg )
{
#region Error Message
if ( errmsg.Length > 0 )
{
List<string> errargs = new List<string>( errmsg );
errargs.RemoveAt( 0 );
Console.Error.WriteLine( );
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.Write( "ERROR:\t" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
Console.ResetColor( );
}
#endregion Error Message
#region Help Text
/*
Mause.exe, Version 1.06
Mouse enabled pAUSE command
Usage: Mause.exe [ prompt ] [ /T:seconds ] [ /N ]
Where: prompt is the prompt to be displayed (default: "Press any key
or mouse button or wheel to continue . . ."; use "" to
show no prompt)
/N do Not flush the keyboard buffer
(default: flush keyboard buffer when program is started)
/T:seconds timeout in seconds (1..3600; default: wait forever)
Notes: Return code 1 for key, 2 for mouse, 3 for timeout or -1 for errors.
While Mause is running, the console's Quick-Edit mode will be
temporarily disabled; before exiting, the console's initial
Quick-Edit state will be restored.
Credits: ConsoleListener class by SWdV on StackOverflow.com
https://stackoverflow.com/a/29971246
Code to flush keyboard buffer by gandjustas on StackOverflow.com
https://stackoverflow.com/a/3769828
Written by Rob van der Woude
https://www.robvanderwoude.com
*/
#endregion Help Text
#region Display Help Text
Console.Error.WriteLine( );
Console.Error.WriteLine( "Mause.exe, Version {0}", progver );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "M" );
Console.ResetColor( );
Console.Error.Write( "ouse enabled p" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "AUSE" );
Console.ResetColor( );
Console.Error.WriteLine( " command" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "Mause.exe [ prompt ] [ /T:timeout ] [ /N ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "prompt" );
Console.ResetColor( );
Console.Error.WriteLine( " is the prompt to be displayed (default: \"Press any key" );
Console.Error.WriteLine( " or mouse button or wheel to continue . . .\"; use \"\" to" );
Console.Error.WriteLine( " show no prompt)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /N" );
Console.ResetColor( );
Console.Error.Write( " do " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "N" );
Console.ResetColor( );
Console.Error.WriteLine( "ot flush the keyboard buffer" );
Console.Error.WriteLine( " (default: flush keyboard buffer when program is started)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /T:seconds" );
Console.ResetColor( );
Console.Error.WriteLine( " timeout in seconds (1..3600; default: wait forever)" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Notes: Return code 1 for key, 2 for mouse, 3 for timeout or -1 for errors." );
Console.Error.WriteLine( " While Mause is running, the console's Quick-Edit mode will be" );
Console.Error.WriteLine( " temporarily disabled; before exiting, the console's initial" );
Console.Error.WriteLine( " Quick-Edit state will be restored." );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Credits: ConsoleListener class by SWdV on StackOverflow.com" );
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Error.WriteLine( " https://stackoverflow.com/a/29971246" );
Console.ResetColor( );
Console.Error.WriteLine( " Code to flush keyboard buffer by gandjustas on StackOverflow.com" );
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Error.WriteLine( " https://stackoverflow.com/a/3769828" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "https://www.robvanderwoude.com" );
#endregion Display Help Text
Environment.Exit( -1 );
}
#endregion Error handling
}
}
// ConsoleListener class by SWdV on StackOverflow.com
// https://stackoverflow.com/a/29971246
namespace ConsoleLib
{
public static class ConsoleListener
{
public static event ConsoleMouseEvent MouseEvent;
public static event ConsoleKeyEvent KeyEvent;
public static event ConsoleWindowBufferSizeEvent WindowBufferSizeEvent;
private static bool Run = false;
public static void Start( )
{
if ( !Run )
{
Run = true;
IntPtr handleIn = GetStdHandle( STD_INPUT_HANDLE );
new Thread( ( ) =>
{
while ( true )
{
uint numRead = 0;
INPUT_RECORD[] record = new INPUT_RECORD[1];
record[0] = new INPUT_RECORD( );
ReadConsoleInput( handleIn, record, 1, ref numRead );
if ( Run )
switch ( record[0].EventType )
{
case INPUT_RECORD.MOUSE_EVENT:
MouseEvent?.Invoke( record[0].MouseEvent );
break;
case INPUT_RECORD.KEY_EVENT:
KeyEvent?.Invoke( record[0].KeyEvent );
break;
case INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT:
WindowBufferSizeEvent?.Invoke( record[0].WindowBufferSizeEvent );
break;
}
else
{
uint numWritten = 0;
WriteConsoleInput( handleIn, record, 1, ref numWritten );
return;
}
}
} ).Start( );
}
}
public static void Stop( ) => Run = false;
public delegate void ConsoleMouseEvent( MOUSE_EVENT_RECORD r );
public delegate void ConsoleKeyEvent( KEY_EVENT_RECORD r );
public delegate void ConsoleWindowBufferSizeEvent( WINDOW_BUFFER_SIZE_RECORD r );
}
public static class NativeMethods
{
public struct COORD
{
public short X;
public short Y;
public COORD( short x, short y )
{
X = x;
Y = y;
}
}
[StructLayout( LayoutKind.Explicit )]
public struct INPUT_RECORD
{
public const ushort KEY_EVENT = 0x0001,
MOUSE_EVENT = 0x0002,
WINDOW_BUFFER_SIZE_EVENT = 0x0004; //more
[FieldOffset( 0 )]
public ushort EventType;
[FieldOffset( 4 )]
public KEY_EVENT_RECORD KeyEvent;
[FieldOffset( 4 )]
public MOUSE_EVENT_RECORD MouseEvent;
[FieldOffset( 4 )]
public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
/*
and:
MENU_EVENT_RECORD MenuEvent;
FOCUS_EVENT_RECORD FocusEvent;
*/
}
public struct MOUSE_EVENT_RECORD
{
public COORD dwMousePosition;
public const uint FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001,
FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004,
FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008,
FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010,
RIGHTMOST_BUTTON_PRESSED = 0x0002;
public uint dwButtonState;
public const int CAPSLOCK_ON = 0x0080,
ENHANCED_KEY = 0x0100,
LEFT_ALT_PRESSED = 0x0002,
LEFT_CTRL_PRESSED = 0x0008,
NUMLOCK_ON = 0x0020,
RIGHT_ALT_PRESSED = 0x0001,
RIGHT_CTRL_PRESSED = 0x0004,
SCROLLLOCK_ON = 0x0040,
SHIFT_PRESSED = 0x0010;
public uint dwControlKeyState;
public const int DOUBLE_CLICK = 0x0002,
MOUSE_HWHEELED = 0x0008,
MOUSE_MOVED = 0x0001,
MOUSE_WHEELED = 0x0004;
public uint dwEventFlags;
}
[StructLayout( LayoutKind.Explicit, CharSet = CharSet.Unicode )]
public struct KEY_EVENT_RECORD
{
[FieldOffset( 0 )]
public bool bKeyDown;
[FieldOffset( 4 )]
public ushort wRepeatCount;
[FieldOffset( 6 )]
public ushort wVirtualKeyCode;
[FieldOffset( 8 )]
public ushort wVirtualScanCode;
[FieldOffset( 10 )]
public char UnicodeChar;
[FieldOffset( 10 )]
public byte AsciiChar;
public const int CAPSLOCK_ON = 0x0080,
ENHANCED_KEY = 0x0100,
LEFT_ALT_PRESSED = 0x0002,
LEFT_CTRL_PRESSED = 0x0008,
NUMLOCK_ON = 0x0020,
RIGHT_ALT_PRESSED = 0x0001,
RIGHT_CTRL_PRESSED = 0x0004,
SCROLLLOCK_ON = 0x0040,
SHIFT_PRESSED = 0x0010;
[FieldOffset( 12 )]
public uint dwControlKeyState;
}
public struct WINDOW_BUFFER_SIZE_RECORD
{
public COORD dwSize;
}
public const uint STD_INPUT_HANDLE = unchecked((uint) -10),
STD_OUTPUT_HANDLE = unchecked((uint) -11),
STD_ERROR_HANDLE = unchecked((uint) -12);
[DllImport( "kernel32.dll" )]
public static extern IntPtr GetStdHandle( uint nStdHandle );
public const uint ENABLE_MOUSE_INPUT = 0x0010,
ENABLE_QUICK_EDIT_MODE = 0x0040,
ENABLE_EXTENDED_FLAGS = 0x0080,
ENABLE_ECHO_INPUT = 0x0004,
ENABLE_WINDOW_INPUT = 0x0008,
ENABLE_INSERT_MODE = 0x0020,
ENABLE_LINE_INPUT = 0x0002,
ENABLE_PROCESSED_INPUT = 0x0001,
ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200;
[DllImportAttribute( "kernel32.dll" )]
public static extern bool GetConsoleMode( IntPtr hConsoleInput, ref uint lpMode );
[DllImportAttribute( "kernel32.dll" )]
public static extern bool SetConsoleMode( IntPtr hConsoleInput, uint dwMode );
[DllImportAttribute( "kernel32.dll", CharSet = CharSet.Unicode )]
public static extern bool ReadConsoleInput( IntPtr hConsoleInput, [Out] INPUT_RECORD[] lpBuffer, uint nLength, ref uint lpNumberOfEventsRead );
[DllImportAttribute( "kernel32.dll", CharSet = CharSet.Unicode )]
public static extern bool WriteConsoleInput( IntPtr hConsoleInput, INPUT_RECORD[] lpBuffer, uint nLength, ref uint lpNumberOfEventsWritten );
}
}
page last modified: 2024-04-16; loaded in 0.0102 seconds