Page 1 of 1
Clean way to setup hotkeys for button events?
Posted: Fri Dec 14, 2007 7:40 pm
by superadnim
Hi, I'd like a clean way (windows only, if it requires callback I'm more than fine with that!) to setup hotkeys to my buttons.
I want to fire up a button event when I press enter for instance, if I have focus on a string gadget (The focus part, no problem) however I don't know how to nicely do this. I saw PB's go on hotkeys with the menu events, etc... I don't like it though!.
Also, I keep on getting the "ding" sound when I hit enter, could I disable this?
Re: Clean way to setup hotkeys for button events?
Posted: Sat Dec 15, 2007 12:40 am
by PB
Both questions have been answered several times before. Search the forums,
and read the FAQ post in the "Coding Questions" section. Thanks very much.
Posted: Sat Dec 15, 2007 4:06 am
by superadnim
Thanks, but both solutions were not as elegant as I would of wanted, thats why I asked.
First of all, for the "ding" sound, you mention "#PB_String_Multiline|#ES_AUTOVSCROLL " yet... why would I even mix "pb's" constants with win api's?, that's not elegant! the day of tomorrow I won't know what pb's constant is, but sure I will about the win api one.
About the hotkey, the methods I've seen were about using PB's hotkey "solution" which is convoluted IMO and another one catching high-level "key strokes"... (I stopped searching right there).
Sorry to repeat but I just wanted a non convoluted solution... It's not my idea to annoy anyone.
Posted: Sat Dec 15, 2007 4:26 am
by PB
> why would I even mix "pb's" constants with win api's?, that's not elegant!
Well, you did say: "I'd like a clean way (windows only, if it requires
callback I'm more than fine with that". So what's wrong with mixing
API then?
As for hotkeys activating when Enter is pressed on a StringGadget, you
can just check for a gadget event on the gadget and use EventWParam()
to see if it's #PB_Key_Enter.
As for the "ding" sound: it's explained in the link from the FAQ that this is
normal because you can't use Enter on a single-line StringGadget, and so
Windows does the "ding" to tell you that the key is invalid there.
Posted: Sat Dec 15, 2007 5:30 am
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
Posted: Sat Dec 15, 2007 7:08 am
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
Posted: Sat Dec 15, 2007 7:26 am
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).
Posted: Sat Dec 15, 2007 7:53 am
by npath
Whoops. I didn't think ahead.
npath
Posted: Sat Dec 15, 2007 8:01 am
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
Posted: Sun Dec 16, 2007 3:12 am
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
Posted: Sun Dec 16, 2007 3:23 am
by Sparkie
I changed my original code to lose the global var. I replaced it with SetProp_() (thanks netmaestro).

Posted: Sun Dec 16, 2007 5:57 am
by superadnim

Now that's code

Posted: Sun Dec 16, 2007 2:07 pm
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.

Posted: Sun Dec 16, 2007 8:46 pm
by superadnim
I take it those are cross-platform?, what's the counterpart of Set/GetProp() in Linus' ?
Posted: Sun Dec 16, 2007 11:10 pm
by Sparkie
According to the PB manual, Set/GetGadgetData() should be cross-platform.
