Trapping left/right or up/down arrow key keystrokes?


#1

Is it possible to use the arrow keys as hotkeys in a form event procedure?

I’m hoping to trap left/right or up/down arrow key keystrokes in a form to run some code to update the contents of a fileglobal variable. I used the Pan6 “.keydown” procedure a lot - and am aware it is gone in PanX, so I’m trying to figure out a possible PanX option…

The code below doesn’t trap the left arrow keystroke, but works fine with most other keys. I’m guessing the “LeftArrow” part is not the correct way to designate it. I tried a few variations with the SpecialKey( function, but no success there either. I’m guessing that function isn’t meant for this type of use?

 if info("formevent") match "Front"
     definehotkeys "window","LeftArrow",{Message "The Left Arrow key was pressed."}
 endif

How could this above code be revised to trap the arrow keys on a keyboard?


#2

asc(info(“keyboard”)) will return numbers for those keys, and any others.


#3

Yes - it returns 63234 for the left arrow key.

What I can’t figure out is how to use that number to define a left arrow key hotkey in a form event procedure as shown above…


#4

I think you could use it in a loop, but it will only be trapped while the loop is running.


#5

Actually what you need is info("keycode") to determine the correct numeric value. Unfortunately, this function doesn’t exist in Panorama X. I think I may implemented it tonight or tomorrow.

According to the definehotkeys documentation, you should be able to use this to add hot key code for the left arrow. Notice that it is “left”, not “leftarrow”.

definehotkeys "window","left",{message "left arrow pressed"}

However, that code doesn’t work. I did some experimentation, and this code does work.

definehotkeys "window","function-left",{message "left arrow pressed"}

For some reason, Apple is adding the function modifier when the arrow keys are pressed. Weird. And if you actually press the function key and an arrow key at the same time, it sends a completely different key code. I don’t know of any other key that works like that, and I’m pretty sure Carbon (which Panorama 6 uses) does not work that way.

So for right now, you can define the arrow hot key code using function-left, function-right, etc. Now that I know about this, however, I may add special case code to change this, however, so be warned that code you write today might have to be changed soon. I’ll keep you updated on what I decide.


I have another suggestion (optional), let’s look at the first line of your code:

if info("formevent") match "Front"

Panorama X 10.1 has a new way to do this. The old way will still work (and congrats on figuring it out w/o documentation), but the new method will have higher performance. To learn about this new way see Form Event Procedures on the Implicitly Triggered Procedures page.

So I would switch the code to:

return

formFRONT:
    definehotkeys "window","function-left",{message "left arrow pressed"}
    return

Also, I might think about changing formFRONT to formOPEN, no reason to run this code every time the window comes to the front. Though it is kind of handy for debugging. If you do leave it as formFRONT, I would actually change it to this:

return

formFRONT:
    deletehotkeys "window"
    definehotkeys "window","function-left",{message "left arrow pressed"}
    return

This makes sure that you have a “clean slate” every time you change the hot key definitions. If you use formOPEN, this isn’t really necessary because you’ll get a clean slate every time the form opens anyway.

Let me take a moment to explain why this is no longer in Panorama X. The .KeyDown procedure was a very coarse tool – EVERY SINGLE KEY typed into the database would go thru the .KeyDown code. Usually you only want special handling for a few keys, and you want Panorama to handle the rest. This was cumbersome, slow and also required the key statement, which was going to be difficult to implement under Cocoa.

With the new system, you can trap only the exact keys you want, and only in specific windows if you want. All other keys are automatically left to Panorama to handle (at full speed). So you just worry about the specific situations where you do want custom key handling


#6

This:

execute ||definehotkeys "file","control-|| + chr(97) + ||",{message "hello"}||

defines CTRL-a as a hotkey. Using chr(63234) gives this error message:

48%20pm

but maybe you can take it from here …


#7

The key code for Control has been 3B


#8

It’s all a mystery to me James - I was just trying to be helpful.


#9

Jim’s “function-left” and formOPEN suggestions worked perfectly. I can now control all aspects of user initiated arrow key presses with any form. Fantastic!

One side effect with this nice bit of example code:

  return
  formFRONT:
     deletehotkeys "window"
     definehotkeys "window","function-left",{message "left arrow pressed"}
     return

In a Form Event Procedure, repeated pressing of the left arrow key without clicking away the message dialogs that get popped up produces multiple stacked message dialogs. That’s probably not a good thing… There was some weird screen artifacts when attempting to click them away. PanX did not crash, just erratic screen flickering at the dialog spots when clicked. Here is a shot of the stacked message dialogs:

If the message dialog is intended to be modal, is there a way to force the user to confirm the dialog before any additional actions are accepted and initiated?


#10

If this had been a Panorama generated dialog, this wouldn’t have happened. Panorama dialogs open in special Panorama windows, and since you have defined your hotkeys for a specific window, they wouldn’t work if a different window was on top.

However, the message alert is an Apple dialog. Panorama doesn’t know anything about that, as far as Panorama is concerned, the Panorama window is still active. So your hotkey is still active. The hotkey system patches into Panorama at a very low level of code. So when you click a hotkey, Panorama is going to perform that action – even if an alert is active.

My first recommendation would be – don’t activate an alert from a hotkey. But if you do, then you should probably disable the hotkeys before displaying the alert.

definehotkeys "window","function-left",|||
    deletehotkeys
    message "left arrow pressed"|||

However, this leaves the problem of how to re-enable the hotkey when the alert is finished. I think this could be done with a timer, but I’ll stick with my recommendation – don’t use alerts in hotkey code. Use a Panorama dialog or nsnotify instead. Or, just be careful not to press the hotkey again when the alert is active.


#11

How about just replacing {message “left arrow pressed”} with {alertsheet “left arrow pressed”}.


#12

It’s not clear to me that nested dialog sheets are going to be better than nested modal dialogs – maybe worse.


#13

Well, shame on me - I never actually tested this and just assumed the modal sheet window would not respond to the hotkey. Wrong! It does keep creating new sheets on top of each other with each additional key press and crashes Panorama as soon as you start closing them. Usually I test these things before opening my mouth but did not this time around and paid the price.:unamused:


#14

I didn’t test it either, but I had a bad feeling about it, just like Hans Solo approaching the Death Star.


#15

You are obviously more attuned to the Force than I am.