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.