// Runs on our automation thread void _windowWatcher_ExcelToolTipWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: if (!_toolTips.Contains(e.WindowHandle)) { _toolTips.Add(e.WindowHandle); ToolTipChanged?.Invoke(this, new ToolTipChangeEventArgs(ToolTipChangeType.Show, e.WindowHandle)); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: if (_toolTips.Remove(e.WindowHandle)) { ToolTipChanged?.Invoke(this, new ToolTipChangeEventArgs(ToolTipChangeType.Hide, e.WindowHandle)); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: default: // Ignoring these.... break; } }
// Runs on our automation thread void _windowWatcher_ExcelToolTipWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: if (!_toolTips.Contains(e.WindowHandle)) { _toolTips.Add(e.WindowHandle); ToolTipChanged?.Invoke(this, new ToolTipChangeEventArgs(ToolTipChangeType.Show, e.WindowHandle)); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: if (_toolTips.Remove(e.WindowHandle)) { ToolTipChanged?.Invoke(this, new ToolTipChangeEventArgs(ToolTipChangeType.Hide, e.WindowHandle)); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: // Not expecting this anymore - Destroy is no longer routed from the WinEvents. Debug.Fail("Unexpected ChangeType"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: default: // Ignoring these.... break; } }
// Runs on the Automation thread void _windowWatcher_InCellEditWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: // CONSIDER: Is this too soon to set up the AutomationElement ?? // TODO: Yes - need to do AutomationElement later (new Window does not have TextPattern ready) SetEditWindow(e.WindowHandle, ref _hwndInCellEdit, ref _inCellEdit); UpdateEditState(); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: //if (_formulaEditFocus == FormulaEditFocus.InCellEdit) //{ // _formulaEditFocus = FormulaEditFocus.None; // UpdateEditState(); //} break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: if (_formulaEditFocus != FormulaEditFocus.InCellEdit) { Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Focus"); _formulaEditFocus = FormulaEditFocus.InCellEdit; UpdateFormulaPolling(); UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: if (_formulaEditFocus == FormulaEditFocus.InCellEdit) { Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Unfocus"); _formulaEditFocus = FormulaEditFocus.None; UpdateFormulaPolling(); UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Show"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Hide"); break; default: throw new ArgumentOutOfRangeException("Unexpected Window Change Type", "e.Type"); } }
// Runs on our automation thread void _windowWatcher_PopupListWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: if (_hwndPopupList == IntPtr.Zero) { Logger.WindowWatcher.Info(string.Format("PopupList window created: {0}", e.WindowHandle)); } else { Logger.WindowWatcher.Warn(string.Format("PopupList window created more than once!? Old: {0}, New: {1}", _hwndPopupList, e.WindowHandle)); } _hwndPopupList = e.WindowHandle; break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: // We expect this only when shutting down Logger.WindowWatcher.Info(string.Format("PopupList window destroyed: {0}", e.WindowHandle)); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose("PopupList window show"); _hwndPopupList = e.WindowHandle; // We might have missed the Create IsVisible = true; if (_selectionChangeHook == null) { Logger.WindowWatcher.Verbose("PopupList WinEvent hook initialize"); // We set up the structure changed handler so that we can catch the sub-list creation InstallEventHandlers(); } UpdateSelectedItem(); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose("PopupList window hide"); IsVisible = false; UpdateSelectedItem(); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: Logger.WindowWatcher.Verbose("PopupList unexpected focus event!?"); break; default: break; } }
// Runs on the Automation thread void _windowWatcher_FormulaBarWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: // CONSIDER: Is this too soon to set up the AutomationElement ?? SetEditWindow(e.WindowHandle, ref _hwndFormulaBar, ref _formulaBar); UpdateEditState(); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: //if (_formulaEditFocus == FormulaEditFocus.FormulaBar) //{ // _formulaEditFocus = FormulaEditFocus.None; // UpdateEditState(); //} break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: if (_formulaEditFocus != FormulaEditFocus.FormulaBar) { Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Focus"); _formulaEditFocus = FormulaEditFocus.FormulaBar; UpdateFormulaPolling(); UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: if (_formulaEditFocus == FormulaEditFocus.FormulaBar) { Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Unfocus"); _formulaEditFocus = FormulaEditFocus.None; UpdateFormulaPolling(); UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Show"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Hide"); break; default: throw new ArgumentOutOfRangeException("Unexpected Window Change Type", "e.Type"); } }
// Runs on our automation thread void _windowWatcher_PopupListWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: if (_hwndPopupList == IntPtr.Zero) { Logger.WindowWatcher.Info($"PopupList window created: {e.WindowHandle}"); } else { Logger.WindowWatcher.Warn($"PopupList window created more than once!? Old: {_hwndPopupList}, New: {e.WindowHandle}"); } _hwndPopupList = e.WindowHandle; break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: // Not expecting this anymore - Destroy is no longer routed from the WinEvents. Debug.Fail("Unexpected ChangeType"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose($"PopupList window show"); _hwndPopupList = e.WindowHandle; // We might have missed the Create IsVisible = true; if (_selectionChangeHook == null) { Logger.WindowWatcher.Verbose($"PopupList WinEvent hook initialize"); // We set up the structure changed handler so that we can catch the sub-list creation InstallEventHandlers(); } UpdateSelectedItem(); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose($"PopupList window hide"); IsVisible = false; UpdateSelectedItem(); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: Logger.WindowWatcher.Verbose($"PopupList unexpected focus event!?"); break; default: break; } }
// Runs on our automation thread void _windowWatcher_PopupListWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: if (_hwndPopupList == IntPtr.Zero) { Logger.WindowWatcher.Info($"PopupList window created: {e.WindowHandle}"); } else { Logger.WindowWatcher.Warn($"PopupList window created more than once!? Old: {_hwndPopupList}, New: {e.WindowHandle}"); } _hwndPopupList = e.WindowHandle; // Automation.AddStructureChangedEventHandler(_popupList, TreeScope.Element, PopupListStructureChangedHandler); // Automation.AddAutomationPropertyChangedEventHandler(_popupList, TreeScope.Element, PopupListVisibleChangedHandler, AutomationElement.???Visible); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: // We expect this only when shutting down Logger.WindowWatcher.Info($"PopupList window destroyed: {e.WindowHandle}"); try { // DO we need to remove...? //if (_popupList != null) //Automation.RemoveAutomationPropertyChangedEventHandler(_popupList, PopupListBoundsChanged); } catch (Exception ex) { /// Too Late???? Logger.WindowWatcher.Verbose($"PopupList Event Handler Remove Error: {ex.Message}"); } // Expected when closing // Debug.Assert(false, "PopupList window destroyed...???"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose($"PopupList window show"); IsVisible = true; // We lazy-create the AutomationElement (expecting to make it only once) if (_popupList == null) { Logger.WindowWatcher.Verbose($"PopupList automation initialize"); _hwndPopupList = e.WindowHandle; _popupList = AutomationElement.FromHandle(_hwndPopupList); // We set up the structure changed handler so that we can catch the sub-list creation InstallEventHandlers(); } UpdateSelectedItem(); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose($"PopupList window hide"); IsVisible = false; UpdateSelectedItem(_selectedItem); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: Logger.WindowWatcher.Verbose($"PopupList unexpected focus event!?"); break; default: break; } }
// Runs on our automation thread void _windowWatcher_SelectDataSourceWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs args) { Logger.Monitor.Verbose($"!> SelectDataSourceWindowChanged ({args.Type})"); OnStateChanged(); }
// Runs on the Automation thread void _windowWatcher_InCellEditWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { // Debug.Print($"\r\n%%% InCellEditWindowChanged: {e.ObjectId} - {e.Type}\r\n"); switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Self) { SetEditWindow(e.WindowHandle, ref _hwndInCellEdit); _updateEditStateAfterTimeout.Signal(); } else if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Caret) { // We expect this on every text change // NOTE: Not anymore after some Excel / Windows update Debug.Print($"-#-#-#- Text Changed ... "); _updateEditStateAfterTimeout.Signal(); } else { Debug.Print($"### Unexpected WindowsChanged object id: {e.ObjectId}"); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: // Not expecting this anymore - Destroy is no longer routed from the WinEvents. Debug.Fail("Unexpected ChangeType"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: if (_formulaEditFocus != FormulaEditFocus.InCellEdit) { if (e.WindowHandle != _hwndInCellEdit) { // We never saw the Create... SetEditWindow(e.WindowHandle, ref _hwndInCellEdit); } Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Focus"); _formulaEditFocus = FormulaEditFocus.InCellEdit; _updateEditStateAfterTimeout.Signal(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: if (_formulaEditFocus == FormulaEditFocus.InCellEdit) { Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Unfocus"); _formulaEditFocus = FormulaEditFocus.None; _updateEditStateAfterTimeout.Signal(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Show"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose($"FormulaEdit - InCellEdit Hide"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.LocationChange: if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Caret) { // We expect this on every text change in newer Excel versions Debug.Print($"-#-#-#- Text Changed ... "); _updateEditStateAfterTimeout.Signal(); } else { Debug.Print($"-#-#-#- Unexpected WindowsChanged object id: {e.ObjectId}"); } break; default: //throw new ArgumentOutOfRangeException("Unexpected Window Change Type", "e.Type"); Logger.WindowWatcher.Verbose($"FormulaEdit - Unexpected Window Change Type: {e.Type}"); break; } }
// Runs on the Automation thread void _windowWatcher_InCellEditWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { // Debug.Print(string.Format("\r\n%%% InCellEditWindowChanged: {e.ObjectId} - {e.Type}\r\n"); switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Self) { SetEditWindow(e.WindowHandle, ref _hwndInCellEdit); UpdateEditState(); } else if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Caret) { // We expect this on every text change // NOTE: Not anymore after some Excel / Windows update Debug.Print("-#-#-#- Text Changed ... "); UpdateEditStateDelayed(); } else { Debug.Print(string.Format("### Unexpected WindowsChanged object id: {0}", e.ObjectId)); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: // We expect this for every text change, but ignore since we react to the Create event //if (_formulaEditFocus == FormulaEditFocus.FormulaBar) //{ // _formulaEditFocus = FormulaEditFocus.None; // UpdateEditState(); //} break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: if (_formulaEditFocus != FormulaEditFocus.InCellEdit) { if (e.WindowHandle != _hwndInCellEdit) { // We never saw the Create... SetEditWindow(e.WindowHandle, ref _hwndInCellEdit); } Logger.WindowWatcher.Verbose("FormulaEdit - InCellEdit Focus"); _formulaEditFocus = FormulaEditFocus.InCellEdit; UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: if (_formulaEditFocus == FormulaEditFocus.InCellEdit) { Logger.WindowWatcher.Verbose("FormulaEdit - InCellEdit Unfocus"); _formulaEditFocus = FormulaEditFocus.None; UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose("FormulaEdit - InCellEdit Show"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose("FormulaEdit - InCellEdit Hide"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.LocationChange: if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Caret) { // We expect this on every text change in newer Excel versions Debug.Print("-#-#-#- Text Changed ... "); UpdateEditStateDelayed(); } else { Debug.Print(string.Format("-#-#-#- Unexpected WindowsChanged object id: {0}", e.ObjectId)); } break; default: //throw new ArgumentOutOfRangeException("Unexpected Window Change Type", "e.Type"); Logger.WindowWatcher.Verbose(string.Format("FormulaEdit - Unexpected Window Change Type: {0}", e.Type)); break; } }
// Runs on our automation thread void _windowWatcher_SelectDataSourceWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs args) { Logger.Monitor.Verbose(string.Format("!> SelectDataSourceWindowChanged ({0})", args.Type)); OnStateChanged(); }
// Runs on the Automation thread void _windowWatcher_FormulaBarWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e) { switch (e.Type) { case WindowWatcher.WindowChangedEventArgs.ChangeType.Create: if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Self) { SetEditWindow(e.WindowHandle, ref _hwndFormulaBar); UpdateEditState(); } else if (e.ObjectId == WindowWatcher.WindowChangedEventArgs.ChangeObjectId.Caret) { // We expect this on every text change (and it is our only detection of text changes) UpdateEditStateDelayed(); } else { Debug.Print($"### Unexpected WindowsChanged object id: {e.ObjectId}"); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy: // We expect this for every text change, but ignore since we react to the Create event //if (_formulaEditFocus == FormulaEditFocus.FormulaBar) //{ // _formulaEditFocus = FormulaEditFocus.None; // UpdateEditState(); //} break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus: if (_formulaEditFocus != FormulaEditFocus.FormulaBar) { Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Focus"); if (e.WindowHandle != _hwndFormulaBar) { // We never saw the Create... SetEditWindow(e.WindowHandle, ref _hwndFormulaBar); } _formulaEditFocus = FormulaEditFocus.FormulaBar; UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus: if (_formulaEditFocus == FormulaEditFocus.FormulaBar) { Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Unfocus"); _formulaEditFocus = FormulaEditFocus.None; UpdateEditState(); } break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Show: Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Show"); break; case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide: Logger.WindowWatcher.Verbose($"FormulaEdit - FormulaBar Hide"); break; default: throw new ArgumentOutOfRangeException("Unexpected Window Change Type", "e.Type"); } }