Jarod_24 said:
I think i can use Console.Read() to get the integer value of the key
pressed. This can be compared with Keys.F1 for example.
Maybe... But the problem I see is that Console.Read and Console.ReadLine
both wait for the user to hit the enter key before they return. You will
have to call SetConsoleMode to disable line input (ENABLE_LINE_INPUT) and
echo input (ENABLE_ECHO_INPUT).
Hmmm.
What data types do i use for the argument to WriteConsole?
BOOL WriteConsole(HANDLE hConsoleOutput, const VOID* lpBuffer, DWORD
nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved);
hConsoleOutput is a IntPtr in VB (i got the handle using GetStdHandle)
lpBuffer is what?
nNumberOfCharsToWrite is a Int32 in VB
lpNumberOfCharsWritten is a adress to an Int32 variable that is getting
written to by the API?
lpReserved is supposed to be NULL, would "Nothing" work with this?
ref:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/writeconsole.asp
Here are my interop definitions... The are in C#, but should be fairly easy
to translate to VB.NET:
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace FireAnt.ConsoleLib
{
#region "Enumerations
[Flags()]
public enum ControlKeyState
{
RightAltPressed = 0x0001,
LeftAltPressed = 0x0002,
RightCtrlPressed = 0x0004,
LeftCtrlPressed = 0x0008,
ShiftPressed = 0x0010,
NumLockOn = 0x0020,
ScrollLockOn = 0x0040,
CapsLockOn = 0x0080,
EnhancedKey = 0x0100,
}
[Flags()]
public enum MouseButtonState
{
FromLeft1stButtonPressed = 0x0001,
RightMostButtonPressed = 0x0002,
FromLeft2ndButtonPressed = 0x0004,
FromLeft3rdButtonPressed = 0x0008,
FromLeft4thButtonPressed = 0x0010,
}
[Flags()]
public enum MouseEventFlags
{
MouseMoved = 0x0001,
DoubleClick = 0x0002,
MouseWheeled = 0x0004,
}
public enum InputEventType : short
{
KeyEvent = 0x0001,
MouseEvent = 0x0002,
WindowBufferSizeEvent = 0x004,
MenuEvent = 0x0008,
FocusEvent = 0x0010,
}
[Flags()]
public enum CharAttributes : short
{
ForegroundBlue = 0x0001,
ForegroundGreen = 0x0002,
ForegroundRed = 0x0004,
ForegroundIntensity = 0x0008,
BackgroundBlue = 0x0010,
BackgroundGreen = 0x0020,
BackgroundRed = 0x0040,
BackgroundIntensity = 0x0080,
}
[Flags()]
public enum SelectionFlags
{
NoSelection = 0x0000,
SelectionInProgress = 0x0001,
SelectionNotEmpty = 0x0002,
MouseSelection = 0x0004,
MouseDown = 0x0008,
}
public enum ControlEvents
{
CtrlC = 0,
CtrlBreak = 1,
Close = 2,
LogOff = 5,
Shutdown = 6,
}
[Flags()]
public enum InputModeFlags
{
EnableProcessedInput = 0x0001,
EnableLineInput = 0x0002,
EnableEchoInput = 0x0004,
EnableWindowInput = 0x0008,
EnableMouseInput = 0x0010,
}
[Flags()]
public enum OutputModeFlags
{
EnableProcessedOutput = 0x0001,
EnableWrapAtEolOutput = 0x0002,
}
public enum StandardHandle
{
Input = -10,
Output = -11,
Error = -12,
}
#endregion
#region "Structures"
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
}
[StructLayout(LayoutKind.Sequential)]
public struct SMALL_RECT
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[StructLayout(LayoutKind.Explicit)]
public struct CHAR
{
[FieldOffset(0)] public byte AsciiChar;
[FieldOffset(0)] public short UnicodeChar;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEY_EVENT_RECORD
{
public bool bKeyDown;
public short wRepeatCount;
public short wVirtualKeyCode;
public short wVirtualScanCode;
public CHAR uChar;
public ControlKeyState dwControlKeyState;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSE_EVENT_RECORD
{
public COORD dwMousePosition;
public MouseButtonState dwButtonState;
public ControlKeyState dwControlKeyState;
public MouseEventFlags dwEventFlags;
}
[StructLayout(LayoutKind.Sequential)]
public struct WINDOW_BUFFER_SIZE_RECORD
{
public COORD dwSize;
}
[StructLayout(LayoutKind.Sequential)]
public struct MENU_EVENT_RECORD
{
public uint dwCommandId;
}
[StructLayout(LayoutKind.Sequential)]
public struct FOCUS_EVENT_RECORD
{
public bool bSetFocus;
}
[StructLayout(LayoutKind.Explicit)]
public struct EVENT_UNION
{
[FieldOffset(0)] public KEY_EVENT_RECORD KeyEvent;
[FieldOffset(0)] public MOUSE_EVENT_RECORD MouseEvent;
[FieldOffset(0)] public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
[FieldOffset(0)] public MENU_EVENT_RECORD MenuEvent;
[FieldOffset(0)] public FOCUS_EVENT_RECORD FocusEvent;
}
[StructLayout(LayoutKind.Sequential)]
public struct INPUT_RECORD
{
public InputEventType EventType;
public EVENT_UNION Event;
}
[StructLayout(LayoutKind.Sequential)]
public struct CHAR_INFO
{
public CHAR Char;
public CharAttributes Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
public COORD dwSize;
public COORD dwCursorPosition;
public CharAttributes wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
}
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_CURSOR_INFO
{
int dwSize;
bool bVisible;
}
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_FONT_INFO
{
int nFont;
COORD dwFontSize;
}
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SELECTION_INFO
{
public SelectionFlags dwFlags;
public COORD dwSelectionAnchor;
public SMALL_RECT srSelection;
}
#endregion
#region "Delegates"
public delegate bool HandlerRoutineDelegate (ControlEvents dwCtrlType);
#endregion
/// <summary>
/// Summary description for ConsoleAPI.
/// </summary>
public class ConsoleApi
{
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool PeekConsoleInput (
IntPtr hConsoleInput,
[Out] INPUT_RECORD[] lpBuffer,
int nLength,
out int lpNumberOfEventsRead);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool ReadConsoleInput (
IntPtr hConsoleInput,
[Out] INPUT_RECORD[] lpBuffer,
int nLength,
out int lpNumberOfEventsRead);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool WriteConsoleInput (
IntPtr hConsoleInput,
[Out] INPUT_RECORD[] lpBuffer,
int nLength,
out int lpNumberOfEventsWritten);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool ReadConsoleOutput (
IntPtr hConsoleOutput,
out CHAR_INFO[] lpBuffer,
COORD dwBufferSize,
COORD dwBufferCord,
ref SMALL_RECT lpReadRegion);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool WriteConsoleOutput (
IntPtr hConsoleOutput,
CHAR_INFO[] lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
ref SMALL_RECT lpWriteRegion);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool ReadConsoleOutputCharacter (
IntPtr hConsoleOutput,
StringBuilder lpCharacter,
int nLength,
COORD dwReadCoord,
out int lpNumberOfCharsRead);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool ReadConsoleOutputAttribute (
IntPtr hConsoleOutput,
CharAttributes[] lpAttribute,
int nLength,
COORD dwReadCoord,
out int lpNumberOfAttrsRead);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool WriteConsoleOutputCharacter (
IntPtr hConsoleOutput,
string lpCharacter,
int nLength,
COORD dwWriteCoord,
out int lpNumberOfCharsWritten);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool WriteConsoleOutputAttribute (
IntPtr hConsoleOutput,
CharAttributes[] lpAttribute,
int nLength,
COORD dwWriteCoord,
out int lpNumberOfAttrsWritten);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool FillConsoleOutputCharacter (
IntPtr hConsoleOupt,
CHAR cCharacter,
int nLength,
COORD dwWriteCoord,
out int lpNumberOfCharsWritten);
[DllImport("kernel32", SetLastError=true)]
public static extern bool FillConsoleOutputAttribute (
IntPtr hConsoleOutput,
CharAttributes wAttribute,
int nLength,
COORD dwWriteCoord,
out int lpNumberOfAttrsWritten);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetConsoleMode (
IntPtr hConsoleInput,
out InputModeFlags lpMode);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetConsoleMode (
IntPtr hConsoleOutput,
out OutputModeFlags lpMode);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetNumberOfConsoleInputEvents (
IntPtr hConsoleInput,
out int lpNumberOfEvents);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetConsoleScreenBufferInfo (
IntPtr hConsoleInput,
out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
[DllImport("kernel32", SetLastError=true)]
public static extern COORD GetLargestConsoleWindowSize (IntPtr
hConsoleOutput);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetConsoleCursorInfo (
IntPtr hConsoleOutput,
out CONSOLE_CURSOR_INFO lpConsoleCursorInfo);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetCurrentConsoleFont (
IntPtr hConsoleOutput,
bool bMaximumWindow,
out CONSOLE_FONT_INFO lpConsoleCurrentFont);
[DllImport("kernel32", SetLastError=true)]
public static extern COORD GetConsoleFontSize (
IntPtr hConsoleOutput,
int nFont);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetConsoleSelectionInfo (out
CONSOLE_SELECTION_INFO lpConsoleSelectionInfo);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GetNumberOfConsoleMouseButtons (out int
lpNumberOfMouseButtons);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleMode (
IntPtr hConsoleInput,
InputModeFlags dwMode);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleMode (
IntPtr hConsoleOutput,
OutputModeFlags dwMode);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleActiveScreenBuffer (IntPtr
hConsoleOutput);
[DllImport("kernel32", SetLastError=true)]
public static extern bool FlushConsoleInputBuffer (IntPtr hConsoleInput);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleScreenBufferSize (
IntPtr hConsoleOutput,
COORD dwSize);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleCursorPosition (
IntPtr hConsoleOutput,
COORD dwCursorPostion);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleCursorInfo (
IntPtr hConsoleOutput,
ref CONSOLE_CURSOR_INFO lpConsoleCursorInfo);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool ScrollConsoleScreenBuffer (
IntPtr hConsoleOutput,
ref SMALL_RECT lpScrollRectangle,
ref SMALL_RECT lpClipRectangle,
COORD dwDestinationOrigin,
ref CHAR_INFO lpFill);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleWindowInfo (
IntPtr hConsoleOutput,
bool bAbsolute,
ref SMALL_RECT lpConsoleWindow);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleTextAttribute (
IntPtr hConsoleOutput,
CharAttributes wAttributes);
[DllImport("kernel32", SetLastError=true)]
public static extern bool SetConsoleCtrlHandler (
HandlerRoutineDelegate HandlerRoutine,
bool Add);
[DllImport("kernel32", SetLastError=true)]
public static extern bool GenerateConsoleCtrlEvent (
ControlEvents dwCtrlEvent,
int dwProcessGroupId);
[DllImport("kernel32", SetLastError=true)]
public static extern bool AllocConsole();
[DllImport("kernel32", SetLastError=true)]
public static extern bool FreeConsole();
[DllImport("kernel32", SetLastError=true)]
public static extern bool AttachConsole (int dwProcessId);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int GetConsoleTitle (
StringBuilder lpConsoleTitle,
int nSize);
[DllImport("kernel32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool SetConsoleTitle (
string lpConsoleTitle);
[DllImport("kernel32", SetLastError=true)]
public static extern IntPtr GetStdHandle (StandardHandle nStdHandle);
private ConsoleApi() {}
}
}
and here is a little class that uses some of them (it is a converted and
modified MSDN sample)...
using System;
using System.Threading;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using FireAnt.ConsoleLib;
namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
//Console.WriteLine(Marshal.SizeOf(typeof(INPUT_RECORD)));
IntPtr hStdin;
int cNumRead, i;
InputModeFlags fdwMode, fdwSaveOldMode;
INPUT_RECORD[] irInBuf = new INPUT_RECORD[128];
// Get the standard input handle.
hStdin = ConsoleApi.GetStdHandle(StandardHandle.Input);
if (hStdin == INVALID_HANDLE_VALUE)
MyErrorExit("GetStdHandle");
// Save the current input mode, to be restored on exit.
if (! ConsoleApi.GetConsoleMode(hStdin, out fdwSaveOldMode) )
MyErrorExit("GetConsoleMode");
// Enable the window and mouse input events.
fdwMode = InputModeFlags.EnableWindowInput |
InputModeFlags.EnableMouseInput;
if (! ConsoleApi.SetConsoleMode(hStdin, fdwMode) )
MyErrorExit("SetConsoleMode");
IntPtr hStdout = ConsoleApi.GetStdHandle(StandardHandle.Output);
COORD size = ConsoleApi.GetLargestConsoleWindowSize(hStdout);
ConsoleApi.SetConsoleScreenBufferSize(hStdout, size);
Console.WriteLine("size.X = {0}, size.Y = {1}", size.X, size.Y);
// Loop to read and handle the input events.
while (true)
{
// Wait for the events.
if (! ConsoleApi.ReadConsoleInput(
hStdin, // input buffer handle
irInBuf, // buffer to read into
128, // size of read buffer
out cNumRead) ) // number of records read
MyErrorExit("ReadConsoleInput");
// Dispatch the events to the appropriate handler.
for (i = 0; i < cNumRead; i++)
{
switch(irInBuf
.EventType)
{
case InputEventType.KeyEvent: // keyboard input
KeyEventProc(ref irInBuf.Event.KeyEvent);
break;
case InputEventType.MouseEvent: // mouse input
MouseEventProc(ref irInBuf.Event.MouseEvent);
break;
case InputEventType.WindowBufferSizeEvent: // scrn buf. resizing
ResizeEventProc(ref irInBuf.Event.WindowBufferSizeEvent);
break;
case InputEventType.FocusEvent: // disregard focus events
case InputEventType.MenuEvent: // disregard menu events
break;
default:
MyErrorExit("unknown event type");
break;
}
}
}
}
private static void MouseEventProc(ref MOUSE_EVENT_RECORD MouseEvent)
{
Console.WriteLine("Button State = {0}", MouseEvent.dwButtonState);
}
private static void ResizeEventProc(ref WINDOW_BUFFER_SIZE_RECORD
WindowEvent)
{
Console.WriteLine("Resize");
}
private static void KeyEventProc(ref KEY_EVENT_RECORD KeyEvent)
{
Console.WriteLine(KeyEvent.wVirtualKeyCode);
}
private static void MyErrorExit(string msg)
{
Console.WriteLine(msg);
System.Environment.Exit(1);
}
}
}
This doesn't test all of them, and I haven't tested all of them yet - but
your welcome to 'em...
HTH
Tom Shelton [MVP]
PS: Man OE sucks... Now I realize why I started using slrn...