$TYPECHECK ON
$INCLUDE <RapidQ2.inc>

DECLARE Function KeyboardProc (ByVal idHook As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Declare Function CallNextHookEx Lib "user32" ALIAS "CallNextHookEx" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As LONG) As Long
'Declare Function GetAsyncKeyState Lib "user32" ALIAS "GetAsyncKeyState" (ByVal nVirtKey As Long) As Integer
Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (idHook As Long, lpfn As Long,  hmod As Long, dwThreadId As long) As Long
Declare Function UnhookWindowsHookEx Lib "user32" ALIAS "UnhookWindowsHookEx" (ByVal hHook As Long) As Long
Declare Function GetCurrentThreadId Lib "kernel32" Alias "GetCurrentThreadId"() As Long
Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (lpModuleName As Long) As Long


Type KBDLLHOOKSTRUCT
    vkCode As Long
    scanCode As Long
    flags As Long
    time As Long
    dwExtraInfo As Long
End Type

' Low-Level Keyboard Constants
$DEFINE  HC_ACTION 0&
$DEFINE  LLKHF_EXTENDED &H1
$DEFINE  LLKHF_INJECTED &H10
$DEFINE  LLKHF_ALTDOWN &H20
$DEFINE  LLKHF_UP &H80

' Virtual Keys
$DEFINE  VK_TAB &H9
$DEFINE  VK_CONTROL &H11
$DEFINE  VK_ESCAPE &H1B
$DEFINE  VK_DELETE &H2E
$DEFINE  VK_SHIFT  &H10


DECLARE SUB OnFormClose()
DECLARE SUB OnFormShow()

' * SetWindowsHook() codes
$DEFINE WH_MIN              (-1)
$DEFINE WH_MSGFILTER        (-1)
$DEFINE WH_JOURNALRECORD    0&
$DEFINE WH_JOURNALPLAYBACK  1&
$DEFINE WH_KEYBOARD         2&
$DEFINE WH_GETMESSAGE       3&
$DEFINE WH_CALLWNDPROC      4&
$DEFINE WH_CBT              5&
$DEFINE WH_SYSMSGFILTER     6&
$DEFINE WH_MOUSE            7&
$DEFINE WH_HARDWARE         8&
$DEFINE WH_DEBUG            9&
$DEFINE WH_SHELL           10&
$DEFINE WH_FOREGROUNDIDLE  11&
$DEFINE WH_CALLWNDPROCRET  12&
$DEFINE WH_MOUSE_LL        14&
$DEFINE WH_MAX             14&
$DEFINE  WH_KEYBOARD_LL    13&



    'set a keyboard hook
DEFINT hHook = SetWindowsHookEx(WH_KEYBOARD_LL, CODEPTR(KeyboardProc), GetModuleHandle(0&), 0&) 'WH_MOUSE 'WH_KEYBOARD
If hHook = 0 THEN Showmessage "failed": Application.Terminate

Function KeyboardProc(ByVal idHook As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    DIM Hookstruct As KBDLLHOOKSTRUCT
    If (idHook = HC_ACTION) Then
        ' Copy the keyboard data out of the lParam (which is a pointer)
        MEMCPY(Hookstruct, lParam, SIZEOF(Hookstruct))
        'here we hook the Alt-Tab key and block it
        If (Hookstruct.vkCode = VK_TAB) And ((Hookstruct.flags And LLKHF_ALTDOWN) <>0) Then
            RESULT = 1
            Exit Function
        End If
    End If
    KeyboardProc = CallNextHookEx(hHook, idHook, wParam, lParam)
End Function



CREATE Form1 AS QFORM
    OnClose = OnFormClose           'MUST do this!!!
    left = 120
    CREATE myEdit AS QEDIT
    Text = "here is some text"
    END CREATE
END CREATE

Form1.ShowModal



SUB OnFormClose()
    UnhookWindowsHookEx hHook           'remove the windows-hook
End Sub
  
