|
-
May 27th, 2002, 01:24 AM
#1
Thread Starter
Member
hooking windows - please help! *resolved*
I've tried to create a hooking-dll in VC++ for VB use.
The dll should hook the MouseProc of every window of a certain thread. For testing purpose the dll is writing the hwnd of the Mousevent to the titlebar of my form every time the MouseProc fires. As long as I'm trying to hook VB-windows only, everything is fine. As soon as I'm trying to hook other windows (TaskBar e.g.), nothing works.
Here is my VC++code:
code:--------------------------------------------------------------------------------
--- in the Hook.cpp ------
#include <iostream>
#include <windows.h>
HHOOK hHook;
HWND hWndSend;
HINSTANCE hDll;
void __stdcall StartHook(HWND hWndHook, HWND _hWndSend) {
hWndSend = _hWndSend;
hDll = LoadLibrary("Hook.dll");
DWORD ThreadID = GetWindowThreadProcessId(hWndHook,NULL);
HOOKPROC hProc = (HOOKPROC) GetProcAddress(hDll, "MouseProc");
hHook = SetWindowsHookEx(WH_MOUSE, hProc, hDll, ThreadID);
char str[100];
sprintf(str, "%d", hHook);
SetWindowText(hWndSend, str);
}
void __stdcall StopHook(void) {
UnhookWindowsHookEx(hHook);
FreeLibrary(hDll);
}
LRESULT __stdcall CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION)
{
MOUSEHOOKSTRUCT mhs;
memcpy(&mhs, (void*)lParam, sizeof(MOUSEHOOKSTRUCT));
char str[100];
sprintf( str, "%d", mhs.hwnd);
SetWindowText(hWndSend,str);
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
--- in the Hook.def ------
LIBRARY "hook.dll"
EXPORTS
StartHook
StopHook
MouseProc
--------------------------------------------------------------------------------
The vb-Project looks like this:
code:--------------------------------------------------------------------------------
Private Declare Sub StartHook Lib "Hook.dll" (ByVal hWndHook As Long, ByVal hWndSend As Long)
Private Declare Sub StopHook Lib "Hook.dll" ()
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Sub Command1_Click()
Dim hWndHook As Long
hWndHook = FindWindow("Shell_TrayWnd", vbNullString)
StartHook hWndHook, Me.hWnd
End Sub
Private Sub Form_Unload(Cancel As Integer)
StopHook
End Sub
--------------------------------------------------------------------------------
This doesn't work at all. When I'm putting hWndHook to Me.hwnd, it works perfectly.
Any ideas?
Thanks, Quixx.
Last edited by Quix; May 29th, 2002 at 12:47 PM.
-
May 27th, 2002, 04:21 AM
#2
Frenzied Member
When calling SetWindowsHookEx
VB Code:
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
you need to specify the hMod for a global hook OR the dwThreadId for a process local hook. Because you are passing both the hook type is defaulting to a local hook so you can only hook the current process - which is VB.
Try passing NULL for dwThreadId.
Hope this helps,
Duncan
-
May 28th, 2002, 02:23 AM
#3
Thread Starter
Member
Thanks for your reply.
I've tried to start the hook from a vb-app using this code
Code:
Private hDll As Long, _
hHook As Long
Private Sub Command1_Click()
Dim hProc As Long, _
idThread As Long
hDll = LoadLibrary(App.Path + "\Hook.dll")
hProc = GetProcAddress(hDll, "MouseProc")
idThread = GetWindowThreadProcessId(FindWindow("Shell_TrayWnd", vbNullString), 0&)
hHook = SetWindowsHookEx(WH_MOUSE, hProc, 0&, idThread)
InitHook Me.hWnd
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
UnhookWindowsHookEx hHook
FreeLibrary hDll
End Sub
hDll, hProc and idThread are ok, but SetWindowsHookEx returns zero (=Error).
I've tried
Code:
hHook = SetWindowsHookEx(WH_MOUSE, hProc, 0&, idThread)
hHook = SetWindowsHookEx(WH_MOUSE, hProc, hDll, 0&)
hHook = SetWindowsHookEx(WH_MOUSE, hProc, hDll, idThread)
neither of them works. What am I doing wrong?
-
May 28th, 2002, 03:23 AM
#4
Frenzied Member
Your best bet to find out what is going on is to get the Err.LastDllError after the call returns zero and translate it thus:
VB Code:
'\\ API Error decoding
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
'\\ -- [ LastSystemError ]----------------------------------
'\\ Returns the message from the system which describes the
'\\ last dll error to occur, as
'\\ held in Err.LastDllError. This function should be
'\\ called as soon after the API call
'\\ which might have errored, as this member can be reset
'\\ to zero by subsequent API calls.
'\\ --------------------------------------------------------
'\\ (c) 2001 Merrion Computing Ltd
Public Function LastSystemError() As String
Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Dim sError As String * 500 '\ Preinitilise a string buffer to put any error message into
Dim lErrNum As Long
Dim lErrMsg As Long
lErrNum = Err.LastDllError
lErrMsg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, lErrNum, 0, sError, Len(sError), 0)
LastSystemError = Trim(sError)
End Function
Hope this helps,
Duncan
-
May 29th, 2002, 09:49 AM
#5
Thread Starter
Member
Thanks for your reply, Duncan.
I've tried the following:
VB Code:
hHook = SetWindowsHookEx(WH_MOUSE, hProc, hDll, idThread)
hHook = SetWindowsHookEx(WH_MOUSE, hProc, hDll, 0&)
'works both, but sets the hook to vb only, even if idThread is the
'id of a thread in a different process, like
'GetWindowThreadProcessId(FindWindow("Shell_TrayWnd", vbNullString), 0&) e.g.
hHook = SetWindowsHookEx(WH_MOUSE, hProc, 0&, idThread)
hHook = SetWindowsHookEx(WH_MOUSE, hProc, 0&, 0&)
'both return the error "Non-locale hook can't be set without module-handle".
But passing the ModuleHandle of the Hook.dll is reducing the hook to the vb-process! How do I set a GLOBAL hook?
-
May 29th, 2002, 10:04 AM
#6
Frenzied Member
Only difference I can see is that where you have 0 I have vbNull i.e.:
VB Code:
hHook = SetWindowsHookEx(WH_MOUSE, hProc, vbNull, idThread)
HTH,
Duncan
-
May 29th, 2002, 12:46 PM
#7
Thread Starter
Member
Hey, that works!!!  Thanks!
Didn't know, there's a difference between vbNull and 0&...
Regards, Quix
-
May 30th, 2002, 03:56 PM
#8
Hyperactive Member
i'm trying to learn how to hook..and i'm starting at this code..i'm VERY newb to VC++ but i know vb pretty well...i'm wondering how to make a .def file so i can test out this global hook
-
May 31st, 2002, 05:05 AM
#9
Thread Starter
Member
I'm new to VC++ too. That was my first C-program.
For the *.def-file just add an ordinary textfile to your project and insert
Code:
LIBRARY "hook.dll"
EXPORTS
InitHook
MouseProc
where InitHook and MouseProc are the Procedures you want to export (and use from vb).
Hope this helps,
Quix
-
May 31st, 2002, 05:11 AM
#10
Thread Starter
Member
BTW, that stuff with SetWindowText didn't work. To recognize when your hooking-Proc is called just add a Beep. I used this code:
Code:
LRESULT __stdcall CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION)
{
MOUSEHOOKSTRUCT mhs;
memcpy(&mhs, (void*)lParam, sizeof(MOUSEHOOKSTRUCT));
Beep(440,50);
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
use mhs.hWnd to get the handle of the window calling the MouseProc.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|