kayhustle
asked on
Need help with setting hooks
I need to set a global hook that raises the callback function whenever a window is minimized,maximized or is set focus. I tried using WH_CBT but this does not seem to work. Is there another hook type I should use? Can you please give sample code that works.
ASKER
Ok, I'm working in .net, when I set the WH_GETMESSAGE hook for some reason the callback function is never called, just like when I set the WH_CBT hook. If I set the WH_MOUSE_LL hook, the callback is called maybe a hundred times before a null reference is raised. This has been an ongoing problem if you can figure this out I will double the points. If I have two of the same processes running then the WH_MOUSE_LL hook will be called maybe 2000 times before the null reference exception is raised. If anybody can figure out why this behavior happens and explain it I'll give double points and even paypal you $20 bucks. If you can just give me an example of how to get it working I'll give at least double the points. Here is the code I have. There is another form that I make a reference to this dll with and do HCallback h = new HCallback(); This class is stored in a dll called testcbthookproc.dll:
using System;
using WindowsFunctions;
using System.Text;
using System.Runtime.InteropServ ices;
namespace testcbthookproc
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class HCallback
{
public const int WH_CBT = 5;
public const int WH_MOUSE = 7; public const int WH_MOUSE_LL = 14;
public const int WH_GETMESSAGE = 3;
public const int WH_CALLWNDPROC = 4;
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32",Char Set=CharSe t.Auto,
CallingConvention=CallingC onvention. StdCall)]
internal static extern int LoadLibrary(string lpLibFileName);
[DllImport("user32.dll",Ch arSet=Char Set.Auto,
CallingConvention=CallingC onvention. StdCall)]
internal static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);
[DllImport("user32.dll",Ch arSet=Char Set.Auto,
CallingConvention=CallingC onvention. StdCall)]
internal static extern int GetWindowText(int hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll",Ch arSet=Char Set.Auto,
CallingConvention=CallingC onvention. StdCall)]
internal static extern int CallNextHookEx(int idHook, int nCode,IntPtr wParam, IntPtr lParam);
public static int hHook;
private bool cbt = false;
public HCallback()
{
int lib = LoadLibrary("testcbthookpr oc.dll");
int mess = WH_GETMESSAGE;
if(mess==WH_CBT)
cbt=true;
HCallback.hHook=SetWindows HookEx(mes s,new HookProc(CBTHookProc2),
(IntPtr)lib,0);
}
public int CBTHookProc2(int nCode, IntPtr wParam, IntPtr lParam)
{
if(nCode>=0)
{
StringBuilder s = new StringBuilder(1000);
GetWindowText((int)wParam, s,100);
if(cbt)
{
switch((HCBTType)nCode)
{
case HCBTType.HCBT_SETFOCUS:
Console.WriteLine(s);
Console.WriteLine("Focus "+((int)wParam).ToString() );//+","+( (int)wh.LP aram).ToSt ring());
break;
case HCBTType.HCBT_CREATEWND:
Console.WriteLine(s);
Console.WriteLine("Created ."+((int)w Param).ToS tring());
break;
case HCBTType.HCBT_MINMAX:
Console.WriteLine(s);
Console.WriteLine("Min max."+((int)wParam).ToStri ng());
break;
}
}
}
else
{
if(nCode==-1)
Console.WriteLine("Got -1 code");
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}
using System;
using WindowsFunctions;
using System.Text;
using System.Runtime.InteropServ
namespace testcbthookproc
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class HCallback
{
public const int WH_CBT = 5;
public const int WH_MOUSE = 7; public const int WH_MOUSE_LL = 14;
public const int WH_GETMESSAGE = 3;
public const int WH_CALLWNDPROC = 4;
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32",Char
CallingConvention=CallingC
internal static extern int LoadLibrary(string lpLibFileName);
[DllImport("user32.dll",Ch
CallingConvention=CallingC
internal static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);
[DllImport("user32.dll",Ch
CallingConvention=CallingC
internal static extern int GetWindowText(int hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll",Ch
CallingConvention=CallingC
internal static extern int CallNextHookEx(int idHook, int nCode,IntPtr wParam, IntPtr lParam);
public static int hHook;
private bool cbt = false;
public HCallback()
{
int lib = LoadLibrary("testcbthookpr
int mess = WH_GETMESSAGE;
if(mess==WH_CBT)
cbt=true;
HCallback.hHook=SetWindows
(IntPtr)lib,0);
}
public int CBTHookProc2(int nCode, IntPtr wParam, IntPtr lParam)
{
if(nCode>=0)
{
StringBuilder s = new StringBuilder(1000);
GetWindowText((int)wParam,
if(cbt)
{
switch((HCBTType)nCode)
{
case HCBTType.HCBT_SETFOCUS:
Console.WriteLine(s);
Console.WriteLine("Focus "+((int)wParam).ToString()
break;
case HCBTType.HCBT_CREATEWND:
Console.WriteLine(s);
Console.WriteLine("Created
break;
case HCBTType.HCBT_MINMAX:
Console.WriteLine(s);
Console.WriteLine("Min max."+((int)wParam).ToStri
break;
}
}
}
else
{
if(nCode==-1)
Console.WriteLine("Got -1 code");
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}
ASKER
oh, ignore the include WindowsFunctions, its just a dll with this enum specified:
public enum HCBTType
{
HCBT_MOVESIZE = 0,
HCBT_MINMAX = 1,
HCBT_QS = 2,
HCBT_CREATEWND = 3,
HCBT_DESTROYWND = 4,
HCBT_ACTIVATE = 5,
HCBT_CLICKSKIPPED = 6,
HCBT_KEYSKIPPED = 7,
HCBT_SYSCOMMAND = 8,
HCBT_SETFOCUS = 9,
}
public enum HCBTType
{
HCBT_MOVESIZE = 0,
HCBT_MINMAX = 1,
HCBT_QS = 2,
HCBT_CREATEWND = 3,
HCBT_DESTROYWND = 4,
HCBT_ACTIVATE = 5,
HCBT_CLICKSKIPPED = 6,
HCBT_KEYSKIPPED = 7,
HCBT_SYSCOMMAND = 8,
HCBT_SETFOCUS = 9,
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
https://www.experts-exchange.com/questions/21529436/Mysterious-behavior-with-setting-hooks.html
Go there and leave the same answer so I can leave you double the points for telling me why it wasn't working.
Go there and leave the same answer so I can leave you double the points for telling me why it wasn't working.
Thanx for that.
I've done it.
I've done it.
#define __DLL
#ifndef _DEBUG
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifdef _DEBUG
#include <crtdbg.h>
#ifdef __DLL
#define __DYNLINK __declspec(dllexport)
#else
#define __DYNLINK __declspec(dllimport)
#endif
#define HOOL_EVENT_NAME "ElmerFudd"
#pragma warning(disable:4786) // 'identifier truncated to 255 characters'
#pragma data_seg( ".shared")
HHOOK g_hhk = NULL;
#pragma data_seg()
HINSTANCE g_hThisDll;
LRESULT CALLBACK HookProc ( int nCode,
WPARAM wParam,
LPARAM lParam
);
int APIENTRY DllMain ( HINSTANCE hInstance,
DWORD dwReason,
LPVOID lpReserved
)
{
if ( dwReason == DLL_PROCESS_ATTACH)
{
g_hThisDll = hInstance;
return ( DisableThreadLibraryCalls ( g_hThisDll));
}
return( TRUE);
}
LRESULT CALLBACK HookProc ( int nCode, // hook code
WPARAM wParam, // removal flag
LPARAM lParam // address of structure with message
)
{
PMSG pmsg = ( PMSG) lParam;
if ( 0 > nCode || PM_NOREMOVE == wParam)
{
return ( CallNextHookEx ( g_hhk,
nCode,
wParam,
lParam
)
);
}
if ( WM_KEYDOWN == pmsg->message
|| WM_KEYUP == pmsg->message
)
{
/* this one is for us, do whatever is desired */
}
return ( CallNextHookEx ( g_hhk,
nCode,
wParam,
lParam
)
);
}
LONG __DYNLINK HookInit ( void)
{
HANDLE hev;
if ( g_hhk) return ( ERROR_ALREADY_EXISTS);
g_hhk = SetWindowsHookEx ( WH_GETMESSAGE,
( HOOKPROC) HookProc,
g_hThisDll,
0
);
#ifdef _DEBUG
_ASSERT ( g_hhk);
#endif
if ( !( hev = CreateEvent ( NULL,
FALSE,
FALSE,
HOOK_EVENT_NAME
)
)
)
{
if ( ERROR_ALREADY_EXISTS == GetLastError ())
{
if ( !( hev = OpenEvent ( EVENT_ALL_ACCESS,
FALSE,
HOOK_EVENT_NAME
)
)
)
{
return ( -1);
}
}
else
{
return ( -2);
}
}
WaitForSingleObject ( hev, INFINITE);
Sleep ( 5000);
return ( 0);
}
LONG __DYNLINK HookTerm ( void)
{
HANDLE hev;
UnhookWindowsHookEx ( g_hhk);
Sleep ( 5000);
if ( !( hev = OpenEvent ( EVENT_ALL_ACCESS,
FALSE,
HOOK_EVENT_NAME
)
)
)
{
return ( GetLastError ());
}
PulseEvent ( hev);
return ( 0);
}
All you need to do is calling 'HookInit()' to set the hook and 'HookTerm()' to remove it.