예제 #1
0
        bool UpdateFocus(IntPtr windowHandle, string windowClassName)
        {
            if (windowHandle == _focusedWindowHandle && _focusedWindowClassName == windowClassName)
            {
                return(false);
            }

            // We see a change in the WindowClassName often - handle that as a focus change too

            Debug.Assert(_focusedWindowClassName != _excelToolTipClass); // We don't expect the ToolTip to ever get the focus
            Logger.WindowWatcher.Verbose($"Focus lost by {_focusedWindowHandle} ({_focusedWindowClassName})");
            // It has changed - raise an event for the old window
            switch (_focusedWindowClassName)
            {
            case _popupListClass:
                PopupListWindowChanged?.Invoke(this, new WindowChangedEventArgs(_focusedWindowHandle, WindowChangedEventArgs.ChangeType.Unfocus, WindowChangedEventArgs.ChangeObjectId.Self));
                break;

            case _inCellEditClass:
                InCellEditWindowChanged?.Invoke(this, new WindowChangedEventArgs(_focusedWindowHandle, WindowChangedEventArgs.ChangeType.Unfocus, WindowChangedEventArgs.ChangeObjectId.Self));
                break;

            case _formulaBarClass:
                FormulaBarWindowChanged?.Invoke(this, new WindowChangedEventArgs(_focusedWindowHandle, WindowChangedEventArgs.ChangeType.Unfocus, WindowChangedEventArgs.ChangeObjectId.Self));
                break;

            //case _nuiDialogClass:
            default:
                // Not one of our watched window, so we don't care
                break;
            }

            // Set the new focus info
            // Event will be raised by WinEventReceived handler itself
            _focusedWindowHandle    = windowHandle;
            _focusedWindowClassName = windowClassName;
            Logger.WindowWatcher.Verbose($"Focus changed to {windowHandle} ({windowClassName})");
            return(true);
        }
예제 #2
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)
        {
            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, e.ObjectId));
                break;

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

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

            case _excelToolTipClass:
                ExcelToolTipWindowChanged?.Invoke(this, new WindowChangedEventArgs(e.WindowHandle, e.EventType, e.ObjectId));
                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;
            }
        }