Clean way to setup hotkeys for button events?

Just starting out? Need help? Post your questions and find answers here.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

*** Edited to remove global var ***

Not fully tested and not sure if it meets your standards for elegance...

Code: Select all

Procedure SringProc(hwnd, msg, wParam, lParam) 
  oldproc = GetProp_(hwnd, "_oldProc") 
  Select msg 
    Case #WM_CHAR 
      ;...Remove ding sound and press button 
      If wParam = #VK_RETURN 
        SendMessage_(GadgetID(1), #BM_CLICK, 0, 0) 
        ProcedureReturn 0 
      EndIf 
  EndSelect 
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wParam, lParam) 
EndProcedure 
If OpenWindow(0, 0, 0, 300, 200, "Silent StringGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  StringGadget(0, 10, 10, 280, 25, "Normal StringGadget") 
  ButtonGadget(1, 10, 40, 280, 25, "Click me or press Enter in StringGadget") 
  EditorGadget(2, 10, 70, 280, 125) 
  oldproc = GetWindowLong_(GadgetID(0), #GWL_WNDPROC) 
  SetProp_(GadgetID(0), "_oldproc", oldproc)
  SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SringProc()) 
  Repeat 
    event = WaitWindowEvent() 
    If event = #PB_Event_Gadget And EventGadget() = 1 
      AddGadgetItem(2, -1, "Current string text is: " + GetGadgetText(0)) 
    EndIf 
  Until event = #PB_Event_CloseWindow 
  RemoveProp_(GadgetID(0), "_oldproc")
EndIf 
Last edited by Sparkie on Sun Dec 16, 2007 3:22 am, edited 1 time in total.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
npath
User
User
Posts: 74
Joined: Tue Feb 15, 2005 5:15 pm

Post by npath »

This doesn't ding on my system (Vista):

Code: Select all

Declare main()
Declare buttonClickEvent()

main()

Procedure main()
  If OpenWindow(0, 0, 0, 170, 80, "Main", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    If CreateGadgetList(WindowID(0))
      StringGadget(1, 10, 10, 150, 25, "")
      ButtonGadget(2, 10, 40, 150, 25, "OK")
    EndIf
    AddKeyboardShortcut(0, #PB_Shortcut_Return, 1)
    SetActiveGadget(1)
  EndIf
  
  Repeat
    event.l = WaitWindowEvent()
    
    Select event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 2
            buttonClickEvent()
        EndSelect
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            buttonClickEvent()
        EndSelect
    EndSelect
    
  Until (event = #PB_Event_CloseWindow)
EndProcedure

Procedure buttonClickEvent()
  SetWindowTitle(0, GetGadgetText(1))
EndProcedure
npath
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> This doesn't ding on my system (Vista)

@npath: The trouble with using AddKeyboardShortcut() is that it effectively
disables the Enter key for your app. For example: add an EditorGadget()
to your app and you won't be able to press Enter in it (without writing the
extra code to handle the keypress yourself).
npath
User
User
Posts: 74
Joined: Tue Feb 15, 2005 5:15 pm

Post by npath »

Whoops. I didn't think ahead.

npath
npath
User
User
Posts: 74
Joined: Tue Feb 15, 2005 5:15 pm

Post by npath »

Very slight modification of Sparkie's excellent code, which prevents the string gadget from losing focus (i.e., added SetActiveGadget(0) to the gadget event):

Code: Select all

Global oldproc
Procedure SringProc(hwnd, msg, wParam, lParam)
  Select msg
    Case #WM_CHAR
      ;...Remove ding sound and press button
      If wParam = #VK_RETURN
        SendMessage_(GadgetID(1), #BM_CLICK, 0, 0)
        ProcedureReturn 0
      EndIf
  EndSelect
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wParam, lParam)
EndProcedure
If OpenWindow(0, 0, 0, 300, 200, "Silent StringGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  StringGadget(0, 10, 10, 280, 25, "Normal StringGadget")
  ButtonGadget(1, 10, 40, 280, 25, "Click me or press Enter in StringGadget")
  EditorGadget(2, 10, 70, 280, 125)
  oldproc = GetWindowLong_(GadgetID(0), #GWL_WNDPROC)
  SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SringProc())
  Repeat
    event = WaitWindowEvent()
    If event = #PB_Event_Gadget And EventGadget() = 1
      AddGadgetItem(2, -1, "Current string text is: " + GetGadgetText(0))
      SetActiveGadget(0)
    EndIf
  Until event = #PB_Event_CloseWindow
EndIf 
npath
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

Even though I haven't compiled the code (no pb in blackberry yet!) for what I could read it seems like a nice solution to me ie. windows message based which is perfect the only bitter part is the global var! I'll see if I can use user data on the string "gadget" or something within the lines...

Thanks
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

I changed my original code to lose the global var. I replaced it with SetProp_() (thanks netmaestro). :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

8) Now that's code :)
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

superadnim wrote:I'll see if I can use user data on the string "gadget" or something within the lines...
You can replace Set/GetProp_() with Set/GetGadgetData() to make it more PBish. :wink:
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

I take it those are cross-platform?, what's the counterpart of Set/GetProp() in Linus' ?
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

According to the PB manual, Set/GetGadgetData() should be cross-platform. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Post Reply