using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class User32
{
/// The delegate for a hook procedure set by SetWindowsHookEx.
///
/// A hook code that the hook procedure uses to determine the action to perform. The value of the hook code depends on the type of
/// the hook; each type has its own characteristic set of hook codes.
///
///
/// The value depends on the hook code, but typically contains information about a message that was sent or posted.
///
///
/// The value depends on the hook code, but typically contains information about a message that was sent or posted.
///
/// The value depends on the hook code.
[PInvokeData("WinUser.h")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
///
///
/// An application-defined callback (or hook) function that the system calls in response to events generated by an accessible object.
/// The hook function processes the event notifications as required. Clients install the hook function and request specific types of
/// event notifications by calling SetWinEventHook.
///
///
/// The WINEVENTPROC type defines a pointer to this callback function. WinEventProc is a placeholder for the application-defined
/// function name.
///
///
///
/// Type: HWINEVENTHOOK
///
/// Handle to an event hook function. This value is returned by SetWinEventHook when the hook function is installed and is specific
/// to each instance of the hook function.
///
///
///
/// Type: DWORD
/// Specifies the event that occurred. This value is one of the event constants.
///
///
/// Type: HWND
///
/// Handle to the window that generates the event, or NULL if no window is associated with the event. For example, the mouse
/// pointer is not associated with a window.
///
///
///
/// Type: LONG
/// Identifies the object associated with the event. This is one of the object identifiers or a custom object ID.
///
///
/// Type: LONG
///
/// Identifies whether the event was triggered by an object or a child element of the object. If this value is CHILDID_SELF, the
/// event was triggered by the object; otherwise, this value is the child ID of the element that triggered the event.
///
///
/// The identifier event thread.
///
/// Type: DWORD
/// Specifies the time, in milliseconds, that the event was generated.
///
///
/// Within the hook function, the parameters hwnd, idObject, and idChild are used when calling AccessibleObjectFromEvent.
/// Servers generate events by calling NotifyWinEvent.
/// Create multiple callback functions to handle different events. For more information, see Registering a Hook Function.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nc-winuser-wineventproc WINEVENTPROC Wineventproc; void Wineventproc(
// HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD idEventThread, DWORD dwmsEventTime ) {...}
[PInvokeData("winuser.h", MSDNShortId = "5fe3cacc-4563-43da-960d-729d3fe4ff70")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void WinEventProc(HWINEVENTHOOK hWinEventHook, uint winEvent, HWND hwnd, int idObject, int idChild, uint idEventThread, uint dwmsEventTime);
/// The type of hook procedure to be installed.
[PInvokeData("WinUser.h", MSDNShortId = "ms644990")]
public enum HookType
{
///
/// Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu,
/// or scroll bar. For more information, see the MessageProc hook procedure.
///
WH_MSGFILTER = -1,
///
/// Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording
/// macros. For more information, see the JournalRecordProc hook procedure.
///
WH_JOURNALRECORD = 0,
///
/// Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information,
/// see the JournalPlaybackProc hook procedure.
///
WH_JOURNALPLAYBACK = 1,
///
/// Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
///
WH_KEYBOARD = 2,
///
/// Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
///
WH_GETMESSAGE = 3,
///
/// Installs a hook procedure that monitors messages before the system sends them to the destination window procedure. For more
/// information, see the CallWndProc hook procedure.
///
WH_CALLWNDPROC = 4,
///
/// Installs a hook procedure that receives notifications useful to a CBT application. For more information, see the CBTProc hook procedure.
///
WH_CBT = 5,
///
/// Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu,
/// or scroll bar. The hook procedure monitors these messages for all applications in the same desktop as the calling thread. For
/// more information, see the SysMsgProc hook procedure.
///
WH_SYSMSGFILTER = 6,
/// Installs a hook procedure that monitors mouse messages. For more information, see the MouseProc hook procedure.
WH_MOUSE = 7,
///
WH_HARDWARE = 8,
///
/// Installs a hook procedure useful for debugging other hook procedures. For more information, see the DebugProc hook procedure.
///
WH_DEBUG = 9,
///
/// Installs a hook procedure that receives notifications useful to shell applications. For more information, see the ShellProc
/// hook procedure.
///
WH_SHELL = 10,
///
/// Installs a hook procedure that will be called when the application's foreground thread is about to become idle. This hook is
/// useful for performing low priority tasks during idle time. For more information, see the ForegroundIdleProc hook procedure.
///
WH_FOREGROUNDIDLE = 11,
///
/// Installs a hook procedure that monitors messages after they have been processed by the destination window procedure. For more
/// information, see the CallWndRetProc hook procedure.
///
WH_CALLWNDPROCRET = 12,
///
/// Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc
/// hook procedure.
///
WH_KEYBOARD_LL = 13,
///
/// Installs a hook procedure that monitors low-level mouse input events. For more information, see the LowLevelMouseProc hook procedure.
///
WH_MOUSE_LL = 14
}
/// Flags for .
[PInvokeData("winuser.h", MSDNShortId = "090bda1b-0635-4aa3-ae33-3987b36e30b8")]
[Flags]
public enum WINEVENT
{
///
/// The DLL that contains the callback function is mapped into the address space of the process that generates the event. With
/// this flag, the system sends event notifications to the callback function as they occur. The hook function must be in a DLL
/// when this flag is specified. This flag has no effect when both the calling process and the generating process are not 32-bit
/// or 64-bit processes, or when the generating process is a console application. For more information, see In-Context Hook Functions.
///
WINEVENT_INCONTEXT = 0,
///
/// The callback function is not mapped into the address space of the process that generates the event. Because the hook function
/// is called across process boundaries, the system must queue events. Although this method is asynchronous, events are
/// guaranteed to be in sequential order. For more information, see Out-of-Context Hook Functions.
///
WINEVENT_OUTOFCONTEXT = 1,
///
/// Prevents this instance of the hook from receiving the events that are generated by threads in this process. This flag does
/// not prevent threads from generating events.
///
WINEVENT_SKIPOWNPROCESS = 2,
///
/// Prevents this instance of the hook from receiving the events that are generated by the thread that is registering this hook.
///
WINEVENT_SKIPOWNTHREAD = 4,
}
///
///
/// Passes the specified message and hook code to the hook procedures associated with the WH_SYSMSGFILTER and WH_MSGFILTER hooks. A
/// WH_SYSMSGFILTER or WH_MSGFILTER hook procedure is an application-defined callback function that examines and,
/// optionally, modifies messages for a dialog box, message box, menu, or scroll bar.
///
///
///
/// Type: LPMSG
/// A pointer to an MSG structure that contains the message to be passed to the hook procedures.
///
///
/// Type: int
///
/// An application-defined code used by the hook procedure to determine how to process the message. The code must not have the same
/// value as system-defined hook codes (MSGF_ and HC_) associated with the WH_SYSMSGFILTER and WH_MSGFILTER hooks.
///
///
///
/// Type: Type: BOOL
/// If the application should process the message further, the return value is zero.
/// If the application should not process the message further, the return value is nonzero.
///
///
///
/// The system calls CallMsgFilter to enable applications to examine and control the flow of messages during internal
/// processing of dialog boxes, message boxes, menus, and scroll bars, or when the user activates a different window by pressing the
/// ALT+TAB key combination.
///
/// Install this hook procedure by using the SetWindowsHookEx function.
/// Examples
/// For an example, see WH_MSGFILTER and WH_SYSMSGFILTER Hooks.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-callmsgfiltera BOOL CallMsgFilterA( LPMSG lpMsg, int nCode );
[DllImport(Lib.User32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winuser.h", MSDNShortId = "callmsgfilter")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CallMsgFilter(ref MSG lpMsg, int nCode);
///
///
/// Passes the hook information to the next hook procedure in the current hook chain. A hook procedure can call this function either
/// before or after processing the hook information.
///
///
///
/// Type: HHOOK
/// This parameter is ignored.
///
///
/// Type: int
///
/// The hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information.
///
///
///
/// Type: WPARAM
///
/// The wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with
/// the current hook chain.
///
///
///
/// Type: LPARAM
///
/// The lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with
/// the current hook chain.
///
///
///
/// Type: Type: LRESULT
///
/// This value is returned by the next hook procedure in the chain. The current hook procedure must also return this value. The
/// meaning of the return value depends on the hook type. For more information, see the descriptions of the individual hook procedures.
///
///
///
/// Hook procedures are installed in chains for particular hook types. CallNextHookEx calls the next hook in the chain.
///
/// Calling CallNextHookEx is optional, but it is highly recommended; otherwise, other applications that have installed hooks
/// will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you
/// absolutely need to prevent the notification from being seen by other applications.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-callnexthookex LRESULT CallNextHookEx( HHOOK hhk, int
// nCode, WPARAM wParam, LPARAM lParam );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "callnexthookex")]
public static extern IntPtr CallNextHookEx(HHOOK hhk, int nCode, IntPtr wParam, IntPtr lParam);
/// Determines whether there is an installed WinEvent hook that might be notified of a specified event.
///
/// Type: DWORD
///
/// The event constant that hooks might be notified of. The function checks whether there is an installed hook for this event constant.
///
///
///
/// Type: BOOL
/// If there is a hook to be notified of the specified event, the return value is TRUE.
/// If there are no hooks to be notified of the specified event, the return value is FALSE.
///
///
///
/// This method is guaranteed to never return a false negative. If this method returns FALSE, it means that no hooks in the
/// system would be notified of the event. However, this method may return a false positive. In other words, it may return
/// TRUE even though there are no hooks that would be notified. Thus, it is safe for components to circumvent some work if
/// this method returns FALSE.
///
/// Event hooks can be installed at any time, so server developers should not cache the return value for long periods of time.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-iswineventhookinstalled BOOL IsWinEventHookInstalled(
// DWORD event );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "bc1e97ad-748d-420a-8c9a-72a555b685e1")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWinEventHookInstalled(uint winEvent);
///
///
/// Installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for
/// certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the
/// calling thread.
///
///
///
/// Type: int
/// The type of hook procedure to be installed. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// WH_CALLWNDPROC 4
///
/// Installs a hook procedure that monitors messages before the system sends them to the destination window procedure. For more
/// information, see the CallWndProc hook procedure.
///
///
/// -
/// WH_CALLWNDPROCRET 12
///
/// Installs a hook procedure that monitors messages after they have been processed by the destination window procedure. For more
/// information, see the CallWndRetProc hook procedure.
///
///
/// -
/// WH_CBT 5
///
/// Installs a hook procedure that receives notifications useful to a CBT application. For more information, see the CBTProc hook procedure.
///
///
/// -
/// WH_DEBUG 9
/// Installs a hook procedure useful for debugging other hook procedures. For more information, see the DebugProc hook procedure.
///
/// -
/// WH_FOREGROUNDIDLE 11
///
/// Installs a hook procedure that will be called when the application's foreground thread is about to become idle. This hook is
/// useful for performing low priority tasks during idle time. For more information, see the ForegroundIdleProc hook procedure.
///
///
/// -
/// WH_GETMESSAGE 3
///
/// Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
///
///
/// -
/// WH_JOURNALPLAYBACK 1
///
/// Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see
/// the JournalPlaybackProc hook procedure.
///
///
/// -
/// WH_JOURNALRECORD 0
///
/// Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording
/// macros. For more information, see the JournalRecordProc hook procedure.
///
///
/// -
/// WH_KEYBOARD 2
/// Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
///
/// -
/// WH_KEYBOARD_LL 13
///
/// Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc hook procedure.
///
///
/// -
/// WH_MOUSE 7
/// Installs a hook procedure that monitors mouse messages. For more information, see the MouseProc hook procedure.
///
/// -
/// WH_MOUSE_LL 14
///
/// Installs a hook procedure that monitors low-level mouse input events. For more information, see the LowLevelMouseProc hook procedure.
///
///
/// -
/// WH_MSGFILTER -1
///
/// Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or
/// scroll bar. For more information, see the MessageProc hook procedure.
///
///
/// -
/// WH_SHELL 10
///
/// Installs a hook procedure that receives notifications useful to shell applications. For more information, see the ShellProc hook procedure.
///
///
/// -
/// WH_SYSMSGFILTER 6
///
/// Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or
/// scroll bar. The hook procedure monitors these messages for all applications in the same desktop as the calling thread. For more
/// information, see the SysMsgProc hook procedure.
///
///
///
///
///
/// Type: HOOKPROC
///
/// A pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a
/// different process, the lpfn parameter must point to a hook procedure in a DLL. Otherwise, lpfn can point to a hook procedure in
/// the code associated with the current process.
///
///
///
/// Type: HINSTANCE
///
/// A handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL
/// if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code
/// associated with the current process.
///
///
///
/// Type: DWORD
///
/// The identifier of the thread with which the hook procedure is to be associated. For desktop apps, if this parameter is zero, the
/// hook procedure is associated with all existing threads running in the same desktop as the calling thread. For Windows Store apps,
/// see the Remarks section.
///
///
///
/// Type: Type: HHOOK
/// If the function succeeds, the return value is the handle to the hook procedure.
/// If the function fails, the return value is NULL. To get extended error information, call GetLastError.
///
///
///
/// SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process,
/// and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is
/// required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit
/// application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have
/// different names.
///
///
/// Because hooks run in the context of an application, they must match the "bitness" of the application. If a 32-bit application
/// installs a global hook on 64-bit Windows, the 32-bit hook is injected into each 32-bit process (the usual security boundaries
/// apply). In a 64-bit process, the threads are still marked as "hooked." However, because a 32-bit application must run the hook
/// code, the system executes the hook in the hooking app's context; specifically, on the thread that called SetWindowsHookEx.
/// This means that the hooking application must continue to pump messages or it might block the normal functioning of the 64-bit processes.
///
///
/// If a 64-bit application installs a global hook on 64-bit Windows, the 64-bit hook is injected into each 64-bit process, while all
/// 32-bit processes use a callback to the hooking application.
///
///
/// To hook all applications on the desktop of a 64-bit Windows installation, install a 32-bit global hook and a 64-bit global hook,
/// each from appropriate processes, and be sure to keep pumping messages in the hooking application to avoid blocking normal
/// functioning. If you already have a 32-bit global hooking application and it doesn't need to run in each application's context,
/// you may not need to create a 64-bit version.
///
///
/// An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a
/// thread created by another process.
///
///
/// Calling the CallNextHookEx function to chain to the next hook procedure is optional, but it is highly recommended; otherwise,
/// other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You
/// should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.
///
///
/// Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook.
///
///
/// The scope of a hook depends on the hook type. Some hooks can be set only with global scope; others can also be set for only a
/// specific thread, as shown in the following table.
///
///
///
/// Hook
/// Scope
///
/// -
/// WH_CALLWNDPROC
/// Thread or global
///
/// -
/// WH_CALLWNDPROCRET
/// Thread or global
///
/// -
/// WH_CBT
/// Thread or global
///
/// -
/// WH_DEBUG
/// Thread or global
///
/// -
/// WH_FOREGROUNDIDLE
/// Thread or global
///
/// -
/// WH_GETMESSAGE
/// Thread or global
///
/// -
/// WH_JOURNALPLAYBACK
/// Global only
///
/// -
/// WH_JOURNALRECORD
/// Global only
///
/// -
/// WH_KEYBOARD
/// Thread or global
///
/// -
/// WH_KEYBOARD_LL
/// Global only
///
/// -
/// WH_MOUSE
/// Thread or global
///
/// -
/// WH_MOUSE_LL
/// Global only
///
/// -
/// WH_MSGFILTER
/// Thread or global
///
/// -
/// WH_SHELL
/// Thread or global
///
/// -
/// WH_SYSMSGFILTER
/// Global only
///
///
///
/// For a specified hook type, thread hooks are called first, then global hooks. Be aware that the WH_MOUSE, WH_KEYBOARD,
/// WH_JOURNAL*, WH_SHELL, and low-level hooks can be called on the thread that installed the hook rather than the thread processing
/// the hook. For these hooks, it is possible that both the 32-bit and 64-bit hooks will be called if a 32-bit hook is ahead of a
/// 64-bit hook in the hook chain.
///
///
/// The global hooks are a shared resource, and installing one affects all applications in the same desktop as the calling thread.
/// All global hook functions must be in libraries. Global hooks should be restricted to special-purpose applications or to use as a
/// development aid during application debugging. Libraries that no longer need a hook should remove its hook procedure.
///
///
/// Windows Store app development If dwThreadId is zero, then window hook DLLs are not loaded in-process for the Windows Store
/// app processes and the Windows Runtime broker process unless they are installed by either UIAccess processes (accessibility
/// tools). The notification is delivered on the installer's thread for these hooks:
///
///
/// -
/// WH_JOURNALPLAYBACK
///
/// -
/// WH_JOURNALRECORD
///
/// -
/// WH_KEYBOARD
///
/// -
/// WH_KEYBOARD_LL
///
/// -
/// WH_MOUSE
///
/// -
/// WH_MOUSE_LL
///
///
///
/// This behavior is similar to what happens when there is an architecture mismatch between the hook DLL and the target application
/// process, for example, when the hook DLL is 32-bit and the application process 64-bit.
///
/// Examples
/// For an example, see Installing and Releasing Hook Procedures.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowshookexa HHOOK SetWindowsHookExA( int idHook,
// HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId );
[DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winuser.h", MSDNShortId = "setwindowshookex")]
public static extern SafeHHOOK SetWindowsHookEx(HookType idHook, HookProc lpfn, HINSTANCE hmod, int dwThreadId);
/// Sets an event hook function for a range of events.
///
/// Type: UINT
///
/// Specifies the event constant for the lowest event value in the range of events that are handled by the hook function. This
/// parameter can be set to EVENT_MIN to indicate the lowest possible event value.
///
///
///
/// Type: UINT
///
/// Specifies the event constant for the highest event value in the range of events that are handled by the hook function. This
/// parameter can be set to EVENT_MAX to indicate the highest possible event value.
///
///
///
/// Type: HMODULE
///
/// Handle to the DLL that contains the hook function at lpfnWinEventProc, if the WINEVENT_INCONTEXT flag is specified in the dwFlags
/// parameter. If the hook function is not located in a DLL, or if the WINEVENT_OUTOFCONTEXT flag is specified, this parameter is NULL.
///
///
///
/// Type: WINEVENTPROC
/// Pointer to the event hook function. For more information about this function, see WinEventProc.
///
///
/// Type: DWORD
///
/// Specifies the ID of the process from which the hook function receives events. Specify zero (0) to receive events from all
/// processes on the current desktop.
///
///
///
/// Type: DWORD
///
/// Specifies the ID of the thread from which the hook function receives events. If this parameter is zero, the hook function is
/// associated with all existing threads on the current desktop.
///
///
///
/// Type: UINT
/// Flag values that specify the location of the hook function and of the events to be skipped. The following flags are valid:
///
///
/// Value
/// Meaning
///
/// -
/// WINEVENT_INCONTEXT
///
/// The DLL that contains the callback function is mapped into the address space of the process that generates the event. With this
/// flag, the system sends event notifications to the callback function as they occur. The hook function must be in a DLL when this
/// flag is specified. This flag has no effect when both the calling process and the generating process are not 32-bit or 64-bit
/// processes, or when the generating process is a console application. For more information, see In-Context Hook Functions.
///
///
/// -
/// WINEVENT_OUTOFCONTEXT
///
/// The callback function is not mapped into the address space of the process that generates the event. Because the hook function is
/// called across process boundaries, the system must queue events. Although this method is asynchronous, events are guaranteed to be
/// in sequential order. For more information, see Out-of-Context Hook Functions.
///
///
/// -
/// WINEVENT_SKIPOWNPROCESS
///
/// Prevents this instance of the hook from receiving the events that are generated by threads in this process. This flag does not
/// prevent threads from generating events.
///
///
/// -
/// WINEVENT_SKIPOWNTHREAD
///
/// Prevents this instance of the hook from receiving the events that are generated by the thread that is registering this hook.
///
///
///
/// The following flag combinations are valid:
///
/// -
/// WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS
///
/// -
/// WINEVENT_INCONTEXT | WINEVENT_SKIPOWNTHREAD
///
/// -
/// WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS
///
/// -
/// WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNTHREAD
///
///
/// Additionally, client applications can specify WINEVENT_INCONTEXT, or WINEVENT_OUTOFCONTEXT alone.
/// See Remarks section for information on Windows Store app development.
///
///
/// Type: HWINEVENTHOOK
///
/// If successful, returns an HWINEVENTHOOK value that identifies this event hook instance. Applications save this return value to
/// use it with the UnhookWinEvent function.
///
/// If unsuccessful, returns zero.
///
///
/// This function allows clients to specify which processes and threads they are interested in.
///
/// If the idProcess parameter is nonzero and idThread is zero, the hook function receives the specified events from all threads in
/// that process. If the idProcess parameter is zero and idThread is nonzero, the hook function receives the specified events only
/// from the thread specified by idThread. If both are zero, the hook function receives the specified events from all threads and processes.
///
///
/// Clients can call SetWinEventHook multiple times if they want to register additional hook functions or listen for
/// additional events.
///
/// The client thread that calls SetWinEventHook must have a message loop in order to receive events.
///
/// When you use SetWinEventHook to set a callback in managed code, you should use the GCHandle structure to avoid exceptions.
/// This tells the garbage collector not to move the callback.
///
///
/// For out-of-context events, the event is delivered on the same thread that called SetWinEventHook. In some situations, even
/// if you request WINEVENT_INCONTEXT events, the events will still be delivered out-of-context. These scenarios include events from
/// console windows and events from processes that have a different bit-depth (64 bit versus 32 bits) than the caller.
///
///
/// While a hook function processes an event, additional events may be triggered, which may cause the hook function to reenter before
/// the processing for the original event is finished. The problem with reentrancy in hook functions is that events are completed out
/// of sequence unless the hook function handles this situation. For more information, see Guarding Against Reentrancy.
///
///
/// Windows Store app development If dwFlags is WINEVENT_INCONTEXT AND (idProcess = 0 | idThread = 0), then window hook DLLs
/// are not loaded in-process for the Windows Store app processes and the Windows Runtime broker process unless they are installed by
/// UIAccess processes (accessibility tools). The notification is delivered on the installer's thread.
///
///
/// This behavior is similar to what happens when there is an architecture mismatch between the hook DLL and the target application
/// process, for example, when the hook DLL is 32-bit and the application process 64-bit.
///
/// Examples
///
/// The following example code shows how a client application might listen for menu-start and menu-end events. For simplicity, the
/// event handler just sends some information to the standard output.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwineventhook HWINEVENTHOOK SetWinEventHook( DWORD
// eventMin, DWORD eventMax, HMODULE hmodWinEventProc, WINEVENTPROC pfnWinEventProc, DWORD idProcess, DWORD idThread, DWORD dwFlags );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "090bda1b-0635-4aa3-ae33-3987b36e30b8")]
public static extern HWINEVENTHOOK SetWinEventHook(uint eventMin, uint eventMax, HINSTANCE hmodWinEventProc, WinEventProc pfnWinEventProc, uint idProcess, uint idThread, WINEVENT dwFlags);
///
/// Removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.
///
///
/// Type: HHOOK
/// A handle to the hook to be removed. This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.
///
///
/// Type: Type: BOOL
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
///
///
/// The hook procedure can be in the state of being called by another thread even after UnhookWindowsHookEx returns. If the
/// hook procedure is not being called concurrently, the hook procedure is removed immediately before UnhookWindowsHookEx returns.
///
/// Examples
/// For an example, see Monitoring System Events.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unhookwindowshookex BOOL UnhookWindowsHookEx( HHOOK hhk );
[DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "unhookwindowshookex")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(HHOOK hhk);
/// Removes an event hook function created by a previous call to SetWinEventHook.
///
/// Type: HWINEVENTHOOK
/// Handle to the event hook returned in the previous call to SetWinEventHook.
///
///
/// Type: BOOL
/// If successful, returns TRUE; otherwise, returns FALSE.
/// Three common errors cause this function to fail:
///
/// -
/// The hWinEventHook parameter is NULL or not valid.
///
/// -
/// The event hook specified by hWinEventHook was already removed.
///
/// -
/// UnhookWinEvent is called from a thread that is different from the original call to SetWinEventHook.
///
///
///
///
///
/// This function removes the event hook specified by hWinEventHook that prevents the corresponding callback function from receiving
/// further event notifications. If the client's thread ends, the system automatically calls this function.
///
///
/// Call this function from the same thread that installed the event hook. UnhookWinEvent fails if called from a thread
/// different from the call that corresponds to SetWinEventHook.
///
///
/// If WINEVENT_INCONTEXT was specified when this event hook was installed, the system attempts to unload the corresponding DLL from
/// all processes that loaded it. Although unloading does not occur immediately, the hook function is not called after
/// UnhookWinEvent returns. For more information on WINEVENT_INCONTEXT, see In-Context Hook Functions.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unhookwinevent BOOL UnhookWinEvent( HWINEVENTHOOK
// hWinEventHook );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "5cffb279-85e1-4f7a-8bbb-d0d618f6afcd")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWinEvent(HWINEVENTHOOK hWinEventHook);
///
/// Contains information passed to a WH_CBT hook procedure, CBTProc, before a window is created.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagcbt_createwnda typedef struct tagCBT_CREATEWNDA {
// struct tagCREATESTRUCTA *lpcs; HWND hwndInsertAfter; } CBT_CREATEWNDA, *LPCBT_CREATEWNDA;
[PInvokeData("winuser.h", MSDNShortId = "cbt_createwnd.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CBT_CREATEWND
{
///
/// Type: LPCREATESTRUCT
/// A pointer to a CREATESTRUCT structure that contains initialization parameters for the window about to be created.
///
public IntPtr lpcs;
///
/// Type: HWND
///
/// A handle to the window whose position in the Z order precedes that of the window being created. This member can also be NULL.
///
///
public HWND hwndInsertAfter;
}
///
/// Contains information passed to a WH_CBT hook procedure, CBTProc, before a window is activated.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagcbtactivatestruct typedef struct tagCBTACTIVATESTRUCT {
// BOOL fMouse; HWND hWndActive; } CBTACTIVATESTRUCT, *LPCBTACTIVATESTRUCT;
[PInvokeData("winuser.h", MSDNShortId = "cbtactivatestruct.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CBTACTIVATESTRUCT
{
///
/// Type: BOOL
/// This member is TRUE if a mouse click is causing the activation or FALSE if it is not.
///
[MarshalAs(UnmanagedType.Bool)]
public bool fMouse;
///
/// Type: HWND
/// A handle to the active window.
///
public HWND hWndActive;
}
///
/// Defines the message parameters passed to a WH_CALLWNDPROCRET hook procedure, CallWndRetProc.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagcwpretstruct typedef struct tagCWPRETSTRUCT { LRESULT
// lResult; LPARAM lParam; WPARAM wParam; UINT message; HWND hwnd; } CWPRETSTRUCT, *PCWPRETSTRUCT, *NPCWPRETSTRUCT, *LPCWPRETSTRUCT;
[PInvokeData("winuser.h", MSDNShortId = "cwpretstruct.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CWPRETSTRUCT
{
///
/// Type: LRESULT
/// The return value of the window procedure that processed the message specified by the message value.
///
public IntPtr lResult;
///
/// Type: LPARAM
/// Additional information about the message. The exact meaning depends on the message value.
///
public IntPtr lParam;
///
/// Type: WPARAM
/// Additional information about the message. The exact meaning depends on the message value.
///
public IntPtr wParam;
///
/// Type: UINT
/// The message.
///
public uint message;
///
/// Type: HWND
/// A handle to the window that processed the message specified by the message value.
///
public HWND hwnd;
}
///
/// Defines the message parameters passed to a WH_CALLWNDPROC hook procedure, CallWndProc.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagcwpstruct typedef struct tagCWPSTRUCT { LPARAM lParam;
// WPARAM wParam; UINT message; HWND hwnd; } CWPSTRUCT, *PCWPSTRUCT, *NPCWPSTRUCT, *LPCWPSTRUCT;
[PInvokeData("winuser.h", MSDNShortId = "cwpstruct.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CWPSTRUCT
{
///
/// Type: LPARAM
/// Additional information about the message. The exact meaning depends on the message value.
///
public IntPtr lParam;
///
/// Type: WPARAM
/// Additional information about the message. The exact meaning depends on the message value.
///
public IntPtr wParam;
///
/// Type: UINT
/// The message.
///
public uint message;
///
/// Type: HWND
/// A handle to the window to receive the message.
///
public HWND hwnd;
}
///
/// Contains debugging information passed to a WH_DEBUG hook procedure, DebugProc.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagdebughookinfo typedef struct tagDEBUGHOOKINFO { DWORD
// idThread; DWORD idThreadInstaller; LPARAM lParam; WPARAM wParam; int code; } DEBUGHOOKINFO, *PDEBUGHOOKINFO, *NPDEBUGHOOKINFO, *LPDEBUGHOOKINFO;
[PInvokeData("winuser.h", MSDNShortId = "debughookinfo.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEBUGHOOKINFO
{
///
/// Type: DWORD
/// A handle to the thread containing the filter function.
///
public uint idThread;
///
/// Type: DWORD
/// A handle to the thread that installed the debugging filter function.
///
public uint idThreadInstaller;
///
/// Type: LPARAM
/// The value to be passed to the hook in the lParam parameter of the DebugProc callback function.
///
public IntPtr lParam;
///
/// Type: WPARAM
/// The value to be passed to the hook in the wParam parameter of the DebugProc callback function.
///
public IntPtr wParam;
///
/// Type: int
/// The value to be passed to the hook in the nCode parameter of the DebugProc callback function.
///
public int code;
}
///
///
/// Contains information about a hardware message sent to the system message queue. This structure is used to store message
/// information for the JournalPlaybackProc callback function.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tageventmsg typedef struct tagEVENTMSG { UINT message;
// UINT paramL; UINT paramH; DWORD time; HWND hwnd; } EVENTMSG, *PEVENTMSGMSG, *NPEVENTMSGMSG, *LPEVENTMSGMSG, *PEVENTMSG,
// *NPEVENTMSG, *LPEVENTMSG;
[PInvokeData("winuser.h", MSDNShortId = "eventmsg.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct EVENTMSG
{
///
/// Type: UINT
/// The message.
///
public uint message;
///
/// Type: UINT
/// Additional information about the message. The exact meaning depends on the message value.
///
public uint paramL;
///
/// Type: UINT
/// Additional information about the message. The exact meaning depends on the message value.
///
public uint paramH;
///
/// Type: DWORD
/// The time at which the message was posted.
///
public uint time;
///
/// Type: HWND
/// A handle to the window to which the message was posted.
///
public HWND hwnd;
}
/// Provides a handle to a hook.
[StructLayout(LayoutKind.Sequential)]
public struct HHOOK : IUserHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HHOOK(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HHOOK NULL => new HHOOK(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HHOOK h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HHOOK(IntPtr h) => new HHOOK(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HHOOK h1, HHOOK h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HHOOK h1, HHOOK h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HHOOK h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a handle to a Windows Event Hook.
[StructLayout(LayoutKind.Sequential)]
public struct HWINEVENTHOOK : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HWINEVENTHOOK(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HWINEVENTHOOK NULL => new HWINEVENTHOOK(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HWINEVENTHOOK h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HWINEVENTHOOK(IntPtr h) => new HWINEVENTHOOK(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HWINEVENTHOOK h1, HWINEVENTHOOK h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HWINEVENTHOOK h1, HWINEVENTHOOK h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HWINEVENTHOOK h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
///
/// Contains information about a low-level keyboard input event.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagkbdllhookstruct typedef struct tagKBDLLHOOKSTRUCT {
// DWORD vkCode; DWORD scanCode; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo; } KBDLLHOOKSTRUCT, *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
[PInvokeData("winuser.h", MSDNShortId = "kbdllhookstruct.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct KBDLLHOOKSTRUCT
{
///
/// Type: DWORD
/// A virtual-key code. The code must be a value in the range 1 to 254.
///
public uint vkCode;
///
/// Type: DWORD
/// A hardware scan code for the key.
///
public uint scanCode;
///
/// Type: DWORD
///
/// The extended-key flag, event-injected flags, context code, and transition-state flag. This member is specified as follows. An
/// application can use the following values to test the keystroke flags. Testing LLKHF_INJECTED (bit 4) will tell you whether
/// the event was injected. If it was, then testing LLKHF_LOWER_IL_INJECTED (bit 1) will tell you whether or not the event was
/// injected from a process running at lower integrity level.
///
///
///
/// Value
/// Meaning
///
/// -
/// LLKHF_EXTENDED (KF_EXTENDED >> 8)
/// Test the extended-key flag.
///
/// -
/// LLKHF_LOWER_IL_INJECTED 0x00000002
/// Test the event-injected (from a process running at lower integrity level) flag.
///
/// -
/// LLKHF_INJECTED 0x00000010
/// Test the event-injected (from any process) flag.
///
/// -
/// LLKHF_ALTDOWN (KF_ALTDOWN >> 8)
/// Test the context code.
///
/// -
/// LLKHF_UP (KF_UP >> 8)
/// Test the transition-state flag.
///
///
/// The following table describes the layout of this value.
///
///
/// Bits
/// Description
///
/// -
/// 0
///
/// Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the
/// key is an extended key; otherwise, it is 0.
///
///
/// -
/// 1
///
/// Specifies whether the event was injected from a process running at lower integrity level. The value is 1 if that is the case;
/// otherwise, it is 0. Note that bit 4 is also set whenever bit 1 is set.
///
///
/// -
/// 2-3
/// Reserved.
///
/// -
/// 4
///
/// Specifies whether the event was injected. The value is 1 if that is the case; otherwise, it is 0. Note that bit 1 is not
/// necessarily set when bit 4 is set.
///
///
/// -
/// 5
/// The context code. The value is 1 if the ALT key is pressed; otherwise, it is 0.
///
/// -
/// 6
/// Reserved.
///
/// -
/// 7
/// The transition state. The value is 0 if the key is pressed and 1 if it is being released.
///
///
///
public uint flags;
///
/// Type: DWORD
/// The time stamp for this message, equivalent to what GetMessageTime would return for this message.
///
public uint time;
///
/// Type: ULONG_PTR
/// Additional information associated with the message.
///
public UIntPtr dwExtraInfo;
}
///
/// Contains information about a mouse event passed to a WH_MOUSE hook procedure, MouseProc.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagmousehookstruct typedef struct tagMOUSEHOOKSTRUCT {
// POINT pt; HWND hwnd; UINT wHitTestCode; ULONG_PTR dwExtraInfo; } MOUSEHOOKSTRUCT, *LPMOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT;
[PInvokeData("winuser.h", MSDNShortId = "mousehookstruct.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MOUSEHOOKSTRUCT
{
///
/// Type: POINT
/// The x- and y-coordinates of the cursor, in screen coordinates.
///
public System.Drawing.Point pt;
///
/// Type: HWND
/// A handle to the window that will receive the mouse message corresponding to the mouse event.
///
public HWND hwnd;
///
/// Type: UINT
/// The hit-test value. For a list of hit-test values, see the description of the WM_NCHITTEST message.
///
public uint wHitTestCode;
///
/// Type: ULONG_PTR
/// Additional information associated with the message.
///
public UIntPtr dwExtraInfo;
}
///
/// Contains information about a mouse event passed to a WH_MOUSE hook procedure, MouseProc.
///
/// This is an extension of the MOUSEHOOKSTRUCT structure that includes information about wheel movement or the use of the X button.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagmousehookstructex typedef struct tagMOUSEHOOKSTRUCTEX {
// DWORD mouseData; base_class tagMOUSEHOOKSTRUCT; } MOUSEHOOKSTRUCTEX, *LPMOUSEHOOKSTRUCTEX, *PMOUSEHOOKSTRUCTEX;
[PInvokeData("winuser.h", MSDNShortId = "mousehookstructex.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MOUSEHOOKSTRUCTEX
{
///
/// Type: POINT
/// The x- and y-coordinates of the cursor, in screen coordinates.
///
public System.Drawing.Point pt;
///
/// Type: HWND
/// A handle to the window that will receive the mouse message corresponding to the mouse event.
///
public HWND hwnd;
///
/// Type: UINT
/// The hit-test value. For a list of hit-test values, see the description of the WM_NCHITTEST message.
///
public uint wHitTestCode;
///
/// Type: ULONG_PTR
/// Additional information associated with the message.
///
public UIntPtr dwExtraInfo;
///
/// Type: DWORD
///
/// If the message is WM_MOUSEWHEEL, the HIWORD of this member is the wheel delta. The LOWORD is undefined and reserved. A
/// positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel
/// was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.
///
///
/// If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, or WM_NCXBUTTONDBLCLK,
/// the HIWORD of mouseData specifies which X button was pressed or released, and the LOWORD is undefined and reserved.
/// This member can be one or more of the following values. Otherwise, mouseData is not used.
///
///
///
/// Value
/// Meaning
///
/// -
/// XBUTTON1 0x0001
/// The first X button was pressed or released.
///
/// -
/// XBUTTON2 0x0002
/// The second X button was pressed or released.
///
///
///
public uint mouseData;
}
///
/// Contains information about a low-level mouse input event.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagmsllhookstruct typedef struct tagMSLLHOOKSTRUCT { POINT
// pt; DWORD mouseData; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo; } MSLLHOOKSTRUCT, *LPMSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;
[PInvokeData("winuser.h", MSDNShortId = "msllhookstruct.htm")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MSLLHOOKSTRUCT
{
///
/// Type: POINT
/// The x- and y-coordinates of the cursor, in per-monitor-aware screen coordinates.
///
public System.Drawing.Point pt;
///
/// Type: DWORD
///
/// If the message is WM_MOUSEWHEEL, the high-order word of this member is the wheel delta. The low-order word is reserved. A
/// positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel
/// was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.
///
///
/// If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, or WM_NCXBUTTONDBLCLK,
/// the high-order word specifies which X button was pressed or released, and the low-order word is reserved. This value can be
/// one or more of the following values. Otherwise, mouseData is not used.
///
///
///
/// Value
/// Meaning
///
/// -
/// XBUTTON1 0x0001
/// The first X button was pressed or released.
///
/// -
/// XBUTTON2 0x0002
/// The second X button was pressed or released.
///
///
///
public uint mouseData;
///
/// Type: DWORD
///
/// The event-injected flags. An application can use the following values to test the flags. Testing LLMHF_INJECTED (bit 0) will
/// tell you whether the event was injected. If it was, then testing LLMHF_LOWER_IL_INJECTED (bit 1) will tell you whether or not
/// the event was injected from a process running at lower integrity level.
///
///
///
/// Value
/// Meaning
///
/// -
/// LLMHF_INJECTED 0x00000001
/// Test the event-injected (from any process) flag.
///
/// -
/// LLMHF_LOWER_IL_INJECTED 0x00000002
/// Test the event-injected (from a process running at lower integrity level) flag.
///
///
///
public uint flags;
///
/// Type: DWORD
/// The time stamp for this message.
///
public uint time;
///
/// Type: ULONG_PTR
/// Additional information associated with the message.
///
public UIntPtr dwExtraInfo;
}
/// Provides a for that is disposed using .
public class SafeHHOOK : SafeHANDLE, IUserHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHHOOK(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHHOOK() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HHOOK(SafeHHOOK h) => h.handle;
///
protected override bool InternalReleaseHandle() => UnhookWindowsHookEx(this);
}
}
}