How to detect keyboard input while application keeps running?

How to detect keyboard input while application keeps running?

I would like to do following: create a do while loop in the code in such a way that it ends if either a certain file is found (I can do this part) or the user hits any key on the keyboard. My question is how I can detect that the user pressed a key on the keyboard while the do while loop is running, checking the presence of the special file. It might be important to note that my application is a console one.

9 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Best Reply

Try looking at the function PEEKCHARQQ. Put this in your loop and it will tell you if a key has been pressed. When it returns .true. then you can retrieve it using say GETCHARQQ (or other). I think this is exactly what you need, and it only works for console applications.

Indeed, this is exactly what I was looking for; I just wasn't able to find this function in help. Thanks a lot!

I would like to ask an additional question: if multiple keys are pressed, all of them will be in the buffer and if I want to process them, I need to use GETCHARQQ until the buffer is empty. I don't know how to do this - how do I know that I should stop reading from the buffer? Continuing to read when the buffer is empty causes that the program stops and waits for user input. Put another way, how to I empty the buffer effectively?

Well my experience fails me here, but I would guess the following: Inside the main loop put a mini loop, which runs as long as PEEKCHARQQ is .true. Each time through the mini loop read a character from the buffer, and exit when PEEKCHARQQ returns .false. But you've probably already thought of this?

We had a similar problem a few years ago when we were still using CVF. Since we had no control over the black box optimizer we used, I created a thread that would perform the keytrapping via getcharqq in a subroutine. The side benefit is that since this optimizer wasn't written multithreaded we weren't wasting any resources that it would have used since we were using dual core machines at the time. I didn't bother with peek at that time since the only job this thread had was to receive an input such that we could issue a "signal" to the optimizer to shut down safely and write out results. This was done very dirtily through changing a common block variable that the developer told us was only used to check the number of iterations the optimizer is allowed to use.

I'm not going to say it was the prettiest thing, but it worked well enough.

dboggs, I was able to create a simple loop that keeps reading from the buffer using GETCHARQQ until PEEKCHARQQ returns .false. and this is sufficient for me. Fortunately, I don't need to know which key was pressed. Help for GETCHARQQ shows an example how to handle "standard" keys and those ones that don't have ASCII representation, but I was not able to make things work for e.g. direction keys for which the documentation is missing an example.

Here's how I do it:

!Capturing a extended keypress
character(1) :: $key
integer(2) :: ikey
$key = getcharqq ()
ikey = ichar ($key)
select case (ikey)
case (13)
! The keypress was (just an example)
case (Z'E0')
! An extended key, call again to get code
ikey = ichar (getcharqq ())
if (ikey == 75) then
!
elseif (ikey == 77) then
!
elseif (ikey == 82) then
!
elseif (ikey == 8) then
!
end select

You can determine the extended code for various special keys just by pressing them while running a test program in debug mode and "watch" the value of ikey. Or print ikey to the screen.

Thank you very much again. This is how I thought things should work, I just was not sure how to handle extended keys - case(Z'E0') did not seem right as GETCHARQQ returns character(1) and Z'E0' is hex. I should probably learn more about this...

Leave a Comment

Please sign in to add a comment. Not a member? Join today