public static IDisposable Subscribe(this IObserver <WinEventInfo> observer, WinEvents winEventStart, WinEvents winEventEnd, ObjectIdentifiers objectIdentifiers) { return(WinEventHook .Create(winEventStart, winEventEnd) .Where(x => x.IdChild == CHILDID_SELF && x.ObjectIdentifier == objectIdentifiers) .Subscribe(observer)); }
/// <summary> /// Create a WinEventHook as observable /// </summary> /// <param name="winEventStart">WinEvent "start" of which you are interested</param> /// <param name="winEventEnd">WinEvent "end" of which you are interested</param> /// <param name="process"></param> /// <param name="thread"></param> /// <returns>IObservable which procudes WinEventInfo</returns> public static IObservable <WinEventInfo> Create(WinEvents winEventStart, WinEvents?winEventEnd = null, int process = 0, int thread = 0) { return(Observable.Create <WinEventInfo>(observer => { void WinEventHookDelegate(IntPtr eventHook, WinEvents winEvent, IntPtr hwnd, ObjectIdentifiers idObject, int idChild, uint eventThread, uint eventTime) { observer.OnNext(WinEventInfo.Create(eventHook, winEvent, hwnd, idObject, idChild, eventThread, eventTime)); } WinEventDelegate winEventDelegate = WinEventHookDelegate; var hookPtr = SetWinEventHook(winEventStart, winEventEnd ?? winEventStart, IntPtr.Zero, winEventDelegate, process, thread, WinEventHookFlags.OutOfContext); if (hookPtr == IntPtr.Zero) { observer.OnError(new Win32Exception("Can't hook.")); return Disposable.Empty; } // Store to keep a reference to it, otherwise it's GC'ed Delegates[hookPtr] = winEventDelegate; return Disposable.Create(() => { UnhookWinEvent(hookPtr); Delegates.Remove(hookPtr); }); }) .Publish() .RefCount()); }
/// <summary> /// Create a WinEventInfo instance /// </summary> /// <param name="winEventHook"> /// 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. /// </param> /// <param name="winEvent">Specifies the event that occurred. This value is one of the event constants.</param> /// <param name="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. /// </param> /// <param name="idObject"> /// Identifies the object associated with the event. This is one of the object identifiers or a /// custom object ID. /// </param> /// <param name="idChild"> /// 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. /// </param> /// <param name="eventThread">Identifies the thread that generated the event, or the thread that owns the current window.</param> /// <param name="eventTime">Specifies the time, in milliseconds, that the event was generated.</param> /// <returns></returns> public static WinEventInfo Create(IntPtr winEventHook, WinEvents winEvent, IntPtr hWnd, ObjectIdentifiers idObject, long idChild, ulong eventThread, ulong eventTime) { return(new WinEventInfo { EventHook = winEventHook, WinEvent = winEvent, Handle = hWnd, ObjectIdentifier = idObject, IdChild = idChild, EventThread = eventThread, EventTime = eventTime }); }
/// <summary> /// Called whenever a WinEvent is received /// </summary> /// <param name="eventType">type of event received</param> /// <param name="hWnd">window concerned by event</param> void eventReceiver(WinEvents eventType, IntPtr hWnd) { switch (eventType) { case WinEvents.EVENT_SYSTEM_FOREGROUND: if (handledWindows.Contains(hWnd)) { if (FocusedWindow != hWnd) { //currentWorkspace.FocusWindow(handledWindows[hWnd]); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine('{' + hWnd.ToString() + "} focused (\"" + titles[hWnd] + "\")"); Console.ResetColor(); FocusedWindow = hWnd; LastHandledFocused = hWnd; } } else { FocusedWindow = (IntPtr)(-1); } break; case WinEvents.EVENT_OBJECT_NAMECHANGE: if (handledWindows.Contains(hWnd)) { string newTitle = GetWindowTitle(hWnd); if (newTitle != titles[hWnd]) { foreach (Workspace ws in workspaces.Values) { if (ws.ContainsWindow(hWnd)) { ws.WindowChangedTitle(hWnd); } } Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine('{' + hWnd.ToString() + "} changed title from \"" + titles[hWnd] + "\" to \"" + newTitle + "\""); Console.ResetColor(); titles[hWnd] = newTitle; } } break; } }
private static extern IntPtr SetWinEventHook(WinEvents eventMin, WinEvents eventMax, IntPtr hmodWinEventProc, WinEventDelegate eventProc, int idProcess, int idThread, WinEventHookFlags winEventHookFlags);
public static IDisposable Subscribe(this IObserver <WinEventInfo> observer, WinEvents winEvent, ObjectIdentifiers objectIdentifiers) { return(Subscribe(observer, winEvent, winEvent, objectIdentifiers)); }
public WinEventHook(WinEvents from, WinEvents to) { eventProcessor = new winEventDelegate(processListeners); hookHandle = SetWinEventHook((uint)from, (uint)to, IntPtr.Zero, eventProcessor, 0, 0, WINEVENT_OUTOFCONTEXT); }