How do I take control of keyboard vol up, down and mute?

Windows specific forum
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

How do I take control of keyboard vol up, down and mute?

Post by ozzie »

I want to intercept the keyboard volume up, down and mute keys so that I can apply the effect directly in my program, which is particularly important for ASIO audio outputs. I can intercept these keys using a window callback, but I don't seem to be able to force Windows to subsequently ignore the action, even by returning 0 in the callback procedure. I need to be able to do this to avoid both my program and Windows applying volume up/down, which could double the effect (eg when using the default sound device). How can I tell Windows to ignore the volume up, down and mute keys?

Here's my test program:

Code: Select all

Procedure WinCallback(hWnd, uMsg, WParam, LParam) 
  Select uMsg
    Case #WM_KEYDOWN
      Debug "$" + Hex(uMsg) + ", #WM_KEYDOWN (" + #WM_KEYDOWN + "), VK=$" + Hex(wparam) + ", lparam=$" + Hex(lparam) + ", prev_key_state=" + Str((lparam & $40000000) >> 30)
      ProcedureReturn 0
    Case #WM_KEYUP
      Debug "$" + Hex(uMsg) + ", #WM_KEYUP (" + #WM_KEYUP + "), VK=$" + Hex(wparam) + ", lparam=$" + Hex(lparam)
      ProcedureReturn 0
    Case #WM_SYSKEYDOWN
      Debug "$" + Hex(uMsg) + ", #WM_SYSKEYDOWN, VK=$" + Hex(wparam) + ", lparam=$" + Hex(lparam) + ", prev_key_state=" + Str((lparam & $40000000) >> 30)
      ProcedureReturn 0
    Case #WM_SYSKEYUP
      Debug "$" + Hex(uMsg) + ", #WM_SYSKEYUP, VK=$" + Hex(wparam) + ", lparam=$" + Hex(lparam)
      ProcedureReturn 0
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure

If OpenWindow(0, 50, 50, 400, 200, "Window Callback Test", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  SetWindowCallback(@WinCallback(),0)
  Repeat 
    Select WaitWindowEvent() 
      Case #PB_Event_CloseWindow 
        End 
    EndSelect 
  ForEver 
EndIf
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: How do I take control of keyboard vol up, down and mute?

Post by RSBasic »

Image
Image
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: How do I take control of keyboard vol up, down and mute?

Post by RASHAD »

Try

Code: Select all

;*********************************************************
;Mute - Unmute
;*********************************************************
; keybd_event_(#VK_VOLUME_MUTE,0,0,0)
; keybd_event_(#VK_VOLUME_MUTE,0,#KEYEVENTF_KEYUP,0)
;*********************************************************
;Volume Up
;*********************************************************
; keybd_event_(#VK_VOLUME_UP,0,0,0)
; keybd_event_(#VK_VOLUME_UP,0,#KEYEVENTF_KEYUP,0)
;*********************************************************
;Volume Down
;*********************************************************
; keybd_event_(#VK_VOLUME_DOWN,0,0,0)
; keybd_event_(#VK_VOLUME_DOWN,0,#KEYEVENTF_KEYUP,0)
;*********************************************************
; MEDIA_PLAY_PAUSE
;*********************************************************
; keybd_event_(#VK_MEDIA_PLAY_PAUSE,0,0,0)
; keybd_event_(#VK_MEDIA_PLAY_PAUSE,0,#KEYEVENTF_KEYUP,0)
;*********************************************************
;Volume Stop
;*********************************************************
; keybd_event_(#VK_MEDIA_STOP,0,0,0)
; keybd_event_(#VK_MEDIA_STOP,0,#KEYEVENTF_KEYUP,0)
Or

Code: Select all

EnableExplicit

#VK_MEDIA_PREV_TRACK = $B1
#VK_MEDIA_NEXT_TRACK = $B0
#VK_MEDIA_PLAY_PAUSE = $B3
#VK_MEDIA_STOP = $B2
#VK_VOLUME_UP = $AF
#VK_VOLUME_DOWN = $AE
#VK_VOLUME_MUTE = $AD

Procedure SetAsyncKeyState_(Key)
  Protected KeyStroke.INPUT
  KeyStroke\type = 1
  KeyStroke\ki\wVk = Key
  KeyStroke\ki\wScan = 0
  KeyStroke\ki\dwFlags = 0
  KeyStroke\ki\time = 0
  KeyStroke\ki\dwExtraInfo = 0
  ProcedureReturn SendInput_(1, @KeyStroke, SizeOf(INPUT))
EndProcedure

;SetAsyncKeyState_(#VK_MEDIA_PREV_TRACK)
;SetAsyncKeyState_(#VK_MEDIA_NEXT_TRACK)
;SetAsyncKeyState_(#VK_MEDIA_PLAY_PAUSE)
;SetAsyncKeyState_(#VK_MEDIA_STOP)
SetAsyncKeyState_(#VK_VOLUME_UP)
;SetAsyncKeyState_(#VK_VOLUME_DOWN)
;SetAsyncKeyState_(#VK_VOLUME_MUTE)
Egypt my love
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: How do I take control of keyboard vol up, down and mute?

Post by ozzie »

Many thanks for the quick replies!

RASHAD: it seems your code is for having my program send these keystrokes, not ignore them. But thanks, anyway.

RSBasic: That does the job! Here's my version of the code, compiled and tested using PB 5.70 (I had to remove Structure KBDLLHOOKSTRUCT as PB already has the structure defined):

Code: Select all

EnableExplicit

Procedure.l KeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
  If wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN
    If *p\vkCode = $AE
      Debug "volume down"
      ProcedureReturn 1
    ElseIf *p\vkCode = $AF
      Debug "volume up"
      ProcedureReturn 1
    ElseIf *p\vkCode = $AD
      ; "volume mute", but ignore on key down due to keyboard auto-repeat
      ProcedureReturn 1
    EndIf
  ElseIf wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP
    If *p\vkCode = $AD
      Debug "volume mute"
      ProcedureReturn 1
    EndIf
  EndIf
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p)
EndProcedure

If OpenWindow(0,0,0,500,250,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  TextGadget(1,10,10,200,20,"Taste ''A'' wird gesperrt.",0)
  StringGadget(2,10,30,200,20,"",0)
  
  SetWindowsHookEx_(#WH_KEYBOARD_LL,@KeyboardHook(),GetModuleHandle_(0),0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Post Reply