'[EasyHook, using a simple messagestream instead of using a real Hook, a bit easier but less events]

'Code/Example below is identical to the VB6 project.
'Code should be pasted into Usercontrol [EasyHookMe] and FORM1.

'For suggestions,
'E.B. Knoppert, ProFinance WOERDEN Netherlands
'ebknoppert@hotmail.com


'// Usercontrol

Option Explicit

Private Type POINTAPI

    x As Long
    y As Long

End Type

Private Type MSG

    hwnd    As Long
    message As Long
    wParam  As Long
    lParam  As Long
    time    As Long
    pt      As POINTAPI

End Type

Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (lpMsg As MSG) As Long
Private Declare Function GetMessage Lib "user32" Alias "GetMessageA" (lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long
Private Declare Function IsDialogMessage Lib "user32" Alias "IsDialogMessageA" (ByVal hDlg As Long, lpMsg As MSG) As Long
Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function TranslateMessage Lib "user32" (lpMsg As MSG) As Long

Private Const SW_HIDE = 0

Public Event WindowMessages(ByVal mhWnd As Long, wMsg As Long, wParam As Long, lParam As Long, ByVal wTime As Long)

Private Sub UserControl_Show()

    On Error Resume Next

    If Not Ambient.UserMode Then Exit Sub

    Dim a       As Long
    Dim hwnd    As Long
    Dim tMsg    As MSG
    Static Frm  As Form

    'Already in process?
    If Not Frm Is Nothing Then Exit Sub

    'Hide usercontrol.
    ShowWindow UserControl.hwnd, SW_HIDE

    'Set var to extender's parent (form)
    Set Frm = Extender.Parent

    'Test for form.
    If Frm Is Nothing Then Exit Sub

    'Modal?
    hwnd = Frm.hwnd

    'Retrieve messages and send them to the declared procedure
    Do While GetMessage(tMsg, ByVal 0&, 0, 0)

        'If form is unloaded, we need an exit of this loop.
        If IsWindow(hwnd) = 0 Then Exit Do

        'Send messages received.
        RaiseEvent WindowMessages(tMsg.hwnd, tMsg.message, tMsg.wParam, tMsg.lParam, tMsg.time)

        'Distinguish dialog messages.
        If IsDialogMessage(hwnd, tMsg) Then
        Else

            'Reply messagestream.
            TranslateMessage tMsg
            DispatchMessage tMsg

        End If

    Loop

End Sub

'// FORM1

Option Explicit

Private Sub EasyHookMe1_WindowMessages(ByVal mhWnd As Long, wMsg As Long, wParam As Long, lParam As Long, ByVal wTime As Long)

    On Error Resume Next

    Const HTBOTTOMRIGHT = 17
    Const HTCAPTION = 2
    Const HTMAXBUTTON = 9
    Const WM_KEYDOWN = &H100
    Const WM_NCLBUTTONDOWN = &HA1
    Const WM_LBUTTONDOWN = &H201
    'Const WM_LBUTTONUP = &H202

'    Debug.Print mhWnd & ", " & wMsg & " H" & Hex$(wMsg) & ", " & wParam & ", " & lParam & ", " & time & ", " & wTime

    'Here we determine on what message we want to do something.
    Select Case wMsg
    Case WM_KEYDOWN

        'Compare hWnd's
        Select Case mhWnd
        Case Me.Text1.hwnd

            'If Key was TAB, we like to validate input.
            'In this example we would like to know if the input was > 99.
            If wParam = vbKeyTab Then

                If Val(Me.Text1) > 99 Then

                    'OK, keep going...

                Else

                    'Abort message, TAB key is NOT processed!
                    'NO focus is set!
                    wParam = 0
                    Beep
                    MsgBox "Value must be more than 99", vbCritical

                End If

            End If

        End Select

    Case WM_NCLBUTTONDOWN

        'Process only the messages of this form.
        If mhWnd <> Me.hwnd Then Exit Sub

        'If we click the non-client area like the Caption of this form,
        'we can do something like showing a msgbox.

        Select Case wParam

        'Cancel maximizebutton if we click it.
        Case HTMAXBUTTON

            Beep
            wParam = 0

        'Caption was clicked, show a msgbox.
        Case HTCAPTION

            wParam = 0
            MsgBox time

        'Right+Bottom border was clicked, show a msgbox.
        Case HTBOTTOMRIGHT

            wParam = 0
            MsgBox "Right+Bottom border clicked."

        End Select

    Case WM_LBUTTONDOWN

        'Compare hWnd's
        Select Case mhWnd
        Case Me.Command1.hwnd

            Beep
            wMsg = 0

        Case Me.List1.hwnd

            'Cancel message when listindex is 1, mouse can not change listindex any longer.
            'Pretty useless but you'll figure it out how you can use this.
            If Me.List1.ListIndex = 1 Then

                Beep
                wMsg = 0

            End If

        End Select

    End Select

End Sub

Private Sub Form_Load()

    Dim a As Long
    Me.List1.Clear

    For a = 0 To 20

        Me.List1.AddItem Timer & Rnd()

    Next a

End Sub
