Solved

Hooking

Posted on 1999-01-17
6
279 Views
Last Modified: 2010-05-03
How would I be able to hook a window to recieve its messages without having to buy and expencive control?
0
Comment
Question by:ViperX
6 Comments
 
LVL 8

Expert Comment

by:MikeP090797
ID: 1469070
Do you want to hook your own form, or another app's window?
0
 
LVL 2

Expert Comment

by:polygon
ID: 1469071
maybe you want to subclass it. Read an example of AddressOf VB operator.
0
 
LVL 4

Expert Comment

by:mcix
ID: 1469072
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 10

Expert Comment

by:viktornet
ID: 1469073
You should use SetWindowsHookEx() and UnhookWindowsEx()
0
 
LVL 2

Accepted Solution

by:
VBDesigns earned 50 total points
ID: 1469074
Here's Sample code on how to do it.  It's pretty basic -- call the hookhWnd function with a 'name':

HookhWnd frmMain.hWnd, "MAIN"

And then when the program exists, unhook it with:

UnhookhWnd frmMain.hWnd, "MAIN"

You'll want to do your manipulating in the WindowProc procedure.  Yes, the code can be cleaned up a bit, but it's what I had laying around.  Good luck!

Public Function HookhWnd(plhWnd As Long, Optional pvItem As Variant) As Long
    Static bNoHook As Boolean
   
    Dim oControlClass As New clsControlClass
    Dim mlAddress As Long
   
    ' Create the hook!
    mlAddress = SetWindowLong(plhWnd, GWL_WNDPROC, AddressOf WindowProc)
   
    oControlClass.hWnd = plhWnd
    oControlClass.SubClassAddress = mlAddress
   
    If IsMissing(pvItem) Then
        oControlClass.Name = CStr(plhWnd)
        mcolHookedhWnds.Add oControlClass, CStr(plhWnd)
    Else
        oControlClass.Name = pvItem
        mcolHookedhWnds.Add oControlClass, CStr(pvItem)
    End If
   
    Debug.Print "Hook hWnd " + CStr(plhWnd)
   
    HookhWnd = True

ErrorHookhWndResume:
    Exit Function

ErrorHookhWnd:
    MsgBox "Error '" + Err.Description + "' occurred in (" _
     + App.Title + ")modMessages:HookhWnd!"
    Resume ErrorHookhWndResume
End Function


Public Function UnhookhWnd(plhWnd As Long, Optional pvItem As Variant) As Long
    ' If they aren't in run mode, exit.
    ' UnHook the passed control!
    Dim sString As String
   
    On Error GoTo ErrorUnhookhWnd
   
    If IsMissing(pvItem) Then
        sString = CStr(plhWnd)
    Else
        sString = CStr(pvItem)
    End If
   
    If mcolHookedhWnds.Count > 0 Then
        If mcolHookedhWnds.Item(sString).SubClassAddress > 0 Then
            UnhookhWnd = SetWindowLong(mcolHookedhWnds.Item(sString).hWnd, _
             GWL_WNDPROC, mcolHookedhWnds.Item(sString).SubClassAddress)
            mcolHookedhWnds.Item(sString).SubClassAddress = 0
            Debug.Print "Unhook hWnd " + sString
            mcolHookedhWnds.Remove sString
        End If
    End If
   
ErrorUnhookhWndResume:
    Exit Function
   
ErrorUnhookhWnd:
    MsgBox "Error '" + Err.Description + "' occurred in (" _
     + App.Title + ")modMessages:UnhookhWnd!"
    Resume ErrorUnhookhWndResume
End Function

Public Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    ' Call the normal window proc for the control!
   
    Dim lTemp As Long
    Dim bEat As Boolean
    Dim sControlName As String
    Dim oClass As clsControlClass
    Dim iLoop As Integer
    Dim lResult As Long
   
    Static bError As Boolean
   
    On Error GoTo ErrorWindowProc
   
    If bError Then Exit Function
   
    For Each oClass In mcolHookedhWnds
        If oClass.hWnd = hw Then
            sControlName = oClass.Name
            Exit For
        End If
    Next
   
    If sControlName = "" Then Exit Function
   
    ' What type of message was sent?
    Select Case UCase(sControlName)
        Case "MAIN"
            Select Case uMsg
                Case WM_TIMECHANGE
                    ' Time has changed!  Update character information!
                bEat=True

                 Case Else
            End Select
   
        Case Else
       
    End Select
   
    ' Eat the message?  If not, pass it on!
    If Not bEat Then
        lResult = CallWindowProc(mcolHookedhWnds.Item(sControlName).SubClassAddress, _
         hw, uMsg, wParam, lParam)
    End If
   
ErrorWindowProcResume:
    Exit Function
   
ErrorWindowProc:
    iwcharEMessage "Error '" + Err.Description + "' occurred in (" + App.Title _
     + ")modMessages:WindowProc!"
    bError = True
    Resume ErrorWindowProcResume
End Function

Here's the Control Class (clsControlClass) code: (priavate single-use instancing)

Option Explicit

Dim mlhWnd As Long
Dim mlSubClassAddress As Long
Dim mlOptions As Long
Dim msName As String
Public Property Get hWnd() As Long
    hWnd = mlhWnd
End Property

Public Property Let hWnd(ByVal plhWnd As Long)
    mlhWnd = plhWnd
End Property

Public Property Get SubClassAddress() As Long
    SubClassAddress = mlSubClassAddress
End Property

Public Property Let SubClassAddress(ByVal plSubClassAddress As Long)
    mlSubClassAddress = plSubClassAddress
End Property

Public Property Get Options() As Long
    Options = mlOptions
End Property

Public Property Let Options(ByVal plOptions As Long)
    mlOptions = plOptions
End Property

Public Property Get Name() As String
    Name = msName
End Property

Public Property Let Name(ByVal psValue As String)
    msName = psValue
End Property





0
 
LVL 1

Expert Comment

by:Johnn
ID: 1469075
email me if you'd like to get my CHOOK dll.  This subclasser hooks every message.  You only need to filter out the ones you want vs. setting the messages you want then filtering thoses ones for each.

here's an example:
dim myHook as new CHook

set myHook=new CHook
myHook.hWnd=yourwindow.hWnd

then you just do this when you form unloads

myHook.hWnd=0
set myHook=nothing

You don't even have form requirement.  So in otherwords if you were building an activex dll you don't nessecarily have to have a form in it to use a subclassing control

jnickle@shaw.wave.ca
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now