Using Alpha Five version 4's OnKey Event

by Dr. Peter Wayne

When A5v4 comes out, it's going to have a number of nifty features. This article introduces the OnKey event, new to Alpha Five version 4, and shows how to use it to program a progressive search field.
Warning
: This article is based on a beta release of Alpha Five version 4. Although I believe the points discussed here will apply to the final version, there is a small chance that the OnKey event will be modified by Alpha Software before the release.

Wouldn't you like to start typing in a "Find by Key" dialog, and have Alpha Five update the display as you type the individual keys? That is, as you type "Softquad", the form will first display the words beginning with "s", then those starting "so", then "sof", and so on. Right now, all Alpha Five can do is wait until you have finished typing and pressed {ENTER} or {F9} before beginning a search.

Well, in Alpha Five version 3 you're stuck, because there is no way to intercept individual keystrokes. But in version 4 there is a new event, the OnKey event, that reacts to each keystroke. We can use the OnKey event to program a more dynamic Find by Key form.

This is the form that we will create. Note how as the invisible "user" types in softq the browse scrolls down to softquad, and then as our invisible user types backspaces the browse scrolls up to the top:

Example of scrolling Find

Figure 1. Example of scrolling Find

The OnKey Event

We're going to use the OnKey event, which is a new form-level event. The OnKey event fires under 3 circumstances:

So pressing a key results in 2 or 3 calls to the OnKey event: 2 if the key is briefly touched, 3 if the key is held down for a while. We can determine which activity is triggering the OnKey event by inspecting the value of the special variable, a_user.key.event, which can have the value of "up", "down", or "repeat".

Other Special OnKey Variables

The a_user.key.value variable contains the key that initiated the OnKey event. For example, if the user presses "b", then a_user.key.value contains "b" also. If the user presses a nonprinting key, then a_user.key.value contains the same text that Alpha Five uses in the sys_send_keys() function: "{BACKSPACE}" if the backspace key is pressed, "{F5}" if function key F5 is pressed, "{CONTROL}" and then "c" if the user presses Ctrl-C.

Another special OnKey variable is a_user.key.handled. If your script sets this value to .t., then Alpha Five knows that your script has handled the key, and the key is "swallowed" by your script and never reaches the form. If you set a_user.key.handled to .f., then your script passes the key action on to the form.

Summary of OnKey special variables
OnKey special variable Behavior
a_user.key.event can be either "down", "up", or "repeat"
a_user.key.value contains the key that was pressed. For regular keys, contains the value. For control keys, use the same format as in sys_send_keys(), e.g., "{%F5}" is Alt-F5
a_user.key.handled set to .f. if you want your script to pass the key value on to Alpha Five
set to .t. if you want your script to "swallow" the key

Here comes the form

For this article, we'll use one simple table, keystrokes.dbf, with a single field, name, defined as Character, width 16, and indexed in ascending order on name. I entered a number of names into the keystrokes table - I wasn't particularly choosy about the words I entered, I just had to populate the table with something!

We start to create our form by placing a Session-level variable, choice, on a blank form. From the Drag-Drop list drag "New variable" to the form, and call it choice:Drag-Drop list
Fig. 2. Choose New Variable from the Drag-Drop list.

Place the choice variable on the form:Place variable on form
Fig. 3. Place the choice variable on the blank form.

From the form designer, select Form, Variables, and set the level of the choice variable to Session:

Session-level variable
Fig. 4. Make choice into a session-level variable.

Finally, add a browse based on the keystrokes table to the form. Accept the default name of browse1 which Alpha Five assigns to this browse. Save the form - I called mine the keystrokes form.

And now, the code...

As letters are entered into the choice field, we want to resynch browse1 to the current contents of choice. I thought I would use 2 variables, tempstr and posn, to record the current search string (= choice) and the length of the search string as letters are added or subtracted. The OnActivate script for the form initializes these variables:OnActivate script
Script 1. OnActivate script for the form.

The work of interpreting the key entries is done by the OnKey script for the form:

dim shared tempstr as c
dim shared posn as n
dim shared choice as c

dim up as c
dim repeat as c
table.current().index_primary_put("name")

if this.active()="choice" then
  select  
    case a_user.key.event="down"
     if left(a_user.key.value,1)="{" then 
      ' it's a control key or backspace or function key
        select
    case a_user.key.value="{BACKSPACE}"
     if posn>0 then 
      posn=posn-1
      tempstr=iif(posn=0,"",left(tempstr,posn))
      a_user.key.handled=.t.
     end if 
    case else
     ' pass through
     a_user.key.handled=.f.
   end select
  else
   posn=posn+1
   tempstr=tempstr+a_user.key.value
   a_user.key.handled=.t.
  end if
 case a_user.key.event="up"
  up=a_user.key.value
  a_user.key.handled=.t.
 case a_user.key.event="repeat"
  repeat=a_user.key.value
  a_user.key.handled=.t.
 end select

 table.current().fetch_find(tempstr)
 browse1.refresh()
 choice=tempstr
 choice.refresh()
end if

Script 2. OnKey script for the form

Note that in Script 2, our script "swallows" the up and repeat key events. The only nonprinting character that Script 2 understands is the {BACKSPACE} key.

In a real application, you might now want to use the OnRowDblClick method of the browse to launch a form or report based on the selected record found in browse1. If you want to get more sophisticated, you might try to see if you can amend Script 2 to recognize and behave appropriately when handed the {INS}, {DEL}, {LEFT} and {RIGHT} keys. If you succeed, let me know, and I'll post it as an addendum to this article!

9/5/98 - pkw

Don't forget, we need your feedback to make this site better!

Return to home