Data Access Worldwide Knowledge Base

Article ID 2316
Article Title HOWTO: Automatically assign an accelerator key based on underlined character in a button label
Article URL http://www.dataaccess.com/kbasepublic/KBPrint.asp?ArticleID=2316
KBase Category VDF12
Date Created 05/24/2007
Last Edit Date 06/13/2007


Article Text
QUESTION:
When I use buttons in my components I usually let Visual DataFlex underline one of the characters to indicate the hotkey (accelerator key) that executes the same functionality as the button. But often I forget to add the appropriate On_Key statement in the button's parent object. Can't this key assigment be automated?

ANSWER:
Yes, it can be automated. In the following code - subclass of button - the set label method is augmented. In this method we remove the current key definition - if any - and assign the new key definition. The trick is that a part of the code is executed as if it was executed in the key definition object.

Class cAcceleratorKeyMixin Is A Mixin
    //****************************************************************************
    // $Module name: DefineAccKeyProperties
    // $Author     : VO
    // Created     : 15-09-96 @ 16:33
    //
    // Description
    //  Add two properties to the object.
    //  1. phoKeyDestination: We can store the accelerator key destination object
    //     in this property. If not assigned by you, the key destination (the
    //     on_key location) will be the parent object.
    //  2. piKeyModifier: Default is the Key_Ctrl plus your underlined character
    //     but you can also store key_alt or key_shift in the property. Note that
    //     a menubar overrides a key_alt+<char> combination if present.
    //
    // $Rev History
    //  15-09-96 Module header created
    //****************************************************************************
    Procedure DefineAccKeyProperties
        Property Handle phoKeyDestination (Parent (Self))
        Property Integer piKeyModifier Key_Ctrl
    End_Procedure
    
    //****************************************************************************
    // $Module name: AcceleratorKeyDef
    // $Author     : VO
    // Created     : 24-05-07 @ 14:33
    //
    // Description
    //  This method will find the underlined key in the value of the button (the
    //  label). If present, a keymapping based on the keymodifier (usually
    //  key_ctrl) and the underlined character will be created. If possible - the
    //  key exists - the key id will be returned in the byref variable. The message
    //  property value will be returned as the message to be send. Finally, the
    //  aux_value property is read and returned. If the latter one is 0 the current
    //  object ID will be used instead.
    //
    //  The function returns true if the function created a key mapping.
    //
    // $Rev History
    //  24-05-07 Module header created
    //****************************************************************************
    Function AcceleratorKeyDef Integer BYREF iKey Integer BYREF iMsg Handle BYREF hoDestination Returns Boolean
        String sItemValue sKeyChar
        Integer iKeyChar iKeyModifier iPos
        Boolean bSuccess
    
        Get Value Item 0 To sItemValue
        Move (Pos ("&", sItemValue)) To iPos
        If (iPos > 0) Begin
            Move (Uppercase ("KEY_" - Mid (sItemValue, 1, iPos + 1))) To sKeyChar
            Move (Eval (sKeyChar)) To iKeyChar
            If (iKeyChar > 0) Begin
                Get piKeyModifier To iKeyModifier
                Move (iKeyModifier + iKeyChar) To iKey
                Get Message Item 0 To iMsg
                Get Aux_Value Item 0 To hoDestination
                If (hoDestination = 0) Begin
                    Move Self To hoDestination
                End
                Move True To bSuccess
            End
        End
        
        Function_Return bSuccess
    End_Function
    
    //****************************************************************************
    // $Module name: AssignAcceleratorKey
    // $Author     : VO
    // Created     : 15-09-96 @ 16:33
    //
    // Description
    //  This method constructs a keymapping (via AccelatorKeyDef) and if successful,
    //  the key mapping will be added or removed from the key destination object.
    //  The trick in this routine is that a part of the code is executed as if
    //  the code was part of the key destination object.
    //
    // $Rev History
    //  15-09-96 Module header created
    //****************************************************************************
    Procedure AssignAcceleratorKey Boolean bRemove
        Integer iKey iMsg
        Boolean bKeyDefined
        Handle hoDestination hoSelf hoKeyDestination
    
        Get AcceleratorKeyDef (&iKey) (&iMsg) (&hoDestination) To bKeyDefined
        If (bKeyDefined) Begin
            Get phoKeyDestination To hoKeyDestination
            If (hoKeyDestination > 0) Begin
                Move Self To hoSelf
                Move hoKeyDestination To Self
                If (bRemove) Begin
                    On_Key iKey Send Default_Key Of hoDestination                
                End
                Else Begin
                    On_Key iKey Send iMsg Of hoDestination
                End
                Move hoSelf To Self
            End
        End
    End_Procedure
    
    //****************************************************************************
    // $Module name: Set Label
    // $Author     : VO
    // Created     : 15-09-96 @ 16:33
    //
    // Description
    //  This method is augmented to assign an accelerator key for execution of
    //  the object's message.
    //
    // $Rev History
    //  15-09-96 Module header created
    //****************************************************************************
    Procedure Set Label String sLabelText
        Send AssignAcceleratorKey True
        Forward Set Label To sLabelText
        Send AssignAcceleratorKey False
    End_Procedure
End_Class

Class cMyButton Is A Button
    Import_Class_Protocol cAcceleratorKeyMixin
    
    //****************************************************************************
    // $Module name: Construct_Object
    // $Author     : VO
    // Created     : 15-09-96 @ 16:33
    //
    // Description
    //  Send a message to define extra properties.
    //
    // $Rev History
    //  15-09-96 Module header created
    //****************************************************************************
    Procedure Construct_Object
        Forward Send Construct_Object
        
        Send DefineAccKeyProperties
    End_Procedure    
End_Class

To test the above code either directly use it in your own system or use the enclosed test view to see the results.


Contributed By:
Vincent Oorsprong
Company: Data Access Worldwide
email: vincent.oorsprong@dataaccess.eu
Web Site: http://www.dataaccess.eu

Web Links Related to this Article
File testacckey.vw
URL=http://www.dataaccess.com/KBasePublic/Files/2316.testacckey.vw


Email this Article
Email this Article to a Colleague
Send Feedback on this Article to Data Access Worldwide
Copyright ©2010 Data Access Corporation. All rights reserved.

The information provided in the Data Access Technical Knowledge Base is provided "as is" without warranty of any kind. Data Access Corporation disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. In no event shall Data Access Corporation or its suppliers be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages, even if Data Access Corporation or its suppliers have been advised of the possibility of such damages. Some states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing limitation may not apply.