Пример #1
0
        // Switches to our Automation thread, updates current state and raises StateChanged event
        void UpdateEditState(bool moveOnly = false)
        {
            Logger.WindowWatcher.Verbose("> FormulaEdit UpdateEditState - Posted");
            _syncContextAuto.Post(moveOnlyObj =>
            {
                Logger.WindowWatcher.Verbose($"FormulaEdit UpdateEditState - Focus: {_formulaEditFocus}");
                //// TODO: This is not right yet - the list box might have the focus... ?
                //AutomationElement focused;
                //try
                //{
                //    focused = AutomationElement.FocusedElement;
                //}
                //catch (ArgumentException aex)
                //{
                //    Debug.Print($"!!! ERROR: Failed to get Focused Element: {aex}");
                //    // Not sure why I get this - sometimes with startup screen
                //    return;
                //}
                AutomationElement focusedEdit = null;
                bool prefixChanged            = false;
                if (_formulaEditFocus == FormulaEditFocus.FormulaBar)
                {
                    focusedEdit = _formulaBar;
                }
                else if (_formulaEditFocus == FormulaEditFocus.InCellEdit)
                {
                    focusedEdit = _inCellEdit;
                }
                else
                {
                    // Neither have the focus, so we don't update anything
                    Logger.WindowWatcher.Verbose("FormulaEdit UpdateEditState End formula editing");
                    CurrentPrefix = null;
                    if (IsEditingFormula)
                    {
                        UninstallLocationMonitor();
                    }
                    IsEditingFormula = false;
                    prefixChanged    = true;
                    // Debug.Print("Don't have a focused text box to update.");
                }

                if (focusedEdit != null)
                {
                    EditWindowBounds = (Rect)focusedEdit.GetCurrentPropertyValue(AutomationElement.BoundingRectangleProperty);
                    IntPtr hwnd      = (IntPtr)(int)focusedEdit.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty);

                    var pt = Win32Helper.GetClientCursorPos(hwnd);

                    if (!IsEditingFormula)
                    {
                        InstallLocationMonitor(GetTopLevelWindow(focusedEdit));
                    }
                    IsEditingFormula = true;

                    var newPrefix = XlCall.GetFormulaEditPrefix();      // What thread do we have to use here ...?
                    if (CurrentPrefix != newPrefix)
                    {
                        CurrentPrefix = newPrefix;
                        prefixChanged = true;
                    }
                    Logger.WindowWatcher.Verbose($"FormulaEdit UpdateEditState Formula editing: CurrentPrefix {CurrentPrefix}, EditWindowBounds: {EditWindowBounds}");
                }

                // TODO: Smarter notification...?
                if ((bool)moveOnlyObj && !prefixChanged)
                {
                    StateChanged?.Invoke(this, new StateChangeEventArgs(StateChangeType.Move));
                }
                else
                {
                    OnStateChanged(new StateChangeEventArgs(StateChangeType.Multiple));
                }
            }, moveOnly);
        }
Пример #2
0
        void UpdateEditStateImpl(bool moveOnly = false)
        {
            Logger.WindowWatcher.Verbose($"> FormulaEdit UpdateEditState - Thread {Thread.CurrentThread.ManagedThreadId}");
            Logger.WindowWatcher.Verbose($"FormulaEdit UpdateEditState - Focus: {_formulaEditFocus} Window: {(_formulaEditFocus == FormulaEditFocus.FormulaBar ? _hwndFormulaBar : _hwndInCellEdit)}");

            IntPtr hwnd = IntPtr.Zero;

            bool prefixChanged = false;

            if (_formulaEditFocus == FormulaEditFocus.FormulaBar)
            {
                hwnd = _hwndFormulaBar;
            }
            else if (_formulaEditFocus == FormulaEditFocus.InCellEdit)
            {
                hwnd = _hwndInCellEdit;
            }
            else
            {
                // Neither have the focus, so we don't update anything
                Logger.WindowWatcher.Verbose("FormulaEdit UpdateEditState End formula editing");

                CurrentPrefix = null;

                if (IsEditingFormula)
                {
                    UninstallLocationMonitor();
                }

                IsEditingFormula = false;
                prefixChanged    = true;

                // Debug.Print("#### FormulaEditWatcher - No Window " + Environment.StackTrace);
            }

            if (hwnd != IntPtr.Zero)
            {
                EditWindowBounds = Win32Helper.GetWindowBounds(hwnd);

                if (!IsEditingFormula)
                {
                    IntPtr hwndTopLevel = Win32Helper.GetRootAncestor(hwnd);
                    InstallLocationMonitor(hwndTopLevel);
                    IsEditingFormula = true;
                }

                var newPrefix = XlCall.GetFormulaEditPrefix();  // What thread do we have to use here ...?

                if (CurrentPrefix != newPrefix)
                {
                    CurrentPrefix = newPrefix;
                    prefixChanged = true;
                }

                Logger.WindowWatcher.Verbose($"FormulaEdit UpdateEditState Formula editing: CurrentPrefix {CurrentPrefix}, EditWindowBounds: {EditWindowBounds}");
            }

            // TODO: Smarter (or more direct) notification...?
            if (moveOnly && !prefixChanged)
            {
                StateChanged?.Invoke(this, new StateChangeEventArgs(StateChangeType.Move));
            }
            else
            {
                OnStateChanged(StateChangeType.Multiple);
            }
        }