The state of modifier keys in FileMaker is represented as a five-bit number taking values from 0 to 31. To read the state of a particular key means to read a particular bit of this number. FileMaker doesn't have native support for binary operations, so developers have to do this on their own. The best way, I think, is to write a few simple custom functions.
The “simplest” (that is without thinking) method would be to go ahead and check the current value of Get( ActiveModifierKeys ) each time you're to read the current state of modifier keys. This approach has several disadvantages. First, one must do it right. Simply checking for
may or may not give you the state of the Shift key, because at the same moment the user may have the other modifier active. For example, if Caps Lock is active, the result of Get( ActiveModifierKeys ) will be 6; same is for other keys, though they're less likely to be mixed.
Second, it's difficult to check for combinations of keys: the code becomes hardly readable. Time, for example, how long does it take you to answer what exactly is checked by the following code:
In my applications I use a few custom functions to check the modifier keys' state. For example, I have a function Shift Is Pressed. This function takes no arguments and returns either True or False depending on the current state of the Shift key. It doesn't care whether other modifiers are pressed or not. With such functions the calculations I write look much simpler:
The general Bit Is Set() function
All the modifier key functions are based on the general Bit Is Set() function. The function takes two parameters:
Bit Is Set( number, bit )
and returns either True or False depending on whether a particular bit of a number is actually set. The function itself is simple:
Test unit test
Modifier key functions
Once you have the Bit Is Set() function these functions are straightforward; what is more important is how to name them. Since these functions aren't the meat of you application and you won't use them very often, it would pay giving them longer and more readable names. I myself have tried two styles:
All caps:
OPTION KEY and not CONTROL KEYPhrases:
Option Is Pressed and not Control Is Pressed
The latter seems to be slightly more readable, so now I stick to it. Here are the functions:
Control Is Pressed
Caps Lock Is Pressed
Shift Is Pressed
Option Is Pressed
Command Is Pressed
Technorati tags: FileMaker, FileMaker 7, FileMaker 8, custom function.
Mikhail,
Thanks very much for this article. In case you're interested, I used the concepts here to create a slightly different custom function that works in place of the five you have:
ModifierKeyIsActive( ModifierKey ) = ~BitIsSet( Get( ActiveModifierKeys ); ModifierKey )
My ~BitIsSet function is the same as your Bit Is Set (just a different naming convention). I then have other custom functions for the constant powers, i.e., kModifierCommand = 16. Of course, I have one custom function that operates in place of your five, but add five others to handle the constants for readability. Just my preference. :) Of course, this gets called like this:
ModifierKeyIsActive( kModifierCommand )
Chuck
Posted by: Charles Ross | August 01, 2006 at 01:48 AM
I actually like your variant more, because it's easier to set up: one function and five straightforward constants. As I use my variant, I noticed that it takes extra time to figure out what bit stores the state of the Option key, if its code in help is 8 :) Of course, it happens only when I add functions in a new file, yet it's less efficient.
I also noticed I've switched from using similar all-inclusive functions like "Window Mode is Find()" to simpler Get( WindowMode ) = FIND MODE, where FIND MODE is a constant, so I believe I adopt your style for modifiers too. Makes code a bit cleaner. Thanks, Chuck :)
Posted by: m.edoshin | August 02, 2006 at 07:34 PM
Hello,
And how to control these keys using IWS (Instant Web Serrver)?
The answer of the funcition Get( ActiveModifierKeys ) is always 0 when the key of a client is pressed using the web browser.
Thanks in advance
Jordi Rodríguez
Posted by: Jordi Rodríguez | March 06, 2009 at 06:14 PM
Hi Jordi,
Unfortunately, in IWP this is not possible.
Posted by: m.edoshin | March 08, 2009 at 02:17 AM