PushButton.SetFocus on Mac

From REALbasicWiki

Jump to: navigation, search

 Available on Mac OS only  This article applies only to Mac  

[edit] Problem

Although there is a SetFocus method for the PushButton class, it does not work by design.

Setting a button's focus was apparently not possible on a Mac until some point in the past, leading now to a preference in System Preferences, Keyboard & Mouse, Full Keyboard Access:

Image:Image20070924a.jpg


Example 1: If set to "Text boxes and lists only" a button cannot have focus:

Image:Image20070924b.jpg


Example 2: If set to "All controls" a button can have focus:

Image:Image20070924c.jpg


Having focus means that pressing the space bar on the keyboard triggers the button. The focus ring around the button gives a visual feedback to the user on which button acts so.

In example 2, besides using the mouse, the user can press the return key to trigger the Delete button, or press the space bar to trigger the Cancel button, all without having to press the tab key repeatedly to navigate to the appropriate button.

[edit] Workaround

To set the focus of a button one needs to make a CarbonLib API call.

However, it is not possible to set the focus directly, but sending the keyboard's tab key code repeatedly to the window until the desired key has focus will do the trick.

The advantage of this approach is that the Full Keyboard Access mentioned above preference is honored implicitly.

To determine how many tabs are necessary the control order has to be taken into account for all controls that can receive focus.

 Private Sub PressKey(KeyCode As Integer)
   // Added 2002-02-10 by Kevin Ballard
   // Corrected 2007-09-15 by Detlev Schmidtke (3rd and 4th bytes were set, but only 2nd should be)
   
   // This sends the KeyDown and KeyUp events for a specific KeyCode.
   // Unfortunately, because of how this uses Virtual KeyCodes, and because
   // I can't find any way to translate regular KeyCodes to Virtual KeyCodes, the
   // only use of this is to test it to find the values for specific characters, then
   // use those values. See PressKey_Tab for a good use of this method.
   
   // 68k Compatible
   
   Const kKeyDown = 3
   Const kKeyUp = 4
   
   Dim OSErr As Integer
   Dim Msg As MemoryBlock
   
   #if TargetMacOS
     
     #if TargetCarbon
       Declare Function PostEvent Lib "Carbon" (eventNum As Short, eventMsg As Integer) As Short
     #else
       Declare Function PostEvent Lib "InterfaceLib" (eventNum As Short, eventMsg As Integer) As Short Inline68K("A02F")
     #endif
     
     Msg = NewMemoryBlock(4)
     
     Msg.Byte(0) = 0
     Msg.Byte(1) = KeyCode
     Msg.Byte(2) = 0
     Msg.Byte(3) = 0
     
     OSErr = PostEvent(kKeyDown, Msg.Long(0))
     OSErr = PostEvent(kKeyUp, Msg.Long(0))
     
   #endif
   
 End Sub

Call this function the calculated number of times:

 Protected Sub PressKey_Tab()
   // Added 2002-10-02 by Kevin Ballard
   
   // This uses PressKey to type the tab character.
   // This is primarily useful for moving to the next control which
   // can receive the focus.
   
   // 68k Compatible
   
   PressKey(48) 'tab
 
 End Sub

[edit] References

The above code is retrieved and corrected from the OpenSource CarbonDeclareLib currently maintained here: [1]

Personal tools
related