Page 1 of 1

Is there a #PB_Event_KeyDown ?

Posted: Thu Jan 08, 2026 4:54 pm
by charvista
Hi

I'm writing a very small procedure to insert a pause and only a click or a key pressed should release the pause.
This is handy to verify a situation, before continuing.
The left/right click are working fine, but how do I get the event for 'any' key pressed?

Code: Select all

Procedure zWait()
    Protected.i Event
    Repeat
        Event = WaitWindowEvent(1)
        Select Event
            Case #PB_Event_LeftClick, #PB_Event_RightClick;, #PB_Event_KeyDown
                Break
        EndSelect
    ForEver
EndProcedure

Re: Is there a #PB_Event_KeyDown ?

Posted: Thu Jan 08, 2026 5:08 pm
by RASHAD
You are a Windows user
So if you want to get any key pressed and any key combination with (alt-ctrl-shift)
You can use Local Hook

Re: Is there a #PB_Event_KeyDown ?

Posted: Thu Jan 08, 2026 5:13 pm
by RASHAD
Simple key checker

Code: Select all

OpenWindow(0, 0, 0,300,40, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
TextGadget(0, 0, 8, 300, 20, "Press any key.", #PB_Text_Center)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
  
    Case #WM_CHAR                         ;Char / Ctrl + Char
      key = EventwParam()
      Debug Str(KEY) + "    " + Chr(key)
      SetGadgetText(0, Str(KEY) + "    " + Chr(key))
      
    Case #WM_SYSKEYUP                     ;Alt + Char
      key = EventwParam()
      Debug Str(KEY) + "    " + Chr(key)
      SetGadgetText(0, Str(KEY) + "    " + Chr(key))
    
 EndSelect
  
Until Quit = 1

Re: Is there a #PB_Event_KeyDown ?

Posted: Thu Jan 08, 2026 5:37 pm
by Axolotl
Just a silly thought:
I am always hesitant to use #WM_ constants in the main loop because I believe that it is not future-proof.
I always have to think about #WM_CLOSE, because I think that this was also possible in the main loop in (very) old versions ... but maybe I am wrong.

Re: Is there a #PB_Event_KeyDown ?

Posted: Thu Jan 08, 2026 6:09 pm
by TI-994A
Hi @charvista. Since it can be used as a container, perhaps the CanvasGadget() could be a good cross-platform solution. It captures pretty much all mouse and keyboard events, including the mouse wheel, without the need for keyboard shortcuts or system-level APIs.

> CanvasGadget()

Re: Is there a #PB_Event_KeyDown ?

Posted: Thu Jan 08, 2026 7:05 pm
by charvista
@RASHAD
Not working for all keys

@TI-994A
Good idea, but it needs to open a window. I tested, but I am missing something as it does not detect any key:

Code: Select all

Define W = OpenWindow(#PB_Any,0,0,1,1,"",#PB_Window_Invisible)
Define C = CanvasGadget(#PB_Any,0,0,1,1,#PB_Canvas_Keyboard)
Repeat
    Select WaitWindowEvent()
        Case #PB_Event_Gadget
            Select EventGadget()
                Case C
                    Select EventType()
                        Case #PB_EventType_KeyDown
                            Debug "!"
                            Break
                    EndSelect
            EndSelect
    EndSelect
ForEver
CloseWindow(W)
Otherwise, I wrote this: (only for Windows):

Code: Select all

Repeat
    Delay(1)
    For i=0 To 255
        k=GetAsyncKeyState_(i) & $FFFF
        Select k
            Case 0, 1, 8, 116; those are ignored, as they are captured at launch
            Default
                Debug Str(i)+"  "+Str(k); only to show that it works
            Break 2
        EndSelect
    Next i
ForEver

Re: Is there a #PB_Event_KeyDown ?

Posted: Fri Jan 09, 2026 11:12 am
by TI-994A
charvista wrote: Thu Jan 08, 2026 7:05 pmGood idea, but it needs to open a window.

Yes, it does. If a cross-platform solution is imperative, you could always hide the window out of screen view, like this.

Code: Select all

Define W = OpenWindow(#PB_Any, -100, -100, 10, 10, "")
Define C = CanvasGadget(#PB_Any, 0, 0, 10, 10, #PB_Canvas_Keyboard)
SetActiveGadget(C)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Gadget
      Select EventGadget()
        Case C
          Select EventType()
            Case #PB_EventType_KeyDown
              Debug "!"
              Break
          EndSelect
      EndSelect
  EndSelect
ForEver
CloseWindow(W)

However, if it must be hooked at a system level, stick with GetAsyncKeyState_()API call.

Re: Is there a #PB_Event_KeyDown ?

Posted: Fri Jan 09, 2026 2:18 pm
by charvista
@RASHAD
I have found a code in the forum that comes from you, using GetAsyncKeyState_() and could simplify it by using & $8000. Thanks, RASHAD :wink:

Code: Select all

Procedure zWait()
    Define.i i,k
    Repeat
        Delay(10)
        For i = 1 To 255
            k = GetAsyncKeyState_(i) & $8000 ; bit 15 indicates "pressed"
            If k
                ;Debug Str(i)+"  "+Str(k)
                Break 2
            EndIf
        Next i
    ForEver
EndProcedure

@TI-994A
Thank you for the correction making it invisible with negative -x,-y, instead of using #PB_Window_Invisible.
And yes, for a cross-platform solution, it is indeed the best so far. As Linux becomes more and more popular, the use of native directives and functions are recommended for easy portability.

Re: Is there a #PB_Event_KeyDown ?

Posted: Fri Jan 09, 2026 9:40 pm
by BarryG
charvista wrote: Thu Jan 08, 2026 4:54 pmIs there a #PB_Event_KeyDown ?
For Windows, you can use #WM_KEYDOWN (or #WM_KEYUP for no repeats). Using Rashad's code:

Code: Select all

OpenWindow(0, 0, 0,300,40, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
TextGadget(0, 0, 8, 300, 20, "Press any key.", #PB_Text_Center)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
  
    Case #WM_KEYDOWN ; Use #WM_KEYUP if you don't want it repeatable.
      key = EventwParam()
      Debug Str(KEY) + "    " + Chr(key)
      SetGadgetText(0, Str(KEY) + "    " + Chr(key))
      
 EndSelect
  
Until Quit = 1