No announcement yet.

Capturing Special Keystrokes

  • Filter
  • Time
  • Show
Clear All
new posts

    Capturing Special Keystrokes

    Good evening, everyone.

    I have a strange one for all you clever programmers out there. I'm developing an application to teach new computer users how to type. Naturally, it will endeavor to teach everything from letters to complicated key combinations, like Control+Escape, Alt+Tab and Alt+Control+Delete. I am, however, unable to find out when these key combinations are typed using the standard GetMessage function, of course, much less stop them from firing up the start menu or switching away from my application. Another headache is programs that define hotkeys in their links. If a program puts its link on the desktop and makes a shortcut key to launch it, I am unable to capture this either.

    I believe my solution is the "CBT Hook". It is designed for computer-based training applications, sounds good since that's what mine is, to capture and optionally disallow keystrokes. Or so I thought. Try as I might, I can't seem to get it to do anything but crash, let alone actually do something useful. I know it's highly unlikely, but I thought perhaps one of you might have done this already? I've spent the evening poring over reference materials such as the Win32 Programmer's reference, but I still can't get anything to work.

    Thus, if anyone has any ideas on how to capture a couple of tricky little keystrokes and prevent Windows from acting on them, I'd love to hear about it.

    Thank you!


    you should be able to trap most keystrokes with a wm_keyboard hook. you can do this in an exe for a local hook, but if you want a global trap you'll need to implement it in a dll (so it can be 'attached' to every process that needs it). that said, i think there are certain key combinations that a wh_keyboard hook cannot catch - however, i've not played with hooks that much, compared to say, semen and wyman.

    anyway, search the bbs for "wh_keyboard" and you should find some examples of keypress trapping. for example,

    powerbasic support
    mailto:[email protected][email protected]</a>
    mailto:[email protected]


      Hi Lance:

      Thank you for your response. I really appreciate you working with me on this!

      The WH_KEYBOARD hook doesn't seem to do much more than the GetMessage loop I'm using now. It seems to be good about capturing keypresses, as well as keeping Windows from receiving them, provided that the key in question isn't a special key. It seems to act a lot like GetMessage, however, when the key in question is something like Control+Escape or an application's hotkey, it never seems to receive the keystroke. Thanks to the article you pointed me to, I've been able to put together a quick test program though, that uses the WH_Keyboard hook. I just added a Function=1 statement at the end of the keyboard hook function to refuse to pass as many keys as I can. Incidentally, I tried this in a DLL and it was able to keep everything from letters to arrows from Windows receiving them anywhere. I was typing away in NotePad and nothing showed up except in my dialog! It still wouldn't capture special keystrokes like Control+Escape and Alt+Tab though. Any ideas?

      Here's what I've done so far:

      GLOBAL hWnd&, hHook AS LONG, hInstance AS LONG,_
      Temp AS STRING, ExKey AS STRING, KeyBuffer AS STRING


      DIM Dummy AS LONG
      DIM hForegroundWindow AS LONG

      'Prevent any Threads from reentering:
      Dummy = DisableThreadLibraryCalls&(hInstance)
      'Install My Hook Procedure:
      hHook = SetWindowsHookEx&(%WH_KEYBOARD, CODEPTR(KeyBoardHookFunction), hInstance, 0&)

      DIALOG NEW 0,"Keyboard Hook Test",,,300,400 TO hWnd&
      CONTROL ADD TEXTBOX, hWnd&, 101, "Hit a Key", 10, 15, 240, 370, %ES_READONLY OR %ES_MULTILINE OR %WS_TABSTOP
      CONTROL ADD BUTTON, hWnd&, 102, "E&xit", 260, 15, 30, 370

      hHook = UnhookWindowsHookEx(hHook)

      FUNCTION KeyBoardHookFunction(BYVAL HookCode AS LONG, BYVAL wParam AS LONG,_

      IF BIT(lParam, 30)=0 THEN 'Only Grab the KeyDown
      ExKey="": Temp=""
      IF wParam=%VK_RETURN THEN Temp="<Enter>"
      IF wParam=%VK_ESCAPE THEN Temp="<Escape>"
      IF wParam=%VK_TAB THEN Temp="<Tab>"
      IF wParam>31 THEN Temp=CHR$(wParam)

      IF ISTRUE(LOWRD(GetKeyState(%VK_MENU)) AND &H8000) THEN ExKey="Alt+"
      IF ISTRUE(LOWRD(GetKeyState(%VK_CONTROL)) AND &H8000) THEN ExKey=ExKey & "Control+"
      IF ISTRUE(LOWRD(GetKeyState(%VK_SHIFT)) AND &H8000) THEN ExKey=ExKey & "Shift+"
      IF wParam>64 AND wParam<91 THEN
      IF ExKey="" THEN Temp=LCASE$(Temp)
      IF ExKey="Shift+" THEN ExKey=""
      End If
      IF Temp<>"" THEN KeyBuffer=KeyBuffer & ExKey & Temp
      CONTROL SET TEXT hWnd&, 101, KeyBuffer
      END IF
      FUNCTION=1 'Don't Pass Key


      Thanks again!




        I was in a similar situation in that my customers use a keyboard
        as one would a control panel and therefore I need complete control
        of the keyboard. Fortunatly EzGui 2.0 gives you that. Check it
        out at You'll find that you'll be a lot more
        productive with the combination of PBDLL & Ezgui.

        Best Regards,
        Russ Srole

        "There are two novels that can change a bookish fourteen-year old's life: The Lord of the Rings and Atlas Shrugged. One is a childish fantasy that often engenders a lifelong obsession with its unbelievable heroes, leading to an emotionally stunted, socially crippled adulthood, unable to deal with the real world. The other, of course, involves orcs." - John Rogers


          Hi Russ:

          Thanks for the note. I'm checking EZGUI out, it does indeed look promising.

          If anyone has any ideas how I might do it myself so I could learn how it's done, that would be great. Otherwise, this product will definitely get the job done.

          Thanks for your help, Everyone!




            Danny --
            (not far from the end)

            Q. If I install this hook, are all the keyboard messages captured? Like: CTRL-ALT-DEL, CTRL-ESC, ALT-TAB, etc.

            A. A normal keyboard hook (WH_KEYBOARD) can swallow keystrokes by returning TRUE in the hook procedure. However, this will not work for system keyboard events such as
            the ones you listed. For Windows NT version4.0 Service Pack 3 and later, you can install a low-level keyboard hook (WH_KEYBOARD_LL) that can detect these system
            keyboard events and eat all of them, except for CTRL+ALT+DEL. This exception is for security reasons.

            Having said that, there are some ways to get around that exception, although Dr. GUI doesn't recommend it. In Windows NT, you can write a GINA (Graphical Identification 'N'
            Authentication) DLL to handle the security exception. (Do a full-text search on "GINA" in Online Help to learn all about it.) Dr. GUI's preference is to leave system keys such as
            CTRL+ALT+DEL alone.

            In Windows 95/98 you can write a filter device driver. There is also a trick for Windows 95/98 that is described in the Microsoft Knowledge Base article Q154868, "HOWTO:
            Block CTRL+ALT+DEL and ALT+TAB in Windows 95/98 in VB," located at You can make a call to
            SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, lpvoid, 0) in order to disable the system keyboard events, including CTRL+ALT+DEL. Calling it again with the
            TRUE changed to FALSE will re-enable these key sequences.

            [This message has been edited by Semen Matusovski (edited June 02, 2001).]


              Hi Semen:
              Thank you so much for your message.
              This is the tip I've been waiting for, I'm off to check it out!