How to activate the buttons using keyboard shortcuts

Windows specific forum
Jan2004
Enthusiast
Enthusiast
Posts: 163
Joined: Fri Jan 07, 2005 7:17 pm

How to activate the buttons using keyboard shortcuts

Post by Jan2004 »

I'm going to make a simple application where there will be no menu. Is it possible to activate the buttons using keyboard shortcuts. If anyone has an idea - please add the code.

Code: Select all

  If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(0, 10, 30, 200, 30, "Button activated with Ctrl+A")
    ButtonGadget(1, 10, 100, 200, 30, "Button activated with Ctrl+B")
    ButtonGadget(2, 10, 160, 200, 30, "Button activated with Ctrl+C")
  

Repeat
    Select WaitWindowEvent() 
      
      Case #PB_Event_CloseWindow   
        Break                      
        
      Case #PB_Event_Gadget  
        Select EventGadget()

          Case 0
            MessageRequester("Keyboard shotcuts", "It is click - not activated with Ctrl+A")
          Case 1
            MessageRequester("Keyboard shotcuts", "It is click - not activated with Ctrl+B")
          Case 2
            MessageRequester("Keyboard shotcuts", "It is click - not activated with Ctrl+B")

      EndSelect
    EndSelect 
  ForEver 
EndIf 
BarryG
Addict
Addict
Posts: 4168
Joined: Thu Apr 18, 2019 8:17 am

Re: How to activate the buttons using keyboard shortcuts

Post by BarryG »

Like this (handles both keyboard shortcuts and gadget clicks with the mouse):

Code: Select all

If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 30, 200, 30, "Button activated with Ctrl+A")
  ButtonGadget(1, 10, 100, 200, 30, "Button activated with Ctrl+B")
  ButtonGadget(2, 10, 160, 200, 30, "Button activated with Ctrl+C")
  
  AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_A, 0)
  AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_B, 1)
  AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_C, 2)
  
  Repeat
    
    event = WaitWindowEvent()
    
    Select event
        
      Case #PB_Event_CloseWindow   
        Break                      
        
      Case #PB_Event_Gadget, #PB_Event_Menu 
        
        If event = #PB_Event_Gadget
          which = EventGadget()
        Else
          which = EventMenu()
        EndIf
        
        Select which
          Case 0
            MessageRequester("Keyboard shotcuts", "It is click - not activated with Ctrl+A")
          Case 1
            MessageRequester("Keyboard shotcuts", "It is click - not activated with Ctrl+B")
          Case 2
            MessageRequester("Keyboard shotcuts", "It is click - not activated with Ctrl+B")
        EndSelect
        
    EndSelect 
    
  ForEver 
  
EndIf 
User avatar
spikey
Enthusiast
Enthusiast
Posts: 767
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: How to activate the buttons using keyboard shortcuts

Post by spikey »

Keyboard shortcuts generate menu events not gadget events but you can still use them without a menu if you don't need one. If you are using a menu add some 'virtual' menu items at the end of your menu enumeration for the shortcuts you wish to implement.

Code: Select all

Enumeration 
  ; Real menu enumerations here, if needed.
  ; ...
  ; End of real menu items.
  
  ; 'Virtual' menu items for shortcut keys not corresponding to a real menu item.
  #MenuEventButtonA
  #MenuEventButtonB
  #MenuEventButtonC
EndEnumeration  

If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(0, 10, 30, 200, 30, "Button activated with Ctrl+A")
  ButtonGadget(1, 10, 100, 200, 30, "Button activated with Ctrl+B")
  ButtonGadget(2, 10, 160, 200, 30, "Button activated with Ctrl+C")
  
  AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_A, #MenuEventButtonA)
  AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_B, #MenuEventButtonB)
  AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_C, #MenuEventButtonC)
  
  
  Repeat
    Select WaitWindowEvent() 
        
      Case #PB_Event_CloseWindow   
        Break                      
        
      Case #PB_Event_Gadget  
        Select EventGadget()
            
          Case 0
            MessageRequester("Keyboard shortcuts", "It is click - not activated with Ctrl+A")
          Case 1
            MessageRequester("Keyboard shortcuts", "It is click - not activated with Ctrl+B")
          Case 2
            MessageRequester("Keyboard shortcuts", "It is click - not activated with Ctrl+B")
            
        EndSelect
        
      Case #PB_Event_Menu
        Select EventMenu()
            
          Case #MenuEventButtonA
              MessageRequester("Keyboard shortcuts", "Keyboard Ctrl+A")
            
          Case #MenuEventButtonB
              MessageRequester("Keyboard shortcuts", "Keyboard Ctrl+B")
            
          Case #MenuEventButtonC
              MessageRequester("Keyboard shortcuts", "Keyboard Ctrl+C")
            
        EndSelect 
        
    EndSelect
    
  ForEver 
EndIf 
Jan2004
Enthusiast
Enthusiast
Posts: 163
Joined: Fri Jan 07, 2005 7:17 pm

Re: How to activate the buttons using keyboard shortcuts

Post by Jan2004 »

Thanks to my colleagues BarryG and spikey for smart solutions. (I had a 5 year break from using PureBasic). It turns out that with PureBasic you can do everything and even more.

It so happened that both interesting solutions differ from each other. The spikey solution - as far as I understand it, works independently - that is, the buttons create separate existences, and the menu - also separate: what will connect them is the same code for individual buttons and their corresponding shortcuts. The shortcut will work even if there is no button. However, in BarryG's solution, keyboard shortcuts are connected to individual buttons - they form a common team, but the lack of a button will also not make it impossible to run the shortcut: the point in this solution is to simplify (reduce) the event handler code by linking it (clicking bind from scratch with a shortcut from the keyboard). So what is here the role of "Event" from the command:

Code: Select all

AddKeyboardShortcut(#Window, Shortcut, Event)
Dear Colleagues, am I doing well?
User avatar
spikey
Enthusiast
Enthusiast
Posts: 767
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: How to activate the buttons using keyboard shortcuts

Post by spikey »

Jan2004 wrote: Sun Jul 16, 2023 2:00 pm The spikey solution - as far as I understand it, works independently
No, both do the same thing but use slightly different code to do it, that's all. As I said earlier, keyboard shortcuts generate menu events not gadget ones. Both solutions are turning a menu event into something that appears to be a gadget event to the user, but isn't really. It's still a menu event and must be handled as such.

BarryG's code relies on the fact that by default stuff gets numbered incrementally starting at zero. Mine doesn't rely on this particular fact, that's all.
Jan2004 wrote: Sun Jul 16, 2023 2:00 pm So what is here the role of "Event" from the command:

Code: Select all

AddKeyboardShortcut(#Window, Shortcut, Event)
No keyboard actions are created automatically. (With the exception of Alt-F4, which is created automatically if the #PB_Window_SystemMenu flag is applied to the window). This command makes the shortcut action actually occur in the program when the specified key sequence occurs. If you comment out these particular lines in both solutions, they will stop working properly. In this case the 'Event' parameter specifies exactly which menu action should occur when the key sequence 'Shortcut' is pressed.
Jan2004
Enthusiast
Enthusiast
Posts: 163
Joined: Fri Jan 07, 2005 7:17 pm

Re: How to activate the buttons using keyboard shortcuts

Post by Jan2004 »

Spikey: Your comment explains all. I will just add that the main trick in BarryG's code is that he uses the corresponding (the same) numbering for buttons and keyboard shortcuts and - in my opinion - is the meaning of using "Event" from the PureBasic command.

Years ago, I was a Basic user called CARealizer. (I even wrote an app in it.) With CARealizer, you could automatically add keyboard shortcuts to buttons, and you could underline letters with ampersands: if, for example, my button was called "Button activated with Shift+A" - then if I wrote "Button &activated with Shift+A" the letter "a" in the word "activated" would be underlined on the button. Is it possible to get something like this in PureBasic. If NOT, I will use GadgetToolTip to teach the users to quickly switch to keyboard shortcuts. It is known that tip text is displayed when the mouse cursor is over the gadget. I also decided that the keyboard shortcuts will not be Ctrl but Shift combinations, because Ctrl is often used (for example: Ctrl+n, Ctrl+o, Ctrl+s, Ctrl+w, etc.), and I can't break users habits. I finally adopted this code for use in my application:

Code: Select all

If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets activated with Shift", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 30, 200, 30, "Button activated with Shift+A")
  GadgetToolTip(0, "You can also activate this button with the Shift + A key combination")
  ButtonGadget(1, 10, 95, 200, 30, "Button activated with Shift+B")
  GadgetToolTip(1, "You can also activate this button with the Shift + B key combination")
  ButtonGadget(2, 10, 160, 200, 30, "Button activated with Shift+C")
  GadgetToolTip(2, "You can also activate this button with the Shift + C key combination")

  AddKeyboardShortcut(0, #PB_Shortcut_Shift | #PB_Shortcut_A, 0)
  AddKeyboardShortcut(0, #PB_Shortcut_Shift | #PB_Shortcut_B, 1)
  AddKeyboardShortcut(0, #PB_Shortcut_Shift | #PB_Shortcut_C, 2)
  ; AddKeyboardShortcut(#Window, Shortcut, Event)
  ; Add Or replace a keyboard shortcut To the specified window. A shortcut generates a menu
  ; Event (like a menu item) As most of them are used in conjunction With menus. 
  
  Repeat
    
    event = WaitWindowEvent()
    
    Select event
        
      Case #PB_Event_CloseWindow   
        Break                      
        
      Case #PB_Event_Gadget, #PB_Event_Menu 
        
        If event = #PB_Event_Gadget
          which = EventGadget()
        Else
          which = EventMenu()
        EndIf
        
        Select which
          Case 0
            MessageRequester("Keyboard shotcuts", "It is click on the button or activated with Shift+A")
          Case 1
            MessageRequester("Keyboard shotcuts", "It is click on the button or activated with Shift+B")
          Case 2
            MessageRequester("Keyboard shotcuts", "It is click on the button or activated with Shift+C")
        EndSelect
        
    EndSelect 
    
  ForEver 
  
EndIf 
BarryG
Addict
Addict
Posts: 4168
Joined: Thu Apr 18, 2019 8:17 am

Re: How to activate the buttons using keyboard shortcuts

Post by BarryG »

My example is very specific with hard-coded values, just to teach the theory and not repeat any code (3 x MessageRequesters instead of 6). There's many ways to do what OP wants, and Spikey's way can be better depending on the situation.
Post Reply