Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Blocking keyboard handling in C#

120 views
Skip to first unread message

silmar...@o2.pl

unread,
Apr 2, 2015, 9:54:52 AM4/2/15
to
Hello all,

so, MS decided to kick me in the butt and drop fullscreen ability of System.Console in Windows 7. That leaves me with a task to implement a fullscreen console from scratch. Seems easy enough - fullscreen form, black backbground, no borders, maximized. The only thing to sort out is blocking keyboard input.

I have an IConsole interface which is a thin wrapper over System.Console:

public interface IConsole {
...
/// <summary>
/// Reads a character from input
/// </summary>
/// <returns>The character read from input</returns>
char ReadKey();
...
}

and the current implementation:

public class SystemConsole: IConsole {
...
public char ReadKey() {
return Console.ReadKey(true).KeyChar;
}
...
}

So basically I need to write a different implementation of IConsole using Windows.Forms. But ReadKey() is a problem. I even wrote a quick-and-dirty proof-of-concept in Java (Swing) to verify my idea:

public class GraphicalConsole implements IConsole {
...
public char ReadKey(){
semaphore.acquire();
return key;
}

public void keyPressed(KeyEvent e) {
key = e.getKeyChar();
semaphore.release();
}
...
}
Works like a charm, as Swing has a separate thread for events (apparently called "AWT-EventQueue-0").

However, the same concept doesn't work in .NET:

public partial class Form1 : Form, IConsole{
...
public char ReadKey() {
s.WaitOne();
return key;
}

private void form_KeyPress(object sender, KeyPressEventArgs e) {
key = e.KeyChar;
s.Release();
}
}

(the code is highly abstracted out for readability, but you get the idea). So the problem seems to be, the events are handled in the main thread, which is hung on the semaphore, and never gets the chance to run form_KeyPress. Classic deadlock.

So here's the question:
- is there any way I can run the event loop in a separate thread?
- is there any other way I can get a fullscreen console in .NET (like a third-party library)?

Thanks in advance.

graspee

unread,
Apr 2, 2015, 7:44:07 PM4/2/15
to
Have you looked at BearLib Terminal? I'm not sure if that lib supports full screen though.

Travis Clark

unread,
Apr 14, 2015, 12:21:31 PM4/14/15
to
Try RLNET, it is available on NuGet

silmar...@o2.pl

unread,
Apr 21, 2015, 7:28:37 AM4/21/15
to
From what I saw, RLNET only supports event-based keyboard input, not blocking input. Or am I mistaken?

Travis Clark

unread,
May 2, 2015, 3:37:07 AM5/2/15
to
It's not true blocking because RLNET expects you to not block the update loop for input. However the RLKeyboard class listens on the event for you and stores away key presses to be checked later.

void rootConsole_Update(object sender, UpdateEventArgs e)
{
RLKeyPress keyPress = rootConsole.Keyboard.GetKeyPress();
if (keyPress != null)
{
//Handle Input

//Update Logic
}
}

silmar...@o2.pl

unread,
Jun 3, 2015, 9:00:37 AM6/3/15
to
Yep, that's exactly what constitutes a non-blocking input, and is also exactly what I don't want. This is how .NET works by default anyway, so I guess RLNET just follows this mode of operation.

0 new messages