Solved

Hooking

Posted on 1999-01-17
6
286 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
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…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

739 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