Posted on 1999-01-17
Medium Priority
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?
Question by:ViperX

Expert Comment

ID: 1469070
Do you want to hook your own form, or another app's window?

Expert Comment

ID: 1469071
maybe you want to subclass it. Read an example of AddressOf VB operator.

Expert Comment

ID: 1469072
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

LVL 10

Expert Comment

ID: 1469073
You should use SetWindowsHookEx() and UnhookWindowsEx()

Accepted Solution

VBDesigns earned 100 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)
        oControlClass.Name = pvItem
        mcolHookedhWnds.Add oControlClass, CStr(pvItem)
    End If
    Debug.Print "Hook hWnd " + CStr(plhWnd)
    HookhWnd = True

    Exit Function

    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)
        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
    Exit Function
    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
    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!

                 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
    Exit Function
    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


Expert Comment

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

then you just do this when you form unloads

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


Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
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…

597 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