public WindowLocationMonitor(Win32Window window, Win32Window relativeTo = null)
        {
            if (window == null)
            {
                throw new ArgumentNullException(nameof(window), "Contract assertion not met: window != null");
            }

            this.Window           = window;
            this.RelativeToWindow = relativeTo ?? new Win32Window(IntPtr.Zero);

            this.Process            = Window.GetProcess();
            this.WindowDraggingHook = new WinEventHook(this.Process, null,
                                                       WinEvent.EVENT_SYSTEM_FOREGROUND, WinEvent.EVENT_SYSTEM_MINIMIZEEND,
                                                       syncCtx: SynchronizationContext.Current);
            this.WindowDraggingHook
            .Where(c => c.WinObject == WinObject.OBJID_WINDOW && (
                       c.Event == WinEvent.EVENT_SYSTEM_FOREGROUND ||
                       c.Event == WinEvent.EVENT_SYSTEM_MOVESIZESTART ||
                       c.Event == WinEvent.EVENT_SYSTEM_MOVESIZEEND ||
                       c.Event == WinEvent.EVENT_SYSTEM_MINIMIZEEND ||
                       c.Event == WinEvent.EVENT_SYSTEM_MINIMIZESTART
                       ))
            .Subscribe(Hook_EventReceived);

            // LocationChange is required to support session connect rearrange, Win+Left, Minimize, Restore
            this.WindowMovedHook = new WinEventHook(Window.GetProcess(), null,
                                                    WinEvent.EVENT_OBJECT_LOCATIONCHANGE, WinEvent.EVENT_OBJECT_LOCATIONCHANGE,
                                                    syncCtx: SynchronizationContext.Current);
            this.WindowMovedHook
            .Where(c => c.WinObject == WinObject.OBJID_WINDOW && c.Window.Handle == Window.Handle)
            .Subscribe(Hook_EventReceived);
        }
 internal WinEventEventArgs(WinEventHook hook, WinEvent @event, IntPtr hwnd, WinObject @object, WinChild child, int threadId, uint time)
 {
     this.Hook      = hook;
     this.Event     = @event;
     this.Window    = new Win32Window(hwnd);
     this.WinObject = @object;
     this.WinChild  = child;
     this.ThreadId  = threadId;
     this.Timestamp = time;
 }