[Mono-list] Console Help!

Jaroslaw Kowalski jaroslaw.kowalski@atm.com.pl
Tue, 6 May 2003 20:12:59 +0200


This is a multi-part message in MIME format.

------=_NextPart_000_0017_01C3140B.E4025620
Content-Type: text/plain;
	charset="ISO-8859-1"
Content-Transfer-Encoding: 7bit

I've made some investigation, and it seems that you cannot do it in managed
way.

Win32 Console can work in various modes (such as line-at-a-time, with-echo,
raw, etc.), and by default it runs in line-at-a-time mode. So you don't get
any input from it until the user presses enter.

I think _getch() internally changes the mode to "raw", reads the character
and switches back.

It turns out that if your program sets the console mode to "raw" at the very
beginning you can use "Console.Read" to behave as you expect it.

I wrote a simple P/Invoke-based (so it works only on Win32) class that you
may freely use in your code (ConsoleSetup.cs). It has functions to get and
set console mode. There's also a test program (Class1.cs) that demonstrates
how to use it.

I don't believe that it's any better than your code, but I hope you'll find
it useful.

Jarek

----- Original Message -----
From: "Thong (Tum) Nguyen" <tum@veridicus.com>
To: "'mono-ximian'" <mono-list@lists.ximian.com>
Sent: Tuesday, May 06, 2003 6:06 PM
Subject: RE: [Mono-list] Console Help!


> I'm don't think that would work.  Console.Read() won't return until the
> user presses enter.  I'm don't think there's a completely managed way to
> read the keyboard :-\.
>
> ^Tum
>
>
> > -----Original Message-----
> > From: mono-list-admin@lists.ximian.com [mailto:mono-list-
> > admin@lists.ximian.com] On Behalf Of Jaroslaw Kowalski
> > Sent: Wednesday, 7 May 2003 2:25 a.m.
> > To: eduardoo@antar.com.mx; mono-es; mono-ximian
> > Subject: Re: [Mono-list] Console Help!
> >
> > Have you tried Console.Read() ??
> >
> > It seems to have the same semantics as getch() (-1 = EOF, otherwise
> cast to
> > (char) and you have your input).
> >
> > Jarek
> >
> > P.S. I haven't tried it, but VS.NET docs say it should work.
> >
> > ----- Original Message -----
> > From: "Eduardo Osorio Armenta" <e_osorio@yahoo.com>
> > To: "mono-es" <mono-hispano@es.gnome.org>; "mono-ximian"
> > <mono-list@lists.ximian.com>
> > Sent: Tuesday, May 06, 2003 4:00 PM
> > Subject: [Mono-list] Console Help!
> >
> >
> > > Hi i hope someone help me!
> > >
> > > i DllImport the _getch() of "MSVC.dll"
> > >
> > > but i want to resemble the getch() function of 'C'
> > > but with pure C# code.
> > >
> > > thanks
> > >
> > >
> > >
> > >
> > > __________________________________
> > > Do you Yahoo!?
> > > The New Yahoo! Search - Faster. Easier. Bingo.
> > > http://search.yahoo.com
> > > _______________________________________________
> > > Mono-list maillist  -  Mono-list@lists.ximian.com
> > > http://lists.ximian.com/mailman/listinfo/mono-list
> > >
> >
> > _______________________________________________
> > Mono-list maillist  -  Mono-list@lists.ximian.com
> > http://lists.ximian.com/mailman/listinfo/mono-list
>
> _______________________________________________
> Mono-list maillist  -  Mono-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
>

------=_NextPart_000_0017_01C3140B.E4025620
Content-Type: text/plain;
	name="ConsoleSetup.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="ConsoleSetup.cs"

using System;
using System.Runtime.InteropServices;

namespace Test1
{
	[Flags]
	public enum ConsoleInputMode : int
	{
		Raw =3D 0,
		ProcessedInput =3D 1,
		LineInput =3D 2,
		EchoInput =3D 4,
		WindowInput =3D 8,
		MouseInput =3D 16,

		U1 =3D 32, // undocumented, but used
		U2 =3D 64, // undocumented, but used
		U3 =3D 128, // undocumented, but used
	}

	public class ConsoleSetup
	{
		public static void SetConsoleInputMode(ConsoleInputMode mode)
		{
			IntPtr handle =3D GetStdHandle(-10);

			SetConsoleMode(handle, mode);
		}

		public static ConsoleInputMode GetConsoleInputMode()
		{
			IntPtr handle =3D GetStdHandle(-10);
			ConsoleInputMode mode;

			GetConsoleMode(handle, out mode);
			return mode;
		}

		[DllImport("kernel32.dll")]
		private extern static void SetConsoleMode(IntPtr handle, =
ConsoleInputMode mode);

		[DllImport("kernel32.dll")]
		private extern static void GetConsoleMode(IntPtr handle, out =
ConsoleInputMode mode);

		[DllImport("kernel32.dll")]
		private extern static IntPtr GetStdHandle(int h);
	}
}
------=_NextPart_000_0017_01C3140B.E4025620
Content-Type: text/plain;
	name="Class1.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="Class1.cs"

using System;
using System.Runtime.InteropServices;

namespace Test1
{
	class Class1
	{
		[STAThread]
		static void Main(string[] args)
		{
			int ch;

			ConsoleInputMode oldMode =3D ConsoleSetup.GetConsoleInputMode();

			Console.WriteLine("Initial mode: {0}", oldMode.ToString());

			ConsoleSetup.SetConsoleInputMode(ConsoleInputMode.Raw);
			Console.WriteLine("Set mode: {0}", =
ConsoleSetup.GetConsoleInputMode().ToString());
			Console.WriteLine("press Q to quit\n");
	=09
			while ((ch =3D Console.In.Read()) !=3D -1)
			{
				if (Char.ToUpper((char)ch) =3D=3D 'Q')
					break;
				Console.WriteLine("ch: {0}", ch);
			}
			ConsoleSetup.SetConsoleInputMode(oldMode);
			Console.WriteLine("Restored mode: {0}", =
ConsoleSetup.GetConsoleInputMode().ToString());
		}
	}
}

------=_NextPart_000_0017_01C3140B.E4025620--