ctrl+ and ctrl- in xBrowse

Post Reply
Natter
Posts: 1279
Joined: Mon May 14, 2007 9:49 am

ctrl+ and ctrl- in xBrowse

Post by Natter »

Pressing ctrl+ and ctrl- changes the background size in xBrowse. What block code can be used to handle these events ?
User avatar
Antonio Linares
Site Admin
Posts: 42836
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 169 times
Been thanked: 123 times
Contact:

Re: ctrl+ and ctrl- in xBrowse

Post by Antonio Linares »

Okay, you want to intercept the default behavior of Ctrl++ (Control + Numpad Plus) and Ctrl+- (Control + Numpad Minus) in TXBrowse. By default these combinations call the :FontSize() method to increase or decrease the font size of the browse.

To override this and execute your own code (perhaps for changing background size, although that's less common and more complex than font size, or for any other custom action), you should use the bKeyDown codeblock property of the TXBrowse object.

How to Use bKeyDown:

Assign a codeblock to the :bKeyDown data member after you create the TXBrowse object but before the dialog/window is activated. This codeblock will receive the key code (nKey) and modifier flags (nFlags) just like the internal KeyDown method.

Crucially, if your codeblock handles the key combination, it MUST return 0. Returning 0 tells the browse (and the underlying system) that the key has been processed and no further default action (like calling the internal :FontSize() or passing the key to the parent) should occur. Returning NIL (or any non-zero value) allows the default processing to continue.

Example Codeblock:

Code: Select all | Expand

#include "InKey.ch" // Required for VK_ constants

// Assuming oBrw is your TXBrowse object instance

oBrw:bKeyDown := {| nKey, nFlags, oBrowse |
    local lCtrlDown

    // Check if the Control key is pressed
    // GetKeyState returns a negative value if the key is down.
    lCtrlDown := ( GetKeyState( VK_CONTROL ) < 0 )

    IF lCtrlDown
        DO CASE
            CASE nKey == VK_ADD // Numpad Plus key
                // --- Your custom code for Ctrl + '+' ---
                MsgInfo( "Ctrl + Numpad Plus detected!" )
                // Example: Maybe change a custom property or call a function
                // oBrowse:SomeCustomBackgroundResize( +1 )
                // --------------------------------------
                RETURN 0 // IMPORTANT: Prevent default FontSize(+1) action

            CASE nKey == VK_SUBTRACT // Numpad Minus key
                // --- Your custom code for Ctrl + '-' ---
                MsgInfo( "Ctrl + Numpad Minus detected!" )
                // Example:
                // oBrowse:SomeCustomBackgroundResize( -1 )
                // --------------------------------------
                RETURN 0 // IMPORTANT: Prevent default FontSize(-1) action

           /* // Optional: Handling for main keyboard +/- (less common/reliable for this)
            CASE nKey == VK_OEM_PLUS .AND. GetKeyState( VK_SHIFT ) < 0 // Main keyboard '+' (usually needs Shift)
                 MsgInfo( "Ctrl + Main Plus detected!" )
                 RETURN 0
            CASE nKey == VK_OEM_MINUS // Main keyboard '-'
                 MsgInfo( "Ctrl + Main Minus detected!" )
                 RETURN 0
           */

        ENDCASE
    ENDIF

    // If the key wasn't handled above, return NIL to allow default processing
    // for other keys (like arrows, Enter, etc.)
    RETURN NIL
|}

// --- Rest of your browse setup and activation ---
// oBrw:CreateFromCode() or oBrw assigned in resource definition
// ACTIVATE WINDOW ...
Explanation:

#include "InKey.ch": Make sure this is included at the top of your PRG file to define constants like VK_ADD, VK_SUBTRACT, VK_CONTROL, etc.
oBrw:bKeyDown := {|| ... }: Assign the codeblock to the browse object's bKeyDown property.
Parameters: The block receives nKey (the virtual key code), nFlags (modifier flags, though GetKeyState is often clearer for specific modifiers), and oBrowse (the browse object itself).

GetKeyState(VK_CONTROL): Explicitly checks if the Control key is currently held down.

CASE nKey == VK_ADD / VK_SUBTRACT: Checks if the pressed key is the Numpad Plus or Numpad Minus. Note: Using the Numpad keys is generally more reliable for this type of shortcut than the main keyboard '+' and '-' which might involve Shift and have different VK codes (VK_OEM_PLUS, VK_OEM_MINUS).
// --- Your custom code ---: Replace the MsgInfo calls with the actual logic you want to perform when these key combinations are pressed.

RETURN 0: This is essential. It stops the TXBrowse's internal KeyDown method from processing this specific key event further, thereby preventing the default :FontSize() call.

RETURN NIL: If the key combination is not Ctrl++ or Ctrl+-, the codeblock returns NIL. This allows the default TXBrowse:KeyDown method (and potentially the parent window) to handle other keys normally (like arrow keys, page up/down, Enter, Escape, etc.).

By implementing this bKeyDown block, you gain full control over what happens when Ctrl++ and Ctrl+- are pressed within your specific TXBrowse instance.
regards, saludos

Antonio Linares
www.fivetechsoft.com
Natter
Posts: 1279
Joined: Mon May 14, 2007 9:49 am

Re: ctrl+ and ctrl- in xBrowse

Post by Natter »

It might be easier to change the :FontSize() method ?
User avatar
Antonio Linares
Site Admin
Posts: 42836
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 169 times
Been thanked: 123 times
Contact:

Re: ctrl+ and ctrl- in xBrowse

Post by Antonio Linares »

That's an interesting thought, and in some pure OOP scenarios, overriding a method in a subclass is a common way to change behavior.

However, in the context of TXBrowse and how FiveWin often handles customization, overriding :FontSize() is generally not the recommended or easiest approach for intercepting the keyboard shortcut.

Here's why and why bKeyDown is preferred:

Modifying the Library: You cannot directly change the METHOD FontSize(...) CLASS TXBrowse line within the xbrowse.ch file itself. Modifying library source code is highly discouraged as it makes updates impossible and can lead to instability.

Subclassing Complexity: To override it properly, you would need to:
Create your own class: CLASS MyXBrowse FROM TXBrowse.
Define a METHOD FontSize(nPlus) within your MyXBrowse class.
Use MyXBrowse instead of TXBrowse wherever you define your browse.

Crucially: Your overridden FontSize method would completely replace the original. If you ever wanted the actual font sizing behavior (maybe called from somewhere else), you'd have to explicitly call ::Super:FontSize(nPlus) inside your overridden method.

Separation of Concerns: The KeyDown method is responsible for interpreting the key press (Ctrl + '+') and deciding what action to call (which happens to be :FontSize by default). The :FontSize method is responsible for performing the action (changing the font and refreshing). Using bKeyDown intercepts the event at the interpretation stage, which is cleaner. Overriding :FontSize intercepts at the action stage, which might have unintended consequences if :FontSize were ever called from somewhere else besides the Ctrl++/- handler.

bKeyDown is the Intended Mechanism: The bKeyDown (and bKeyChar, bGotFocus, bLostFocus, etc.) codeblocks are specifically provided in FiveWin controls as the standard, flexible way to hook into and customize event handling without needing to subclass or modify the original class methods. They allow you to:

React to specific events.

Perform custom actions.

Optionally prevent the default action (by returning 0 from bKeyDown).

Simplicity: While subclassing might seem appealing initially, the bKeyDown approach is arguably simpler for this specific task:
No need to define a new class.

You only write code for the specific keys you want to handle.

The mechanism to prevent default behavior (return 0) is straightforward.

In summary:

While you could technically override :FontSize by creating a subclass, it's more complex, potentially brittle (if the base class changes how :FontSize is used), and mixes the concerns of input handling and action execution.

Using the provided bKeyDown codeblock is the idiomatic and recommended FiveWin/TXBrowse way to intercept keyboard events like Ctrl++ and Ctrl+-, perform custom actions, and prevent the default behavior.
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply