Beispiel #1
0
 /// <summary>
 /// Event Handler - listens to events in the hook manager.
 /// Sends the new messege to the backgound worker of the mainlogic.
 /// the background worker will prosess all the data and will send updates to the GUI when it is done.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 public void Manager_WindowChanged(object sender, WindowChangedEventArgs e)
 {
     if (!backgroundLogic.managerWindowChangedWorker.IsBusy)
     {
         backgroundLogic.managerWindowChangedWorker.RunWorkerAsync();
     }
 }
Beispiel #2
0
 protected void OnFocusChange(WindowChangedEventArgs eventArgs)
 {
     if (FocusChange != null)
     {
         FocusChange.Invoke(this, eventArgs);
     }
 }
Beispiel #3
0
        private void OnVbeFocusChanged(object sender, WindowChangedEventArgs e)
        {
            if (e.EventType == FocusType.GotFocus)
            {
                switch (e.Window.Type)
                {
                case WindowKind.Designer:
                    //Designer or control on designer form selected.
                    if (e.Window == null || e.Window.IsWrappingNullReference || e.Window.Type != WindowKind.Designer)
                    {
                        return;
                    }
                    new Task(() => DispatchSelectedDesignerDeclaration(_vbe.SelectedVBComponent)).Start();
                    break;

                case WindowKind.CodeWindow:
                    //Caret changed in a code pane.
                    if (e.CodePane != null && !e.CodePane.IsWrappingNullReference)
                    {
                        new Task(() => DispatchSelectedDeclaration(new DeclarationChangedEventArgs(e.CodePane, _parser.State.FindSelectedDeclaration(e.CodePane)))).Start();
                    }
                    break;
                }
            }
            else if (e.EventType == FocusType.ChildFocus)
            {
                //Treeview selection changed in project window.
                new Task(() => DispatchSelectedProjectNodeDeclaration(_vbe.SelectedVBComponent)).Start();
            }
        }
Beispiel #4
0
 /// <summary>
 /// Called if the active window changes.
 /// </summary>
 /// <param name="e"></param>
 protected void OnActiveWindowChangedEvent(WindowChangedEventArgs e)
 {
     if (this.ActiveWindowChangedEvent != null)
     {
         this.ActiveWindowChangedEvent(this, e);
     }
 }
Beispiel #5
0
        private void OnVbeFocusChanged(object sender, WindowChangedEventArgs e)
        {
            if (e.EventType == FocusType.GotFocus)
            {
                switch (e.Hwnd.ToWindowType())
                {
                case WindowType.DesignerWindow:
                    Task.Run(() =>
                    {
                        using (var component = _vbe.SelectedVBComponent)
                        {
                            DispatchSelectedDesignerDeclaration(component);
                        }
                    });
                    break;

                case WindowType.CodePane:
                    //Caret changed in a code pane.
                    Task.Run(() =>
                    {
                        using (var pane = VbeNativeServices.GetCodePaneFromHwnd(e.Hwnd))
                        {
                            var selection = pane.GetQualifiedSelection();
                            if (!selection.HasValue)
                            {
                                return;
                            }

                            var selectedDeclaration = _selectedDeclarationProvider.SelectedDeclaration(selection.Value);
                            var eventArgs           = new DeclarationChangedEventArgs(_vbe, selectedDeclaration);
                            DispatchSelectedDeclaration(eventArgs);
                        }
                    });
                    break;
                }
            }
            else if (e.EventType == FocusType.ChildFocus)
            {
                //Treeview selection changed in project window.
                Task.Run(() =>
                {
                    using (var component = _vbe.SelectedVBComponent)
                    {
                        DispatchSelectedProjectNodeDeclaration(component);
                    }
                });
            }
        }
        private void OnVbeFocusChanged(object sender, WindowChangedEventArgs e)
        {
            if (e.EventType == FocusType.GotFocus)
            {
                switch (e.Hwnd.ToWindowType())
                {
                case WindowType.DesignerWindow:
                    Task.Run(() =>
                    {
                        using (var component = _vbe.SelectedVBComponent)
                        {
                            DispatchSelectedDesignerDeclaration(component);
                        }
                    });
                    break;

                case WindowType.CodePane:
                    //Caret changed in a code pane.
                    Task.Run(() =>
                    {
                        using (var pane = VbeNativeServices.GetCodePaneFromHwnd(e.Hwnd))
                        {
                            DispatchSelectedDeclaration(
                                new DeclarationChangedEventArgs(_vbe, _parser.State.FindSelectedDeclaration(pane)));
                        }
                    });
                    break;
                }
            }
            else if (e.EventType == FocusType.ChildFocus)
            {
                //Treeview selection changed in project window.
                Task.Run(() =>
                {
                    using (var component = _vbe.SelectedVBComponent)
                    {
                        DispatchSelectedProjectNodeDeclaration(component);
                    }
                });
            }
        }
Beispiel #7
0
        /// <summary>
        /// Reports that an element value has changed.
        /// </summary>
        /// <param name="elementid">DWORD value representing a particular entry in the array of element values associated with the selection context. For valid elementid values, see VSConstants.VSSELELEMID.</param>
        /// <param name="varValueOld">VARIANT that contains the previous element value. This parameter contains element-specific data, such as a pointer to the IOleCommandTarget interface if elementid is set to SEID_ResultsList or a pointer to the IOleUndoManager interface if elementid is set to SEID_UndoManager.</param>
        /// <param name="varValueNew">VARIANT that contains the new element value. This parameter contains element-specific data, such as a pointer to the IOleCommandTarget interface if elementid is set to SEID_ResultsList or a pointer to the IOleUndoManager interface if elementid is set to SEID_UndoManager.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public virtual int OnElementValueChanged(uint elementid, object varValueOld, object varValueNew)
        {
            if (elementid == (uint)VSConstants.VSSELELEMID.SEID_WindowFrame)
            {
                IVsWindowFrame oldFrame = (IVsWindowFrame)varValueOld;
                IVsWindowFrame newFrame = (IVsWindowFrame)varValueNew;

                WindowChangedEventArgs args = new WindowChangedEventArgs();
                if (oldFrame != null)
                {
                    args.OldData = ParseFrame(oldFrame);
                }

                if (newFrame != null)
                {
                    args.NewData = ParseFrame(newFrame);
                }

                this.OnActiveWindowChangedEvent(args);
            }
            return(VSConstants.S_OK);
        }
Beispiel #8
0
            private void WatchWindow()
            {
                IntPtr handle;

                try
                {
                    handle = process.MainWindowHandle;
                }
                catch (Exception e)
                {
                    Util.Logging.Log(e);
                    return;
                }

                Windows.FindWindow.TextComparer classCallback = new Windows.FindWindow.TextComparer(
                    delegate(string name, StringBuilder sb)
                {
                    if (sb.Length == EDIT_CLASSNAME.Length)
                    {
                        return(sb.ToString().Equals(EDIT_CLASSNAME));
                    }
                    return(false);
                });

                Windows.FindWindow.TextComparer textCallback = new Windows.FindWindow.TextComparer(
                    delegate(string name, StringBuilder sb)
                {
                    if (name != null && name.Equals(EDIT_CLASSNAME))
                    {
                        return(sb.Length > 500 && sb[0] == '*');
                    }

                    return(true);
                });

                StringBuilder buffer = new StringBuilder(DX_WINDOW_CLASSNAME.Length);
                int           length = 0;

                var wce     = new WindowChangedEventArgs();
                var _handle = IntPtr.Zero;

                //watched for windowed mode process exit with no handle -- likely an invisible crash due to outdated Local.dat

                do
                {
                    try
                    {
                        process.Refresh();
                        handle = process.MainWindowHandle;
                    }
                    catch (Exception e)
                    {
                        Util.Logging.Log(e);
                    }

                    try
                    {
                        if (this.process.HasExited)
                        {
                            if (handle == IntPtr.Zero && (IsAutomaticLogin(this.Account.Settings) || Util.Args.Contains(this.Args, "nopatchui")))
                            {
                                var elapsed = this.process.ExitTime.Subtract(this.process.StartTime).TotalSeconds;
                                if (elapsed < 60 && WindowCrashed != null)
                                {
                                    WindowCrashed(this, CrashReason.NoPatchUI);
                                }
                            }

                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        Util.Logging.Log(e);
                        return;
                    }

                    if (handle != IntPtr.Zero)
                    {
                        if (_handle != handle)
                        {
                            _handle    = handle;
                            wce.Handle = handle;

                            if (WindowChanged != null)
                            {
                                wce.Type = WindowChangedEventArgs.EventType.HandleChanged;
                                WindowChanged(this, wce);
                            }
                        }

                        buffer.Length = 0;
                        NativeMethods.GetClassName(handle, buffer, buffer.Capacity + 1);

                        int l;
                        if ((l = buffer.Length) != length)
                        {
                            length = l;

                            if (l > 0)
                            {
                                string className = buffer.ToString();
                                if (className.Equals(DX_WINDOW_CLASSNAME))
                                {
                                    if (WindowChanged != null)
                                    {
                                        wce.Type = WindowChangedEventArgs.EventType.DxWindowCreated;
                                        WindowChanged(this, wce);
                                    }

                                    try
                                    {
                                        var t = DateTime.UtcNow.AddSeconds(30);

                                        do
                                        {
                                            buffer.Length = 0;
                                            if (NativeMethods.GetWindowText(handle, buffer, 2) > 0 && buffer[0] != 'U') //window text is initially Untitled
                                            {
                                                if (WindowChanged != null)
                                                {
                                                    wce.Type = WindowChangedEventArgs.EventType.TitleChanged;
                                                    WindowChanged(this, wce);
                                                }

                                                break;
                                            }
                                        }while (DateTime.UtcNow < t && !process.WaitForExit(100));
                                    }
                                    catch (Exception e)
                                    {
                                        Util.Logging.Log(e);
                                    }

                                    using (var volumeControl = new Windows.Volume.VolumeControl(process.Id))
                                    {
                                        //already loaded if audio is initialized (only checks default playback device)
                                        var hasVolume = volumeControl.Query();

                                        if (hasVolume)
                                        {
                                            if (WindowChanged != null && !this.process.HasExited)
                                            {
                                                wce.Type = WindowChangedEventArgs.EventType.DxWindowReady;
                                                WindowChanged(this, wce);
                                            }

                                            return;
                                        }

                                        var nextCheck_Seconds = 3;
                                        var memoryUsage       = process.PeakWorkingSet64;
                                        var limit             = DateTime.UtcNow.AddMinutes(3);
                                        var nextCheck         = DateTime.UtcNow.AddSeconds(nextCheck_Seconds);
                                        var memoryChecks      = 0;
                                        //var verified = false;

                                        do
                                        {
                                            //the volume will be initialized first, then a child process (CoherentUI) will spawn
                                            if (hasVolume = volumeControl.Query() || HasChildProcess(process.Id))
                                            {
                                                break;
                                            }

                                            //watching for changes in memory usage to check if it's still doing something
                                            //bypassing the launching can cause it to get stuck on authentication if either the credentials are wrong or the network isn't authorized
                                            if (watchAutologin && DateTime.UtcNow > nextCheck)
                                            {
                                                process.Refresh();

                                                var memoryChange = process.PeakWorkingSet64 - memoryUsage;
                                                memoryUsage += memoryChange;

                                                if (memoryChange < 1000000)
                                                {
                                                    if (++memoryChecks == 3)
                                                    {
                                                        //this account may be stuck trying to authenticate

                                                        var account = this.Account.Settings;
                                                        if (account.HasCredentials && account.NetworkAuthorizationState != Settings.NetworkAuthorizationState.Disabled && Settings.NetworkAuthorization.HasValue)
                                                        {
                                                            if (account.NetworkAuthorizationState == Settings.NetworkAuthorizationState.Unknown)
                                                            {
                                                                if (AuthenticationRequired != null)
                                                                {
                                                                    AuthenticationRequired(this, null);
                                                                }

                                                                return;
                                                            }
                                                            else
                                                            {
                                                                Tools.ArenaAccount session;
                                                                switch (NetworkAuthorization.Verify(account, true, null, out session))
                                                                {
                                                                case NetworkAuthorization.VerifyResult.Completed:
                                                                case NetworkAuthorization.VerifyResult.Required:

                                                                    if (AuthenticationRequired != null)
                                                                    {
                                                                        AuthenticationRequired(this, session);
                                                                    }

                                                                    return;

                                                                case NetworkAuthorization.VerifyResult.OK:

                                                                    //authentication was ok - assuming it's a slow load
                                                                    nextCheck_Seconds = 10;
                                                                    //verified = true;

                                                                    break;

                                                                case NetworkAuthorization.VerifyResult.None:
                                                                default:

                                                                    //authentication isn't being tracked - assuming it's stuck
                                                                    nextCheck_Seconds = 10;

                                                                    break;
                                                                }
                                                            }
                                                        }
                                                        else
                                                        {
                                                            //authentication isn't enabled
                                                            nextCheck_Seconds = 10;
                                                        }
                                                    }
                                                    else if (memoryChecks > 6)
                                                    {
                                                        if (AuthenticationRequired != null)
                                                        {
                                                            AuthenticationRequired(this, null);
                                                        }

                                                        return;
                                                    }
                                                }
                                                else
                                                {
                                                    memoryChecks = 0;
                                                }

                                                nextCheck = DateTime.UtcNow.AddSeconds(nextCheck_Seconds);
                                            }
                                        }while (DateTime.UtcNow < limit && !this.process.WaitForExit(500));

                                        if (WindowChanged != null && !this.process.HasExited)
                                        {
                                            wce.Type = WindowChangedEventArgs.EventType.DxWindowReady;
                                            WindowChanged(this, wce);
                                        }

                                        return;
                                    }
                                }
                                else if (className[0] == '#')
                                {
                                    var result = Find(handle, classCallback, textCallback);
                                    if (result != null)
                                    {
                                        CrashReason reason = CrashReason.Unknown;

                                        string text = result.Text;
                                        int    i    = text.IndexOf("Assertion:", 0, 100);
                                        if (i != -1)
                                        {
                                            int j = text.IndexOf('\n', i);
                                            if (text.IndexOf("Is your archive up to date?", i, j - i, StringComparison.OrdinalIgnoreCase) != -1 ||
                                                text.IndexOf("Client needs to be patched", i, j - i, StringComparison.OrdinalIgnoreCase) != -1)
                                            {
                                                reason = CrashReason.PatchRequired;
                                            }
                                        }

                                        if (WindowCrashed != null)
                                        {
                                            WindowCrashed(this, reason);
                                        }
                                    }
                                    return;
                                }
                                else if (className.Equals(LAUNCHER_WINDOW_CLASSNAME))
                                {
                                    if (WindowChanged != null)
                                    {
                                        wce.Type = WindowChangedEventArgs.EventType.TitleChanged;
                                        WindowChanged(this, wce);
                                    }
                                }
                            }
                        }
                    }
                }while (!process.WaitForExit(500) && this.watcher != null);
            }
Beispiel #9
0
        protected virtual void OnWindowChanged()
        {
            WindowChangedEventArgs args = new WindowChangedEventArgs();

            WindowChanged?.Invoke(this, args);
        }
 /// <summary>
 /// Called if the active window changes.
 /// </summary>
 /// <param name="e"></param>
 protected void OnActiveWindowChangedEvent(WindowChangedEventArgs e)
 {
     if (this.ActiveWindowChangedEvent != null)
         this.ActiveWindowChangedEvent(this, e);
 }
        /// <summary>
        /// Reports that an element value has changed.
        /// </summary>
        /// <param name="elementid">DWORD value representing a particular entry in the array of element values associated with the selection context. For valid elementid values, see VSConstants.VSSELELEMID.</param>
        /// <param name="varValueOld">VARIANT that contains the previous element value. This parameter contains element-specific data, such as a pointer to the IOleCommandTarget interface if elementid is set to SEID_ResultsList or a pointer to the IOleUndoManager interface if elementid is set to SEID_UndoManager.</param>
        /// <param name="varValueNew">VARIANT that contains the new element value. This parameter contains element-specific data, such as a pointer to the IOleCommandTarget interface if elementid is set to SEID_ResultsList or a pointer to the IOleUndoManager interface if elementid is set to SEID_UndoManager.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public virtual int OnElementValueChanged(uint elementid, object varValueOld, object varValueNew)
        {
            if (elementid == (uint)VSConstants.VSSELELEMID.SEID_WindowFrame)
            {
                IVsWindowFrame oldFrame = (IVsWindowFrame)varValueOld;
                IVsWindowFrame newFrame = (IVsWindowFrame)varValueNew;

                WindowChangedEventArgs args = new WindowChangedEventArgs();
                if (oldFrame != null)
                {
                    args.OldData = ParseFrame(oldFrame);
                }

                if (newFrame != null)
                {
                    args.NewData = ParseFrame(newFrame);
                }

                this.OnActiveWindowChangedEvent(args);
            }
            return VSConstants.S_OK;
        }
Beispiel #12
0
 /// <summary>
 /// the general subscriber for all windows events.
 /// each objects publishes an event with the same delegate. they all sbscribed here.
 /// if the window title or the process have changed - than invoke the rest of the events in the middle man and so on.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void Manager_WindowChanged(object sender, WindowChangedEventArgs e)
 {
     WindowChanged?.Invoke(sender, e);
 }
Beispiel #13
0
        // This runs on the Automation thread, via SyncContextAuto passed in to WinEventHook when we created this WindowWatcher
        // CONSIDER: We would be able to run all the watcher updates from WinEvents, including Location and Selection changes,
        //           but since WinEvents have no hwnd filter, UIAutomation events might be more efficient.
        // CONSIDER: Performance optimisation would keep a list of window handles we know about, preventing the class name check every time
        void _windowStateChangeHook_WinEventReceived(object sender, WinEventHook.WinEventArgs e)
        {
            if (!WindowChangedEventArgs.IsSupportedWinEvent(e.EventType))
            {
                return;
            }

            var className = Win32Helper.GetClassName(e.WindowHandle);

            if (e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_FOCUS)
            {
                // Might raise change event for Unfocus
                if (!UpdateFocus(e.WindowHandle, className))
                {
                    // We already have the right focus
                    return;
                }
            }

            // Debug.Print("### Thread receiving WindowStateChange: " + Thread.CurrentThread.ManagedThreadId);
            switch (className)
            {
            //case _sheetWindowClass:
            //    if (e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_SHOW)
            //    {
            //        // Maybe a new workbook is on top...
            //        // Note that there is also an EVENT_OBJECT_PARENTCHANGE (which we are not subscribing to at the moment
            //    }
            //    break;
            case _popupListClass:
                PopupListWindowChanged?.Invoke(this, new WindowChangedEventArgs(e.WindowHandle, e.EventType));
                break;

            case _inCellEditClass:
                InCellEditWindowChanged?.Invoke(this, new WindowChangedEventArgs(e.WindowHandle, e.EventType));
                break;

            case _formulaBarClass:
                FormulaBarWindowChanged?.Invoke(this, new WindowChangedEventArgs(e.WindowHandle, e.EventType));
                break;

            case _excelToolTipClass:
                ExcelToolTipWindowChanged?.Invoke(this, new WindowChangedEventArgs(e.WindowHandle, e.EventType));
                break;

            //case _nuiDialogClass:
            //    // Debug.Print($"SelectDataSource {_selectDataSourceClass} Window update: {e.WindowHandle:X}, EventType: {e.EventType}, idChild: {e.ChildId}");
            //    if (e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_CREATE)
            //    {
            //        // Get the name of this window - maybe ours or some other NUIDialog
            //        var windowTitle = Win32Helper.GetText(e.WindowHandle);
            //        if (windowTitle.Equals(_selectDataSourceTitle, StringComparison.OrdinalIgnoreCase))
            //        {
            //            SelectDataSourceWindow = e.WindowHandle;
            //            SelectDataSourceWindowChanged?.Invoke(this,
            //                new WindowChangedEventArgs { Type = WindowChangedEventArgs.ChangeType.Create });
            //        }
            //    }
            //    else if (SelectDataSourceWindow == e.WindowHandle && e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_SHOW)
            //    {
            //        IsSelectDataSourceWindowVisible = true;
            //        SelectDataSourceWindowChanged?.Invoke(this,
            //                new WindowChangedEventArgs { Type = WindowChangedEventArgs.ChangeType.Create });
            //    }
            //    else if (SelectDataSourceWindow == e.WindowHandle && e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_HIDE)
            //    {
            //        IsSelectDataSourceWindowVisible = false;
            //        SelectDataSourceWindowChanged?.Invoke(this, new WindowChangedEventArgs { Type = WindowChangedEventArgs.ChangeType.Hide });
            //    }
            //    else if (SelectDataSourceWindow == e.WindowHandle && e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_DESTROY)
            //    {
            //        IsSelectDataSourceWindowVisible = false;
            //        SelectDataSourceWindow = IntPtr.Zero;
            //        SelectDataSourceWindowChanged?.Invoke(this, new WindowChangedEventArgs { Type = WindowChangedEventArgs.ChangeType.Destroy });
            //    }
            //    break;
            default:
                //InCellEditWindowChanged(this, EventArgs.Empty);
                break;
            }
        }
Beispiel #14
0
            private void WatchWindow()
            {
                IntPtr handle;

                try
                {
                    handle = process.MainWindowHandle;
                }
                catch (Exception e)
                {
                    Util.Logging.Log(e);
                    return;
                }

                Windows.FindWindow.TextComparer classCallback = new Windows.FindWindow.TextComparer(
                    delegate(string name, StringBuilder sb)
                {
                    if (sb.Length == EDIT_CLASSNAME.Length)
                    {
                        return(sb.ToString().Equals(EDIT_CLASSNAME));
                    }
                    return(false);
                });

                Windows.FindWindow.TextComparer textCallback = new Windows.FindWindow.TextComparer(
                    delegate(string name, StringBuilder sb)
                {
                    if (name != null && name.Equals(EDIT_CLASSNAME))
                    {
                        return(sb.Length > 500 && sb[0] == '*');
                    }

                    return(true);
                });

                StringBuilder buffer = new StringBuilder(DX_WINDOW_CLASSNAME.Length);
                int           length = 0;

                var wce     = new WindowChangedEventArgs();
                var _handle = IntPtr.Zero;

                do
                {
                    try
                    {
                        do
                        {
                            process.Refresh();
                            handle = process.MainWindowHandle;

                            if (handle == IntPtr.Zero)
                            {
                                if (!process.WaitForExit(10))
                                {
                                    process.WaitForInputIdle();
                                }
                            }
                            else
                            {
                                break;
                            }
                        }while (!process.HasExited);
                    }
                    catch (Exception e)
                    {
                        Util.Logging.Log(e);
                    }

                    try
                    {
                        if (this.process.HasExited)
                        {
                            //no longer applicable - nopatchui exiting without creating a window likely meant the client wasn't up to date

                            //if (handle == IntPtr.Zero && (IsAutomaticLogin(this.Account.Settings) || Util.Args.Contains(this.Args, "nopatchui")))
                            //{
                            //    var elapsed = this.process.ExitTime.Subtract(this.process.StartTime).TotalSeconds;
                            //    if (elapsed < 60 && WindowCrashed != null)
                            //        WindowCrashed(this, CrashReason.NoPatchUI);
                            //}
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        Util.Logging.Log(e);
                        return;
                    }

                    if (handle != IntPtr.Zero)
                    {
                        if (_handle != handle)
                        {
                            _handle    = handle;
                            wce.Handle = handle;

                            if (WindowChanged != null)
                            {
                                wce.Type = WindowChangedEventArgs.EventType.HandleChanged;
                                WindowChanged(this, wce);
                            }
                        }

                        buffer.Length = 0;
                        NativeMethods.GetClassName(handle, buffer, buffer.Capacity + 1);

                        int l;
                        if ((l = buffer.Length) != length)
                        {
                            length = l;

                            if (l > 0)
                            {
                                string className = buffer.ToString();
                                if (className.Equals(DX_WINDOW_CLASSNAME))
                                {
                                    if (WindowChanged != null)
                                    {
                                        wce.Type = WindowChangedEventArgs.EventType.DxWindowCreated;
                                        WindowChanged(this, wce);
                                    }

                                    //window initialization order:
                                    //title change > volume (window is ready) > coherentui

                                    int      pidChild  = 0;
                                    bool     hasVolume = false;
                                    DateTime limit;

                                    using (var volumeControl = new Windows.Volume.VolumeControl(process.Id))
                                    {
                                        if (processWasAlreadyStarted && ((hasVolume = volumeControl.Query()) || (pidChild = GetChildProcess(process.Id)) > 0))
                                        {
                                            //window is already loaded

                                            if (WindowChanged != null)
                                            {
                                                wce.Type = WindowChangedEventArgs.EventType.TitleChanged;
                                                WindowChanged(this, wce);
                                            }

                                            limit = DateTime.UtcNow.AddMinutes(1);
                                        }
                                        else
                                        {
                                            try
                                            {
                                                limit = DateTime.UtcNow.AddSeconds(30);
                                                var ws1 = IntPtr.Zero;

                                                do
                                                {
                                                    //window style changes when loading into fullscreen mode
                                                    var ws2 = NativeMethods.GetWindowLongPtr(handle, (int)GWL.GWL_STYLE);
                                                    if (ws2 != ws1)
                                                    {
                                                        if (ws1 != IntPtr.Zero && WindowChanged != null)
                                                        {
                                                            wce.Type = WindowChangedEventArgs.EventType.DxWindowStyleChanged;
                                                            WindowChanged(this, wce);
                                                        }

                                                        ws1 = ws2;
                                                    }

                                                    buffer.Length = 0;
                                                    if (NativeMethods.GetWindowText(handle, buffer, 2) > 0 && buffer[0] != 'U') //window text is initially Untitled
                                                    {
                                                        if (WindowChanged != null)
                                                        {
                                                            wce.Type = WindowChangedEventArgs.EventType.TitleChanged;
                                                            WindowChanged(this, wce);
                                                        }

                                                        break;
                                                    }
                                                }while (DateTime.UtcNow < limit && !process.WaitForExit(100));
                                            }
                                            catch (Exception e)
                                            {
                                                Util.Logging.Log(e);
                                            }

                                            var nextCheck_Seconds = 3;
                                            var memoryUsage       = process.PeakWorkingSet64;
                                            var nextCheck         = DateTime.UtcNow.AddSeconds(nextCheck_Seconds);
                                            var memoryChecks      = 0;
                                            //var verified = false;

                                            limit = DateTime.UtcNow.AddMinutes(3);

                                            do
                                            {
                                                if ((hasVolume = volumeControl.Query()) || (pidChild = GetChildProcess(process.Id)) > 0)
                                                {
                                                    break;
                                                }

                                                #region -nopatchui activity check (obsolete)

                                                //watching for changes in memory usage to check if it's still doing something
                                                //bypassing the launcher (-nopatchui) can cause it to get stuck on authentication if either the credentials are wrong or the network isn't authorized
                                                if (!hasVolume && DateTime.UtcNow > nextCheck)
                                                {
                                                    process.Refresh();

                                                    var memoryChange = process.PeakWorkingSet64 - memoryUsage;
                                                    memoryUsage += memoryChange;

                                                    if (memoryChange < 1000000)
                                                    {
                                                        if (++memoryChecks == 3)
                                                        {
                                                            //this account may be stuck trying to authenticate

                                                            var account = this.Account.Settings;
                                                            if (account.HasCredentials && account.NetworkAuthorizationState != Settings.NetworkAuthorizationState.Disabled && Settings.NetworkAuthorization.HasValue)
                                                            {
                                                                if (account.NetworkAuthorizationState == Settings.NetworkAuthorizationState.Unknown)
                                                                {
                                                                    if (AuthenticationRequired != null)
                                                                    {
                                                                        AuthenticationRequired(this, null);
                                                                    }

                                                                    return;
                                                                }
                                                                else
                                                                {
                                                                    Tools.ArenaAccount session;
                                                                    switch (NetworkAuthorization.Verify(account, true, null, out session))
                                                                    {
                                                                    case NetworkAuthorization.VerifyResult.Completed:
                                                                    case NetworkAuthorization.VerifyResult.Required:

                                                                        if (AuthenticationRequired != null)
                                                                        {
                                                                            AuthenticationRequired(this, session);
                                                                        }

                                                                        return;

                                                                    case NetworkAuthorization.VerifyResult.OK:

                                                                        //authentication was ok - assuming it's a slow load
                                                                        nextCheck_Seconds = 10;
                                                                        //verified = true;

                                                                        break;

                                                                    case NetworkAuthorization.VerifyResult.None:
                                                                    default:

                                                                        //authentication isn't being tracked - assuming it's stuck
                                                                        nextCheck_Seconds = 10;

                                                                        break;
                                                                    }
                                                                }
                                                            }
                                                            else
                                                            {
                                                                //authentication isn't enabled
                                                                nextCheck_Seconds = 10;
                                                            }
                                                        }
                                                        else if (memoryChecks > 6)
                                                        {
                                                            if (AuthenticationRequired != null)
                                                            {
                                                                AuthenticationRequired(this, null);
                                                            }

                                                            return;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        memoryChecks = 0;
                                                    }

                                                    nextCheck = DateTime.UtcNow.AddSeconds(nextCheck_Seconds);
                                                }

                                                #endregion
                                            }while (DateTime.UtcNow < limit && !this.process.WaitForExit(500));
                                        }
                                    }

                                    if (WindowChanged != null && !this.process.HasExited)
                                    {
                                        wce.Type = WindowChangedEventArgs.EventType.DxWindowReady;
                                        WindowChanged(this, wce);
                                    }

                                    #region Find CoherentUI

                                    if (pidChild == 0)
                                    {
                                        do
                                        {
                                            if ((pidChild = GetChildProcess(process.Id)) > 0)
                                            {
                                                break;
                                            }
                                        }while (DateTime.UtcNow < limit && !this.process.WaitForExit(500));
                                    }

                                    if (pidChild > 0)
                                    {
                                        try
                                        {
                                            using (var child = Process.GetProcessById(pidChild))
                                            {
                                                limit = DateTime.UtcNow.AddSeconds(10);
                                                var pid = pidChild;

                                                do
                                                {
                                                    if ((pidChild = GetChildProcess(pid)) > 0)
                                                    {
                                                        break;
                                                    }
                                                }while (DateTime.UtcNow < limit && !child.WaitForExit(500));
                                            }

                                            if (pidChild > 0)
                                            {
                                                using (var child = Process.GetProcessById(pidChild))
                                                {
                                                    long mem     = 0;
                                                    byte counter = 0;
                                                    limit = DateTime.UtcNow.AddSeconds(60);

                                                    do
                                                    {
                                                        if (mem > 0)
                                                        {
                                                            child.Refresh();
                                                        }
                                                        var _mem = child.PeakWorkingSet64;
                                                        if (_mem > mem)
                                                        {
                                                            mem     = _mem;
                                                            counter = 0;
                                                        }
                                                        else if (++counter > 2)
                                                        {
                                                            break;
                                                        }
                                                    }while (DateTime.UtcNow < limit && !child.WaitForExit(100));
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            Util.Logging.Log(ex);
                                        }
                                    }

                                    #endregion

                                    if (WindowChanged != null && !this.process.HasExited)
                                    {
                                        wce.Type = WindowChangedEventArgs.EventType.InGameCoherentUIReady;
                                        WindowChanged(this, wce);
                                    }

                                    return;
                                }
                                else if (className[0] == '#')
                                {
                                    var result = Find(handle, classCallback, textCallback);
                                    if (result != null)
                                    {
                                        CrashReason reason = CrashReason.Unknown;

                                        string text = result.Text;
                                        int    i    = text.IndexOf("Assertion:", 0, 100);
                                        if (i != -1)
                                        {
                                            int j = text.IndexOf('\n', i);
                                            if (text.IndexOf("Is your archive up to date?", i, j - i, StringComparison.OrdinalIgnoreCase) != -1 ||
                                                text.IndexOf("Client needs to be patched", i, j - i, StringComparison.OrdinalIgnoreCase) != -1)
                                            {
                                                reason = CrashReason.PatchRequired;
                                            }
                                        }

                                        if (WindowCrashed != null)
                                        {
                                            WindowCrashed(this, reason);
                                        }
                                    }
                                    return;
                                }
                                else if (className.Equals(LAUNCHER_WINDOW_CLASSNAME))
                                {
                                    if (WindowChanged != null)
                                    {
                                        wce.Type = WindowChangedEventArgs.EventType.TitleChanged;
                                        WindowChanged(this, wce);
                                    }

                                    #region Find CoherentUI

                                    var pidChild = 0;
                                    var limit    = DateTime.UtcNow.AddSeconds(30);

                                    do
                                    {
                                        if ((pidChild = GetChildProcess(process.Id)) > 0)
                                        {
                                            break;
                                        }

                                        this.process.Refresh();
                                        if (_handle != this.process.MainWindowHandle)
                                        {
                                            break;
                                        }
                                    }while (DateTime.UtcNow < limit && !this.process.WaitForExit(500));

                                    if (pidChild > 0)
                                    {
                                        try
                                        {
                                            using (var child = Process.GetProcessById(pidChild))
                                            {
                                                limit = DateTime.UtcNow.AddSeconds(10);
                                                var pid = pidChild;

                                                do
                                                {
                                                    if ((pidChild = GetChildProcess(pid)) > 0)
                                                    {
                                                        break;
                                                    }

                                                    this.process.Refresh();
                                                    if (_handle != this.process.MainWindowHandle)
                                                    {
                                                        break;
                                                    }
                                                }while (DateTime.UtcNow < limit && !child.WaitForExit(500));
                                            }

                                            if (pidChild > 0)
                                            {
                                                using (var child = Process.GetProcessById(pidChild))
                                                {
                                                    long mem     = 0;
                                                    byte counter = 0;
                                                    limit = DateTime.UtcNow.AddSeconds(60);

                                                    do
                                                    {
                                                        if (mem > 0)
                                                        {
                                                            child.Refresh();
                                                        }
                                                        var _mem = child.PeakWorkingSet64;
                                                        if (_mem > mem)
                                                        {
                                                            mem     = _mem;
                                                            counter = 0;
                                                        }
                                                        else if (++counter > 2)
                                                        {
                                                            break;
                                                        }
                                                    }while (DateTime.UtcNow < limit && !child.WaitForExit(100));

                                                    if (WindowChanged != null)
                                                    {
                                                        wce.Type = WindowChangedEventArgs.EventType.LauncherCoherentUIReady;
                                                        WindowChanged(this, wce);
                                                    }
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            Util.Logging.Log(ex);
                                        }
                                    }

                                    #endregion
                                }
                            }
                        }
                    }
                }while (!process.WaitForExit(500) && this.watcher != null);
            }
 protected void OnFocusChange(WindowChangedEventArgs eventArgs)
 {
     FocusChange?.Invoke(this, eventArgs);
 }