Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

System Wide Hooking 3

Status
Not open for further replies.

mattKnight

Programmer
May 10, 2002
6,225
GB
Hi all,

Its been a while since my last post!

I have a requirement to modify the default context menu (teh copy / paste / etc one). If this were for a single application, it would be relatively easy! i.e. follow the magic steps in the KB224302 that is trap the WM_CONTEXTMENU message and go from there.

How do I hook the system - I vaguely remember that you have to create a DLL, inject it (where?) but am now a bit lost

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
Here's a thread thread222-1379849 that takes all this up in detail, once it gets focused a bit. I have a long piece of code (much of it borrowed) near the bottom, and Hypetia makes some suggestions for improvement that aren't implemented.

HTH

Bob
 
No, Bob, that's not really what Matt is looking for; that just subclasses a specified window. Matt wants to hook into all message queues on a system-wide basis (a global hook) so that he can spot a WM_CONTEXTMENU message no matter where it originates.

Specifically, what he really needs to do is implement the WH_SYSMSGFILTER hook - but that needs to go in a classic DLL if it is to work ...
 
(and we covered how to make a classic DLL in VB in thread222-1293832)
 
Nice one strongm [smile]

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.
 
Bob - Thanks for the thread, as Strongm says I do need the system wide hook

Strongm - Now that I know which hook to look at I can do some more research on that specific line. I had forgotten about making classic DLLs in VB - thanks for the reminder!


Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
Ok, I see the difference now. But, you can't use CBT hooking for this?
 
All right, I believe I'm caught up now. The code I sent along only captures the context menu for a given window.
 
Hi all...

I've been playing with this a bit over the weekend, but i've struck a major problem...

The DLLMain Entry Point doesn't execute!
Code:
Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String)

Public hInstance As Long
Public hHook As Long

Public Const WH_SYSMSGFILTER = 6
Public Const DLL_PROCESS_ATTACH = 1
Public Const DLL_THREAD_ATTACH = 2
Public Const DLL_THREAD_DETACH = 3
Public Const DLL_PROCESS_DETACH = 0


Code:
Public Function DllMain(hInst As Long, fdwReason As Long, lpvReserved As Long) As Boolean
' This entry point doesn't run
hInstance = hInst

Select Case fdwReason
    Case DLL_PROCESS_ATTACH
        OutputDebugString ("DllMain:DLL_PROCESS_ATTACH")
    Case DLL_THREAD_ATTACH
        OutputDebugString ("DllMain:DLL_THREAD_ATTACH")
    Case DLL_THREAD_DETACH
        OutputDebugString ("DllMain:DLL_THREAD_DETACH")
    Case DLL_PROCESS_DETACH
        OutputDebugString ("DllMain:DLL_PROCESS_DETACH")
End Select
 
 
 DllMain = True
End Function


Public Function InstallFilterDLL() As Long
'Install our hook
OutputDebugString ("Installing Hook")
OutputDebugString ("hInstance = " & hInstance)
hHook = SetWindowsHookEx(WH_SYSMSGFILTER, AddressOf SysMsgProc, hInstance, 0)
OutputDebugString ("hHook = " & hHook)
InstallFilterDLL = hHook
End Function

Public Function UnInstallFilterDLL() As Long
'uninstall hook
OutputDebugString ("hHook = " & hHook)
UnInstallFilterDLL = UnhookWindowsHookEx(hHook)
End Function

Public Function SysMsgProc(ByVal uCode As Long, ByVal wParam As Long, ByVal lParam As Long)
'Don't try to do too much at the moment
OutputDebugString ("Hook")
SysMsgProc = CallNextHookEx(hHook, uCode, wParam, lParam)
End Function

Code:
NAME GlobalHook
LIBRARY GlobalHook
DESCRIPTION "Example of classic DLL"
EXPORTS DllMain @1
	InstallFilterDLL @2
	UnInstallFilterDLL @3

Code:
Public Declare Function InstallFilterDLL Lib "C:\Projects\Systemwide hook\VBMainhook\globHook.dll" () As Long

Public Declare Function UnInstallFilterDLL Lib "C:\Projects\Systemwide hook\VBMainhook\globHook.dll" () As Long

Public Sub Install()
Dim lRetVal As Long
lRetVal = InstallFilterDLL()

If lRetVal <> 0 Then
    sysform1.Caption = "SYSMSGHook Installed: " & Hex(lRetVal) & " " & sysform1.Text1.hWnd
Else
    sysform1.Caption = "Error installing hook"
End If
End Sub
Public Sub Uninstall()
Dim lRetVal As Long
lRetVal = UnInstallFilterDLL()

If lRetVal = 1 Then
    sysform1.Caption = "No hooks installed " & sysform1.Text1.hWnd
Else
    sysform1.Caption = "Error installing hook"
End If

End Sub

I've based the VB dll on strongm's code in thread222-1293832
and all of that seems to work ok...

Any thougts

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
Duely Considering ;-)

Can you suggest why with the current code, when the buttons are clicked the code executes i.e. the hook tries to set (but fails as the hInstance is still 0) That suggests that the DLL is loaded (and I've only every had to LoadLibrary when i've been using resource dlls)

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
As I recall DllMain is only actually called under certain specific circumstances (and one of those is if LoadLibrary is used to load the DLL)
 
So it says!

However, the DllMain function still doesn't execute

I've tried with DLL written in C++ and the DLLMain fucntion does execute!

So it may be that the VB Dll isn't quite right...

As soon as I have some time I'll investigate and pass back information

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
Hmmm. To be honest I've never worried about DllMain, never had a requirement to do anything in it, so I'm not sure what might be wrong.

I guess, given you are using it to get the hInstance, that a you've tried app.hInstance instead?
 
And I think I have found a solution, thanks to some comments added to the source article I originally referred to

1) Looks like the parameters to DLLMain all have to be ByVal
2) Return needs to be a Long (not a boolean; should have picked that up)
3) Need to add one more line to the shim:
Immediately after
[tt]strCommand = Replace(strCommand, "/DLL", "/DEF:" & Chr(34) & strFolder & "\" & strDef & Chr(34) & " /DLL")[/tt]
add
[tt]strCommand = Replace(strCommand, "/ENTRY:__vbaS", "/ENTRY:DllMain")[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top