Intercept the *Return Key*

Just starting out? Need help? Post your questions and find answers here.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Intercept the *Return Key*

Post by MachineCode »

Manual wrote:A shortcut generates a menu event (like a menu item) as most of them are used in conjunction with menus.
So, they're meant to be used with menus. :P
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Intercept the *Return Key*

Post by Randy Walker »

kenmo wrote::?: :?: :?:

Randy, am I overlooking something...? Why can't you use AddKeyboardShortcut() with #PB_Shortcut_Return for your needs?...
The only problem is if your window has a multiline text gadget or editor gadget... how do you still receive Return presses? My preferred solution is...
Not to put words in your mouth but, we can finish that sentence with ''a workaround, for lack of having a clear and defined rock solid means of intercepting use of the return key''

I also have a number of windows in my app. Seventeen to be somewhat precise,and the majority do have multi-line StringGadgets, which in itself is already a workaround I adopted long ago to help defeat the ding that accompanies use of the Return key while inside a StringGadget if it is left single line. My string gadgets either prompt the user for information or they are provided as a means to perform a search. I use Fkeys in more than half the windows. So far I haven't found any need to disable/re-enable any of them. I would hate to have to adopt the practice as another workaround for managing the Return key.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Intercept the *Return Key*

Post by kenmo »

You aren't putting words in my mouth... I already put those words in my mouth. :) I ended my post with:
It sounds like a workaround, but it is simple to implement and seems to work fine.
And I guess that's my point... AddKeyboardShortcut() + a little bit of bookkeeping is one way (possibly the best way, currently) to accomplish your goal using native PB code. That's in addition to callbacks and OS-specific API/constants, which you already know about.

It sounds like the only thing you would not consider a "workaround" is a native KeyDown event in PB, or an EventType_ReturnKey, or similar. In that case, it sounds like you want a Feature Request rather than a Coding Question. (And that's fine, it would actually be very useful beyond just the Return key.)

But of course, in the end, it would be compiled to OS-specific code behind the scenes... just saves us some manual coding.


PS. I was just looking through the docs... didn't StringGadget used to have a MultiLine constant? Or has EditorGadget/ScintillaGadget always been the proper way to do multiline text?
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Intercept the *Return Key*

Post by Randy Walker »

kenmo wrote:PS. I was just looking through the docs... didn't StringGadget used to have a MultiLine constant? Or has EditorGadget/ScintillaGadget always been the proper way to do multiline text?
Yes, I saw somewhere that PB_multiline thingy was removed a long while back. I forget where I saw the comment.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Intercept the *Return Key*

Post by em_uk »

This method always works for me (rough version of the idea atleast) :

Code: Select all

return_key = 1
quit_event = 2
button_return=3
OpenWindow(0,#Null,#Null,400,200,"HAI",#PB_Window_ScreenCentered)
StringGadget(1,5,5,300,20,"Sting Field 1")
StringGadget(2,5,35,300,20,"2 Field String")
ButtonGadget(3,5,60,70,30,"Clear",#PB_Button_Default)
AddKeyboardShortcut(0,#PB_Shortcut_Return,return_key)
AddKeyboardShortcut(0,#PB_Shortcut_Escape,quit_event)
AddKeyboardShortcut(0,#PB_Shortcut_Return,button_return)


SetActiveGadget(1)

Repeat
  
  event=WaitWindowEvent()
  eventg=EventGadget()
  
  Select event
      
    Case #PB_Event_Gadget
      
      Select eventg
          
        Case 1,2
          Select EventType()
              
            Case #PB_EventType_Focus
              
              AddKeyboardShortcut(0,#PB_Shortcut_Return, return_key)
              
            Case #PB_EventType_LostFocus
              RemoveKeyboardShortcut(0,#PB_Shortcut_Return)
              AddKeyboardShortcut(0,#PB_Shortcut_Return,button_return)
          EndSelect
          
        Case 3

          AddKeyboardShortcut(0,#PB_Shortcut_Return,button_return)
          MessageRequester("Easy",GetGadgetText(1)+" See?")
          SetActiveGadget(1)
      EndSelect
      
    Case #PB_Event_Menu

      Select eventg
          
        Case return_key 
          
          Selected=GetActiveGadget()+1
          If (Selected)>3 : SetActiveGadget(Selected):EndIf
          SetActiveGadget(Selected) : SetGadgetState(Selected,1)

        Case button_return
          MessageRequester("Easy",GetGadgetText(1)+" See?")
          SetActiveGadget(1)
          
        Case quit_event
          Quit=1
          
      EndSelect
      
  EndSelect
 ; Debug event
Until Quit=1
----

R Tape loading error, 0:1
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Intercept the *Return Key*

Post by skywalk »

Respect multi-line EditorGadget without callbacks or removal of keyboard shortcuts.
Windows only...

Code: Select all

Global numMenuEntries = 4  ; Keep track of total menu items if you have any
Global return_key    = numMenuEntries + 1
Global quit_event    = numMenuEntries + 2
Procedure.i gad_NoTabStop(hndGad.i)
  Protected.i Style = GetWindowLongPtr_(hndGad, #GWL_STYLE)
  SetWindowLongPtr_(hndGad, #GWL_STYLE, Style & ((-1) - #WS_TABSTOP))
  ProcedureReturn hndGad
EndProcedure

Procedure Win0_Open()
  OpenWindow(0,#Null,#Null,400,200,"Hit Escape to Quit",#PB_Window_ScreenCentered)
  StringGadget(1,5,5,300,20,"String 1")
  StringGadget(2,5,35,300,20,"String 2")
  ButtonGadget(3,5,60,120,30,"Tab to here, then Enter",#PB_Button_Default)
  EditorGadget(4,5,110,300,60,#ES_MULTILINE)
  AddGadgetItem(4,-1,"Edit 1"+#CRLF$+"Hit Enter Here...Edit 1")
  gad_NoTabStop(GadgetID(4))
  AddKeyboardShortcut(0,#PB_Shortcut_Return,return_key)
  AddKeyboardShortcut(0,#PB_Shortcut_Escape,quit_event)
  If CreateMenu(0, WindowID(0))    ; menu creation starts....
    MenuTitle("Project")
    MenuItem(1, "Open"   +Chr(9)+"Ctrl+O")
    MenuItem(2, "Save"   +Chr(9)+"Ctrl+S")
    MenuItem(3, "Save as"+Chr(9)+"Ctrl+A")
    MenuItem(4, "Close"  +Chr(9)+"Ctrl+C")
  EndIf
  SetActiveGadget(1)
EndProcedure

Procedure Win0_Main()
  Repeat
    evWW = WaitWindowEvent()
    Select evWW
    Case #PB_Event_Gadget
      evG = EventGadget()
      Select evG
      Case 1,2
      Case 3
        MessageRequester("Clicked",GetGadgetText(3))
      EndSelect
    Case #PB_Event_Menu
      evM = EventMenu()
      Select evM
      Case return_key
        evG = GetActiveGadget()
        If evG = 4
          keybd_event_(#VK_SHIFT,0,0,0)
          keybd_event_(#VK_RETURN,0,0,0)
          keybd_event_(#VK_RETURN,0,#KEYEVENTF_KEYUP,0)
          keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0)
        Else
          MessageRequester("Return Key From:",GetGadgetText(evG))
        EndIf
      Case 4,quit_event
        Quit = 1
      EndSelect
    EndSelect
  Until Quit = 1
EndProcedure
Win0_Open()
Win0_Main()
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Intercept the *Return Key*

Post by Randy Walker »

Ok people... Get Ready ! ! ! :lol:

I'm getting my next 'Tips_n_Tricks' post lined up for submission, and boyyyyyy let me tell you. Its a whopper of a soulution. Centers on the use of the AddShortcutKey since that seem to be the general cencensus for non-API non-CAllBack cross platform operations. You're going to roll your eyes, and that's ok. Maybe over there we can snare all the seasoned eyeballs into the discussion and get this dilemma ironed out into something ''practical''.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Intercept the *Return Key*

Post by Randy Walker »

And here it is. As promised. The solution to beat all solutions :lol: (tongue in cheek) AND ... its cross platform, but it is also still just another workaround :? :( :cry:
viewtopic.php?f=12&t=49086&sid=b68c4e7d ... 4e11b4ce97
Also, submitted a Feature Request:
viewtopic.php?f=3&t=49089&sid=b68c4e7d9 ... 4e11b4ce97
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Intercept the *Return Key*

Post by MachineCode »

Randy Walker wrote:I have been forced to add a CallBack and things just went downhill from there. Can't seem to rely on WaitWindowEvent() = #WM_KEYDOWN checking any more.
#WM_KEYDOWN works fine with a Callback. Sorry to tell you this, but you're your own worst enemy. I'd say you just currently have a bad coding style if nothing's "working" when you add a Callback; and I truly, honestly say that without any intent of malice, or to cause offence, or to make you angry. Please don't take it the wrong way.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Intercept the *Return Key*

Post by Randy Walker »

MachineCode wrote:
Randy Walker wrote:I have been forced to add a CallBack and things just went downhill from there. Can't seem to rely on WaitWindowEvent() = #WM_KEYDOWN checking any more.
#WM_KEYDOWN works fine with a Callback. Sorry to tell you this, but you're your own worst enemy. I'd say you just currently have a bad coding style if nothing's "working" when you add a Callback; and I truly, honestly say that without any intent of malice, or to cause offence, or to make you angry. Please don't take it the wrong way.
Ok, so what you are saying here is, if I take my code from v4.20 that was working fine and I compile it using the v4.60 compiler and half my controls stop working then I have bad coding style?

While I can easily agree that I am my own worst enemy, I have to say there is something wrong in your logic. If the APIs compile and work fine in 4.20 then I expect they sould compile and work in v4.60 >> after applying changes ordained by PureBasic change logs, and only making said changes as specified in that change log.

If you are judging me on my last (ridiculous) post over in 'Tips-n-Trick' where I was using evey possible AddKeyboardShortcut then you missed the joke entirely. That was a satire on the total absence of any practical facility in PureBasic to catch keyboard input to a StringGadget. I think, even if you re-examine my basic code structure (ignoring the AddKeyboardShortcut non-sense) you will find my coding practices are very orderly. And, no. I'm not offended, angry and not taking it the wrong way. I like feedback, so thank you for that.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Intercept the *Return Key*

Post by MachineCode »

Randy Walker wrote:if I take my code from v4.20 that was working fine and I compile it using the v4.60 compiler and half my controls stop working then I have bad coding style?
Well, whether v4.60 can actually break previously working code from v4.20 is something that would have be checked by seeing your code. It's very possible that v4.60 does break something in your coding logic.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Intercept the *Return Key*

Post by ts-soft »

Windows Only,
here a small example that emulate old dialog behavior.
Return for buttons and stringgadgets.

Code: Select all

EnableExplicit

Procedure EmulateDialogCallback(hWnd, uMsg, wParam, lParam)
  Protected oldproc = GetProp_(hWnd, "oldproc")
 
  Select uMsg
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "oldproc")
    Case #WM_KEYDOWN
      Select GadgetType(GetDlgCtrlID_(hWnd))
        Case #PB_GadgetType_Button, #PB_GadgetType_ButtonImage
          If wParam = #VK_RETURN
            SendMessage_(hWnd, #BM_CLICK , 0, 0)
            ProcedureReturn 0
          EndIf
        Case #PB_GadgetType_String
          If wParam = #VK_RETURN
            SetFocus_(GetNextDlgTabItem_(GetParent_(hWnd), hWnd, #False))
            ProcedureReturn 0
          EndIf
        Case #PB_GadgetType_Option
          If wParam = #VK_DOWN
            SendMessage_(GetNextDlgGroupItem_(GetParent_(hWnd), hWnd, #False), #BM_CLICK , 0, 0)
            ProcedureReturn 0
          ElseIf wparam = #VK_UP
            SendMessage_(GetNextDlgGroupItem_(GetParent_(hWnd), hWnd, #True), #BM_CLICK , 0, 0)
            ProcedureReturn 0
          EndIf
      EndSelect
  EndSelect
 
  ProcedureReturn CallWindowProc_(oldproc, hWnd, uMsg, wParam, lParam)
EndProcedure

Procedure EmulateDialog(ID)
  Protected oldproc = SetWindowLongPtr_(GadgetID(ID), #GWL_WNDPROC, @EmulateDialogCallback())
  ProcedureReturn SetProp_(GadgetID(ID), "oldproc", oldproc)
EndProcedure

Procedure InitEmulateWin(ID)
  ProcedureReturn SendMessage_(WindowID(ID), #WM_CHANGEUISTATE, 2 | (1 << 16), 0)
EndProcedure

; Example

Define i
OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   
ButtonGadget(0, 10, 10, 200, 20, "Default Button")
StringGadget(1, 10, 40, 200, 20, "")
StringGadget(2, 10, 70, 200, 20, "")
OptionGadget(3, 10, 100, 60, 20, "Option 1")
OptionGadget(4, 10, 130, 60, 20, "Option 2")
OptionGadget(5, 10, 160, 60, 20, "Option 3")
SetGadgetState(3, 1)
SetActiveGadget(0)
For i = 0 To 5
  EmulateDialog(i)
Next

InitEmulateWin(0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow : Break
    Case #PB_Event_Gadget
      Debug "Gadget: " + Str(EventGadget()) + " : Type: " + Str(EventType())
  EndSelect
ForEver
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Intercept the *Return Key*

Post by Randy Walker »

@ts-soft ... Looks complicated :D
All contributions welcome, and thanks for the feedback :wink:
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Slyvnr
User
User
Posts: 58
Joined: Wed Jun 27, 2007 10:10 pm
Location: USA
Contact:

Re: Intercept the *Return Key*

Post by Slyvnr »

Randy Walker wrote:
Can we get a show of hands from the audience please? How many of you would call this a workaround?

Code: Select all

          Case #PB_Event_CloseWindow
            Quit = 1
I thought that was the standard way of doing the [X} close Window and not a work around.

Slyvnr
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Intercept the *Return Key*

Post by Randy Walker »

Slyvnr wrote:
Randy Walker wrote:
Can we get a show of hands from the audience please? How many of you would call this a workaround?

Code: Select all

          Case #PB_Event_CloseWindow
            Quit = 1
I thought that was the standard way of doing the [X} close Window and not a work around.

Slyvnr
This is a direct way to do the [x] close Window:

Code: Select all

  Repeat
    Event = WaitWindowEvent()
  
  Until Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
And this is some silly workaround (or perceived shortcut) some people have gotten into the habit of doing:

Code: Select all

  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      quit = 1
    EndIf
    
  Until quit = 1
If for some reason you encounter a condition that requires the application to close then this would be more appropriate:

Code: Select all

  Repeat
    Event = WaitWindowEvent()
    
    If MyRasberriesTurnBlue.l = #True
      Event = #PB_Event_CloseWindow
    EndIf
  
  Until Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
Always more than one way to skin a cat. I imagine there are even some people that would say Rube Goldburg is a master of efficiency. I think the direct way is more appropriate, if not more proper.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Post Reply