Skip to content

Instantly share code, notes, and snippets.

@deccer
Last active February 20, 2018 23:00
Show Gist options
  • Save deccer/def5c9d5d1ad5007cedce6e104d13185 to your computer and use it in GitHub Desktop.
Save deccer/def5c9d5d1ad5007cedce6e104d13185 to your computer and use it in GitHub Desktop.
Global/Local WH_MESSAGE Hook
public enum HookType
{
MessageQueue = 3, //WH_GETMESSAGE
Shell = 10, //WH_SHELL
}
public abstract class ManagedHook : IDisposable
{
private delegate IntPtr MessageDelegate(int code, IntPtr wparam, IntPtr lparam);
private const int HcAction = 0;
[DllImport("user32", EntryPoint = "SetWindowsHookExA", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int hookId, [MarshalAs(UnmanagedType.FunctionPtr)] MessageDelegate messageDelegate, IntPtr moduleHandle, IntPtr threadId);
[DllImport("user32", EntryPoint = "UnhookWindowsHookEx", SetLastError = true)]
private static extern int UnhookWindowsHookEx(IntPtr hHook);
[DllImport("user32", EntryPoint = "CallNextHookEx", SetLastError = true)]
private static extern IntPtr CallNextHook(IntPtr hHook, int ncode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThreadId();
private readonly IntPtr _hookHandle;
protected ManagedHook(HookType hookType, bool installGlobally = false)
{
_hookHandle = SetWindowsHookEx((int)hookType, ProcessMessage, IntPtr.Zero, installGlobally ? IntPtr.Zero : GetCurrentThreadId());
if (_hookHandle == IntPtr.Zero)
{
throw new Exception(Marshal.GetLastWin32Error().ToString("X"));
}
}
private IntPtr ProcessMessage(int code, IntPtr wparam, IntPtr lparam)
{
if (code == HcAction)
{
try
{
if (Handle(wparam, lparam)) return new IntPtr(1);
}
catch
{
// ignored
}
}
return CallNextHook(_hookHandle, code, wparam, lparam);
}
protected abstract bool Handle(IntPtr wparam, IntPtr lparam);
public void Dispose()
{
UnhookWindowsHookEx(_hookHandle);
}
}
class WmNcPaintHook : ManagedHook
{
[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
public UInt32 message;
public IntPtr wParam;
public IntPtr lParam;
public UInt32 time;
public Point pt;
}
public WmNcPaintHook()
: base(WindowsFormsApp4.HookType.MessageQueue)
{
}
protected override bool Handle(IntPtr wparam, IntPtr lparam)
{
var msg = Marshal.PtrToStructure<MSG>(lparam);
Debug.WriteLine($"wparam: {wparam} lParam: {lparam} msg.wnd: {msg.hwnd} msg.msg: {msg.message}");
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment