Page 1 of 1

How to register a hotkey in your program

Posted: Sat Nov 24, 2007 7:17 am
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

Re: How to register a hotkey in your program

Posted: Sat Nov 24, 2007 7:28 am
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

Posted: Sat Nov 24, 2007 7:40 am
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

Posted: Sat Nov 24, 2007 10:26 pm
by hardfalcon
Nice code, certainly better than using GetKeyAsnycState_()... :D