CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7

Hybrid View

  1. #1
    Join Date
    Mar 2014
    Posts
    4

    Blocking Keyboard Play/Pause Button in Win 8

    I am writing an application that needs to temporarily disable the Play/Pause button that appears on multimedia keyboards.

    Normally, a key can be blocked quite easily by installing a low level keyboard hook (WH_KEYBOARD_LL) where the KeyboardProc intercepts the key (in this case VK_MEDIA_PLAY_PAUSE) and returns a "1" instead of calling CallNextHookEx. I have tried this with other keys (including the Windows key VK_LWIN) and this works perfectly. I also have no problems with this method under Windows 7 where all keys, including VK_MEDIA_PLAY_PAUSE get blocked.

    Windows 8 is a different story. When my application has input focus, everything works as expected, meaning the VK_MEDIA_PLAY_PAUSE key gets blocked and no other application responds to it. However, when my application loses focus, my hook procedure gets called (this was verified by sending out a OutputDebugString) but other applications respond to key even though I return a "1". As soon as my app gets focus again, everything is block as it should.

    After some investigation, I found that the multimedia keys not only generate keystrokes but also generate WM_APPCOMMAND messages so I added ShellProc (WH_SHELL) hook with the following hook procedure:

    LRESULT __declspec(dllexport)__stdcall CALLBACK ShellProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
    // Do we have to handle this message?
    if (nCode == HSHELL_APPCOMMAND)
    {
    OutputDebugStringX(">>>>> HSHELL_APPCOMMAND");
    // Process the hook if the hNotifyWnd window handle is valid
    short AppCommand = GET_APPCOMMAND_LPARAM(lParam);
    switch (AppCommand)
    {
    case APPCOMMAND_MEDIA_NEXTTRACK:
    case APPCOMMAND_MEDIA_PLAY_PAUSE:
    case APPCOMMAND_MEDIA_PREVIOUSTRACK:
    case APPCOMMAND_MEDIA_STOP:
    OutputDebugString(">>>>>ShellProc got a media command");
    return 1;

    }
    }

    // Call the next handler in the chain
    return CallNextHookEx (hsh, nCode, wParam, lParam);
    }

    This procedure is only getting called when my app has input focus. Whenever I have input focus and return "1" the Play/Pause command gets blocked. As soon as I lose focus the procedure does not get called/hooked.

    Anyone have any idea as to what is going on? As I have mentioned, the code works for other keys, just not the multimedia keys.

    Alternatively, can anyone suggest another way of blocking the multimedia keyboards Play/Pause button?

    Lisa

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Blocking Keyboard Play/Pause Button in Win 8

    WH_KEYBOARD_LL is a special case of a hook which services keys that originated and are intended for another process.
    This is quite exceptional and it was added to make creating disability apps easier.

    THe ShellProc only services shell hooks that originate in and are intended for your own process.

    If you need to trap shell commands in another process, you'll need to get your code injected into that other process' memoryspace, and install the hook in that other process.

  3. #3
    Join Date
    Mar 2014
    Posts
    4

    Re: Blocking Keyboard Play/Pause Button in Win 8

    Thanks for your response.

    The strange thing about the keyboard hook is that is always being called but only blocks the keystroke when my application has focus. This problem only occurs with the multimedia keys. If I replace the hook for VK_MEDIA_PLAY_PAUSE with VK_LWIN the left Windows Key gets block regardless of whether my application has focus or not. VK_MEDIA_PLAY_PAUSE only gets block if my application has focus.

    The ShellProc code that I had posted above resides in a separate DLL and the hook is installed using the following code:

    hsh=SetWindowsHookEx(WH_SHELL,(HOOKPROC)ShellProc,hins,0);

    Since the ThreadID is "0" this code should be injected in all the existing threads running in the same desktop but for some reason it is not being called when my app does not have input focus. Shouldn't this code be called all the time?

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Blocking Keyboard Play/Pause Button in Win 8

    Quote Originally Posted by BunnyF View Post
    hsh=SetWindowsHookEx(WH_SHELL,(HOOKPROC)ShellProc,hins,0);

    Since the ThreadID is "0" this code should be injected in all the existing threads running in the same desktop but for some reason it is not being called when my app does not have input focus. Shouldn't this code be called all the time?
    Yes, but the above assumes that the bitness of your code and dll are the same as the bitness of the app being injected to.

    I'm goign to assume you made a Win32 app, but the other app is Win64. So your hook never gets installed.

    This is the main reason for the existance of the _LL version of hooks, it means disability apps don't need to worry about bitness. But the _LL versions of hooks do have their disadvantages also. If you want to suppress keys, then the _LL hooks aren't ideal because you can override them, which is probably what's happening here for the media keys.

  5. #5
    Join Date
    Mar 2014
    Posts
    4

    Re: Blocking Keyboard Play/Pause Button in Win 8

    In my case, I am running a 32-bit application, the other app is also 32-bit but the OS is 64-bit.

    The interesting thing is that everything works fine (i.e. the hook gets called and I am able to block the command) when my application is the foreground window and the hook does not get called at all when my application is not the foreground window.

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Blocking Keyboard Play/Pause Button in Win 8

    You may find this article and its links of interest.
    http://stackoverflow.com/questions/7...-message-queue
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Mar 2014
    Posts
    4

    Re: Blocking Keyboard Play/Pause Button in Win 8

    Thanks for the link. I have read through all of the postings and it does not address my questions.

    As I had said earlier in my message, my hooking procedure works perfectly for most keys with the exception of the multimedia keys. What is different about the multimedia keys, such as VK_MEDIA_PLAY_PAUSE, that they behave differently?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured