0

I want to disallow the user of my application from using alt-tab. I'm trying to solve this by using a low level keyboard hook.

Setting it up works perfectly, the callback procedure is triggered when I press the key combination etc. The weird thing that happens is that I can alt-tab out of the application but then alt-tabbing is disabled, completely. I switch applications with the mouse and try alt-tabbing but nothing happens. I switch back to my application and alt-tab again and it switches the application, but only one step. When out of my application the alt-tab isn't working anymore.

I've tried different scenarios, first I thought it had something to do with the debugger in VS2010 but no, running it with out the debugger gives the same results.

Have I completely misunderstood this hook procedure, is it meant to only catch stuff happening when the application isn't in focus?

osman.hpp :

static HHOOK m_hhook;

static LRESULT CALLBACK lowLevelKeyboardProc( int key, WPARAM wParam, LPARAM lParam );

osman.cpp :

HHOOK OSMan::m_hhook;

/*
* pseudo init code
*/
void OSMan::init()
{
     m_hHook = SetWindowsHookEx( WH_KEYBOARD_LL, (HOOKPROC)lowLevelKeyboardProc, 0, 0 );
}

LRESULT CALLBACK OSMan::lowLevelKeyboardProc( int key, WPARAM wParam, LPARAM lParam )
{
    KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam;

    switch (key)
    {
    case HC_ACTION:
        {
           if (pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN)
                 return 1;

        }

    default:
         break;
    }
   return CallNextHookEx( m_hHook, key, wParam, lParam);
}

edit:

  • added code.
Alex
  • 197
  • 1
  • 11
  • 1
    Some code demonstrating how you are setting up your hook would be helpful. – Mike Kwan Feb 29 '12 at 09:55
  • @InS: whenever someone wants something this restrictive, they're often building a kiosk application where the user just wants to find out if a book is in stock or where in the store the rubber bands are stocked. – sarnold Feb 29 '12 at 10:03
  • 1
    @sarnold: The proper way to make something like a kiosk is to use operating system features like [group policies](http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19735) and separate administrator and "kiosk" user accounts. It takes less time to set up computer accounts with the proper permissions than trying to develop what's basically a software hack designed to cripple the operating system. – In silico Feb 29 '12 at 10:07
  • @ins: that'd be worth an up-vote as an answer. :) – sarnold Feb 29 '12 at 10:11
  • @sarnold: If the OP talked about kiosks, I would post an answer. :-) – In silico Feb 29 '12 at 10:12
  • We'll first of all I'm not the designer of the application. Second this is just a solution for a problem that we arn't really supporting, instead of wasting precious and expensive time to solve the real issue we are just disallowing alt-tabbing when running on unsupported software. – Alex Feb 29 '12 at 10:16
  • @Insilico: actually for some games this may be needed, I'm encountered more than a few recently that brick the system if you tab-alt (though that might be bad device management at play) – Necrolis Feb 29 '12 at 10:20
  • @Alex: Ouch. How does one manage to write an application so screwy that `alt-tab` needs to be disabled when it runs? – In silico Feb 29 '12 at 10:20
  • We'll since people are trying to run it on unsupported operating systems it isn't really an issue of screwy application and therefore this solution has been decided upon. – Alex Feb 29 '12 at 10:28
  • Why not just refuse to run on unsupported versions of the OS, if they're so unsupported? – Alexey Frunze Feb 29 '12 at 11:15
  • @Alex It is a decision made by my superiors and something I don't have a say in. But that would be my personal solution as well.. – Alex Feb 29 '12 at 11:24
  • It doesn't work properly because you are not checking for any errors. m_hHook will be zero if the posted code is accurate. – Hans Passant Feb 29 '12 at 13:22
  • There might be some spelling misstakes in hte code I've posted here. For example I've noticed myself that the uper & lower-case letters in m_hhook aren't correct everywhere. So no, the code I've posted here wont be correct straight out of the box. In my project I do have error code handling to catch any errors and the callbackfunction is being executed, breakpoints in it get triggered for example. – Alex Feb 29 '12 at 15:13

2 Answers2

1

You are installing a System Wide hook, that is why you have disabled the use of Alt-TAB on the whole system.

You can't use a WH_KEYBOARD_LL you must use a WH_KEYBOARD hook, and make it process specific.

The params of the SetWindowsHookEx will change if you make your hook process specific.

Here is an overview of the params :

dwThreadId [in] Type: DWORD

The identifier of the thread with which the hook procedure is to be associated.

If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.

PS : in reply to comment :

The hook only is installed after the process got one appropriate event. While hooking onto keyboard messages, you will have to send at least one keyboard message before the hook is installed.

Work Around

Maybe you want to work around this issue by using the ShowWindow function ? Here is the doc : http://www.pinvoke.net/default.aspx/user32.showwindow

cf : http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces

cf http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx and http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959(v=vs.85).aspx#wh_keyboardhook

squelos
  • 1,189
  • 6
  • 16
  • With `WH_KEYBOARD_LL` and a `0` as the last argument on `SetWindowsHookEx` would, what I understand, not cause the problems that I am experiencing. Because for some reason I am still able to `alt-tab` out of my application, but when my application isn't in focus `alt-tabbing` isn't working - that `alt-tabbing` isn't working outside the application isn't an issue.. its the `alt-tabbing` out of the application that is the issue! – Alex Feb 29 '12 at 10:33
  • So you are saying that you can alt tab out once, but then alt tab is completely disabled ? – squelos Feb 29 '12 at 10:52
  • Yes, that is what I am experiencing. But when I set focus to my application again I'm able to `alt-tab` once again and then its disabled again. So it seems like when my application is in focus my hook is disabled. – Alex Feb 29 '12 at 10:59
  • Check my edit, i think its because the hook is only installed after the first apprioriate event (in your case, after the first keystroke you send.). – squelos Feb 29 '12 at 11:03
  • No, since the hook isn't active at all when my application is in focus. Only when my application is out of focus is the hook getting triggered.. – Alex Feb 29 '12 at 11:46
  • Now I have tried using the `WH_KEYBOARD` instead of the `_LL`. Sorry to say it didn't solve it. As your links stated the `lParam` is where you detect if `alt` is pressed and the `wParam` is where you detect your key. So I checked if both these are true, the `KF_ALTDOWN` and `VK_TAB` but they are never true at the same time. Either one or the other is true or non of them but never both at the same time. Even when I hold `alt-tab`. – Alex Feb 29 '12 at 12:32
  • Yes, that is actually normal. You can use Spy++ (tools -> Spy++ in VS)(maybe another way to get to spy ++ if its not present in your VS) . Spy++ will allow you to see all the messages that are sent/received. You will probably notice that you get actually a few messages, for the desired Alt-tab. I cant test now, but i imagine you get WM_KEYDOWNs for the CTRL, then WM_KEYDOWNS for the ALT. And that will give result in an alt-tab :). You might have to work around this, and use the WinAPI's to keep your app focused ! – squelos Feb 29 '12 at 12:55
1

If you want to disable alt+tab correctly, you should just register the hotkey via RegisterHotKey(0,0,MOD_ALT,VK_TAB); and then handle (well, more ignore) the message that this generates, this allows you to make it application local, not worry about Windows hook chains and allows you to easily enable or disable it on the fly.

Although for a game, the idTech 4 input handling code has a vast array of the input gems.

Necrolis
  • 25,836
  • 3
  • 63
  • 101
  • I've already tried this route without any luck. The function itself returned false and when using the method `GetLastError()` I recived something like "The HotKeyId is already registered" or something in that direction. – Alex Feb 29 '12 at 10:37
  • @Alex: what happens if you unregister the old one? – Necrolis Feb 29 '12 at 12:05
  • That is the funny thing, there is no old one. I even tried to unregister it even if it wasn't existing. Just by doing the unregister call just before I did the register call. No difference. – Alex Feb 29 '12 at 12:31