Console input problem

J

JM

Hi,

I need a function for a character based program (console) that works exactly
like the INKEY$() function in (old) QBasic: Read only 1 keystroke and then
move on. Console.Read; Console.ReadLine;.... all read input until the user
hits <Enter>.
For example, if you get the question "Do you wish to continue? (Y/N)", from
the moment the user presses his "Y" key, I want to continue.
I haven't found a function in the console class that will do this.

Can someone please help me to acompish this? It MUST be possible, no? Maybe
through winAPI?


Thanks in advance,

JFM


PS: Please do not reply by e-mail as the e-mailaddress I entered is fake,
I'm already getting way too much spam!
 
C

Chris Morse

Hi,

I need a function for a character based program (console) that works exactly
like the INKEY$() function in (old) QBasic: Read only 1 keystroke and then
move on. Console.Read; Console.ReadLine;.... all read input until the user
hits <Enter>.
For example, if you get the question "Do you wish to continue? (Y/N)", from
the moment the user presses his "Y" key, I want to continue.
I haven't found a function in the console class that will do this.

Can someone please help me to acompish this? It MUST be possible, no? Maybe
through winAPI?


Thanks in advance,

JFM


PS: Please do not reply by e-mail as the e-mailaddress I entered is fake,
I'm already getting way too much spam!


You can't do it in straight VB.NET. All the console functions wait
until ENTER has been pressed before stuff get's pushed through the
streams.

There's a workaround, if you have Visual C++ .NET

Build the following VC++.NET Code and compile it:

#include "stdafx.h"
#include <conio.h>
namespace Helper
{
public __gc class InKey
{
public:
static System::Int32 ReadKeypress()
{
while ( ! _kbhit() ) {}
return _getch();
}
};
}

Then, reference the .NET DLL in your Console app and call it like
this:

Dim nChar As Integer = Helper.InKey.ReadKeypress()


Hope that helps!
// CHRIS
 
C

Chris Morse

static System::Int32 ReadKeypress()
{
while ( ! _kbhit() ) {}
return _getch();
}

Actually, in the while() loop I would insert a sleep() call for, say,
50 milliseconds.. just to keep the cpu usage down..

// CHRIS
 
O

One Handed Man [ OHM# ]

Whidbey promises to make some enhancements in this area, Im not sure if this
is one of them, but there should be full console support like there is in
C++. Rubbish really, you cant even do a clear screen natively.

OHM


Chris said:
You can't do it in straight VB.NET. All the console functions wait
until ENTER has been pressed before stuff get's pushed through the
streams.

There's a workaround, if you have Visual C++ .NET

Build the following VC++.NET Code and compile it:

#include "stdafx.h"
#include <conio.h>
namespace Helper
{
public __gc class InKey
{
public:
static System::Int32 ReadKeypress()
{
while ( ! _kbhit() ) {}
return _getch();
}
};
}

Then, reference the .NET DLL in your Console app and call it like
this:

Dim nChar As Integer = Helper.InKey.ReadKeypress()


Hope that helps!
// CHRIS

Regards - OHM# OneHandedMan{at}BTInternet{dot}com
 
J

JM

Hi, thanks a lot for this code, I think I'll get there
with this.
But I only have a basic knowledge of C++ (have learned it
years ago but almost never used it), so I copied your
code into a new C++ .NET Class library, but when I try to
build the project, I get some errors and I don't know
what to do with it...

This is the build output:

------ Build started: Project: ConsoleHelpers,
Configuration: Debug Win32 ------

Compiling...
ConsoleHelpers.cpp
Linking...
ConsoleHelpers.obj : error LNK2001: unresolved external
symbol "int __cdecl _getch(void)" (?_getch@@$$J0YAHXZ)
ConsoleHelpers.obj : error LNK2001: unresolved external
symbol "int __cdecl _kbhit(void)" (?_kbhit@@$$J0YAHXZ)
D:\(...)\Visual Studio Projects\ConsoleApplication4
\Debug\ConsoleHelpers.dll : fatal error LNK1120: 2
unresolved externals

ConsoleHelpers - 3 error(s), 0 warning(s)


---------------------- Done ----------------------

Build: 0 succeeded, 1 failed, 0 skipped




BTW: my news server seems to be down so it might take a
little longer before I can react to any replies...
 
S

Stephen Martin

The problem is that the console is set, by default, to line input mode so
there is nothing in the input buffer until a line has been entered. The
solution is not to use a busy wait but to change the console input mode. The
following is a rough example:

Module Whatever

<System.Runtime.InteropServices.DllImport("kernel32")> _
Function SetConsoleMode(ByVal hConsoleHandle As IntPtr, _
ByVal dwMode As Integer) As Integer
End Function

<System.Runtime.InteropServices.DllImport("kernel32")> _
Function GetConsoleMode(ByVal hConsoleHandle As IntPtr, _
ByRef dwMode As Integer) As Integer
End Function

Private Const ENABLE_LINE_INPUT As Integer = 2
Private Const ENABLE_ECHO_INPUT As Integer = 4

Private Const CONIN As Integer = 3

Sub Main()

Dim hStdIn As New IntPtr(CONIN)
Dim nMode As Integer
Dim cInput As Char

GetConsoleMode(hStdIn, nMode)
nMode = (nMode And Not ENABLE_LINE_INPUT) _
And Not ENABLE_ECHO_INPUT

If SetConsoleMode(hStdIn, nMode) = 0 Then
'Error do something
Exit Sub
End If

Console.Write("Do you want to continue?(Y/N)")

Do While True
cInput = Char.ToUpper(Convert.ToChar(Console.Read()))
If cInput = "N"c Then
Exit Do
ElseIf cInput = "Y"c Then
Console.Write(cInput & vbCrLf)
Console.Write("Do you want to continue?(Y/N)")
End If
Loop

End Sub

End Module
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top