How to register a hotkey in your program

Share your advanced PureBasic knowledge/code with the community.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

How to register a hotkey in your program

Post by Mistrel »

Here is an example for how to register hotkeys to use within your program. Thanks to Trond for his example from another thread.

I'm reposting this under Tricks 'n' Tips because I think my example is a bit clearer. I've also fixed a bug.

To unset a hotkey register it again with the same modifier.

Code: Select all

Procedure HotKey(Key, Modifiers)
  Static ID

  If RegisterHotKey_(0, ID, Modifiers, Key) = 0
    ProcedureReturn -1
  EndIf
  ID+1
  ProcedureReturn ID-1
EndProcedure

Msg.MSG

hk1=HotKey(#VK_A,#MOD_CONTROL)
hk2=HotKey(#VK_S,#MOD_CONTROL)
hk3=HotKey(#VK_D,#MOD_CONTROL)

Repeat
  GetMessage_(@Msg, 0, 0, 0)
  If MSG\message = #WM_HOTKEY
    Select MSG\wParam
    	Case hk1
    		Debug "Ctrl-A"
    	Case hk2
    		Debug "Ctrl-S"
    	Case hk3
    		Debug "Ctrl-D"
		EndSelect
  EndIf
ForEver
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: How to register a hotkey in your program

Post by PB »

And just a quick note from MSDN regarding the F12 key:
Windows NT4 and Windows 2000/XP: The F12 key is reserved for use
by the debugger at all times, so it should not be registered as a hot key.
Even when you are not debugging an application, F12 is reserved in case
a kernel-mode debugger or a just-in-time debugger is resident.
So always make sure you set the F12 key with Shift, Control or Alt to avoid
this potential problem. In fact, the RegisterHotKey API won't allow you to set
the F12 hotkey alone on those systems:

Code: Select all

If OpenWindow(0,0,0,0,0,"test")
  Debug RegisterHotKey_(WindowID(0),1,0,#VK_F12) ; Fails.
  Debug RegisterHotKey_(WindowID(0),2,#MOD_SHIFT|#MOD_CONTROL,#VK_F12) ; Works.
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Thanks, PB.

In retrospect Trond's "bug" is probably a better way to handle the hotkey IDs. Here is another example.

Code: Select all

Procedure SetHotKey(Key,Modifiers)
   Static ID
   If RegisterHotKey_(0,ID,Modifiers,Key)=0
     ProcedureReturn -1
   EndIf
   ID+1
   ProcedureReturn ID
EndProcedure

Procedure HotKeyMsg()
   msg.MSG
   GetMessage_(@msg,0,0,0)
   If msg\message=#WM_HOTKEY
      ProcedureReturn msg\wParam+1
   EndIf
EndProcedure

hk_ctrla=SetHotKey(#VK_A,#MOD_CONTROL)

If OpenConsole()
   EnableGraphicalConsole(1)

  Repeat
     HotKeyEvent=HotKeyMsg()
     If HotKeyEvent
        Select HotKeyEvent
           Case hk_ctrla
              PrintN("Ctrl-A")
        EndSelect
     EndIf

     Delay(20) ; Don't eat all the CPU time, we're on a multitask OS
  Until KeyPressed$=Chr(27) ; Wait until escape is pressed
EndIf
hardfalcon
User
User
Posts: 89
Joined: Fri Apr 29, 2005 3:03 pm
Location: Luxembourg
Contact:

Post by hardfalcon »

Nice code, certainly better than using GetKeyAsnycState_()... :D
"And God caused a deep sleep to fall upon Adam, and he slept: and he took one of his ribs, and closed up the flesh instead thereof; And the spare rib, which God had taken from man, made he a woman, and brought her unto the man"
Post Reply