Non blocking keypress reading?

On Windows XP is there a way to test that a certain key has been pressed
without blocking?

Iâ??ve tried using curses but it blocks the current thread and any other
thread until a key is pressed.

I want to give the user 10 seconds so make a selection before a default
action is taken.

Here is the test code Iâ??ve got;

require 'curses'
include Curses
init_screen
noecho
trap(0) { echo }

t1 = Time.new
Thread.new do

	#example timer thread
	while(true) do
	x = Time.new - t1
	h = 3+3
	setpos(12,10)

  addstr("#{x}")

end
end

setpos(1,5)
addstr("Please select your location")
setpos(3,5)
addstr("  1 - Work")
setpos(4,5)
addstr("  2 - Home")
setpos(6,5)
addstr("Esc - Exit")
while (c = getch) != ?\e do
 # check what key is pressed and do stuff
end

Sard A. wrote:

On Windows XP is there a way to test that a certain key has been pressed
without blocking?

From my quick search, I didn’t find a way. Maybe this will help though?

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/4435

On 9/8/06, Sard A. [email protected] wrote:

Here is the test code I’ve got;

    end

search the archive for kbhit

On Friday 08 September 2006 20:42, Sard A. wrote:

On Windows XP is there a way to test that a certain key has been pressed
without blocking?

Iâ??ve tried using curses but it blocks the current thread and any other
thread until a key is pressed.

I want to give the user 10 seconds so make a selection before a default
action is taken.

require ‘timeout’
begin
 Timeout.timeout(10) do
  key = gets
 end
rescue Timeout::Error
 key = default
end

t1 = Time.new
end
while (c = getch) != ?\e do

check what key is pressed and do stuff

end


Weez International Limited

East Roppongi Bldg 5F, 509
3-16-35 Roppongi, Minato-ku Tokyo #106-0032
Tel: 81-(0)3-3505-3881 Fax: 81-(0)3-3505-3883
E-mail: [email protected]
Website: http://weez-int.com

Sard A. wrote in post #136581:

On Windows XP is there a way to test that a certain key has been pressed
without blocking?

Iâ??ve tried using curses but it blocks the current thread and any other
thread until a key is pressed.

I want to give the user 10 seconds so make a selection before a default
action is taken.

Here is the test code Iâ??ve got;

require ‘curses’
include Curses
init_screen
noecho
trap(0) { echo }

t1 = Time.new
Thread.new do

#example timer thread
while(true) do
x = Time.new - t1
h = 3+3
setpos(12,10)

addstr("#{x}")

end
end

setpos(1,5)
addstr(“Please select your location”)
setpos(3,5)
addstr(" 1 - Work")
setpos(4,5)
addstr(" 2 - Home")
setpos(6,5)
addstr(“Esc - Exit”)
while (c = getch) != ?\e do

check what key is pressed and do stuff

end

I know this is an old post, but still appears among Google’s top
results.

By combinig the various solutions I just read, I came up with a
cross-platform way to solve that problem.
Details here:

The relevant piece of code: a GetKey.getkey method
returning the ASCII code or nil if none was pressed.

Should work both on Windows and Unix.

module GetKey

Check if Win32API is accessible or not

@use_stty = begin
require ‘Win32API’
false
rescue LoadError
# Use Unix way
true
end

Return the ASCII code last key pressed, or nil if none

Return::

* Integer: ASCII code of the last key pressed, or nil if none

def self.getkey
if @use_stty
system(‘stty raw -echo’) # => Raw mode, no echo
char = (STDIN.read_nonblock(1).ord rescue nil)
system(‘stty -raw echo’) # => Reset terminal mode
return char
else
return Win32API.new(‘crtdll’, ‘_kbhit’, [ ], ‘I’).Call.zero? ? nil
: Win32API.new(‘crtdll’, ‘_getch’, [ ], ‘L’).Call
end
end

end

And here is a simple program to test it:

loop do
k = GetKey.getkey
puts “Key pressed: #{k.inspect}”
sleep 1
end

In the link provided above, I also show how to use the curses library,
but the result gets a bit whacky on Windows.

Hope this will help others.