Is there a #PB_Event_KeyDown ?

Just starting out? Need help? Post your questions and find answers here.
User avatar
charvista
Addict
Addict
Posts: 958
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Is there a #PB_Event_KeyDown ?

Post 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
- Windows 11 Home 64-bit
- PureBasic 6.21 (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 8K monitor with DPI @ 300%
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 5022
Joined: Sun Apr 12, 2009 6:27 am

Re: Is there a #PB_Event_KeyDown ?

Post 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
Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 5022
Joined: Sun Apr 12, 2009 6:27 am

Re: Is there a #PB_Event_KeyDown ?

Post 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
Egypt my love
Axolotl
Addict
Addict
Posts: 907
Joined: Wed Dec 31, 2008 3:36 pm

Re: Is there a #PB_Event_KeyDown ?

Post 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.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
User avatar
TI-994A
Addict
Addict
Posts: 2789
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Is there a #PB_Event_KeyDown ?

Post 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()
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
charvista
Addict
Addict
Posts: 958
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Re: Is there a #PB_Event_KeyDown ?

Post 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
- Windows 11 Home 64-bit
- PureBasic 6.21 (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 8K monitor with DPI @ 300%
User avatar
TI-994A
Addict
Addict
Posts: 2789
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Is there a #PB_Event_KeyDown ?

Post 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.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
charvista
Addict
Addict
Posts: 958
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Re: Is there a #PB_Event_KeyDown ?

Post 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.
- Windows 11 Home 64-bit
- PureBasic 6.21 (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 8K monitor with DPI @ 300%
BarryG
Addict
Addict
Posts: 4300
Joined: Thu Apr 18, 2019 8:17 am

Re: Is there a #PB_Event_KeyDown ?

Post 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
Post Reply