SetWinEventHook function

Sets an event hook function for a range of events.


  DWORD        eventMin,
  DWORD        eventMax,
  HMODULE      hmodWinEventProc,
  WINEVENTPROC pfnWinEventProc,
  DWORD        idProcess,
  DWORD        idThread,
  DWORD        dwFlags



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.



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.





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.



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.



Return Value


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.


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.

// Global variable.

// Initializes COM and sets up the event hook. // void InitializeMSAA() { CoInitialize(NULL); g_hook = SetWinEventHook( EVENT_SYSTEM_MENUSTART, EVENT_SYSTEM_MENUEND, // Range of events (4 to 5). NULL, // Handle to DLL. HandleWinEvent, // The callback. 0, 0, // Process and thread IDs of interest (0 = all) WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); // Flags. }

// Unhooks the event and shuts down COM. // void ShutdownMSAA() { UnhookWinEvent(g_hook); CoUninitialize(); }

// Callback function that handles events. // void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { IAccessible* pAcc = NULL; VARIANT varChild; HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);
if ((hr == S_OK) && (pAcc != NULL)) { BSTR bstrName; pAcc->get_accName(varChild, &bstrName); if (event == EVENT_SYSTEM_MENUSTART) { printf("Begin: "); } else if (event == EVENT_SYSTEM_MENUEND) { printf("End: "); } printf("%S\n", bstrName); SysFreeString(bstrName); pAcc->Release(); } }


Windows version Windows 2000 Professional [desktop apps only] Windows Server 2003 [desktop apps only]
Target Platform Windows
Header winuser.h (include Windows.h)
Library User32.lib
DLL User32.dll

See Also

Registering a Hook Function