Repository: nvaccess/nvda

Issue:
Key echo while typing and speech while editing cells in Excel does not work at all without the experimental UIA setting enabled
### Steps to reproduce:

This happens with default settings (i.e, usage of UIA in Excel is not enabled). The problem goes away when turning the setting on, so this is probably a regression.

1. Open a new blank excel workbook. Type some text into cell A1, e.g "abc"
2. Press f2, and attempt to use the arrow keys to read the text

### Actual behavior:

Nothing is heard when typing into a cell. Pressing the arrow keys to review the text when using f2 to edit the cell contents does not work either.

This makes it virtually impossible to edit complex formulae without resorting to copying and pasting out into notepad, doing the edits there, then pasting it back.

### Expected behavior:

Typing into the cell echos the character that you typed (based on my key echo setting). Using the arrow keys to review text in a cell when pressing f2 works.

### System configuration
#### NVDA installed/portable/running from source:
Installed

#### NVDA version:
alpha-22295,49a85788

#### Windows version:
Windows 10 20h2

#### Name and version of other software in use when reproducing the issue:
Excel 16.0.13901.20366 64-bit 

#### Other information about your system:

### Other questions
#### Does the issue still occur after restarting your computer?
Yes

#### Have you tried any other versions of NVDA? If so, please report their behaviors.
No

#### If add-ons are disabled, is your problem still occurring?
Yes

#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?
N/A


Discussion:
Hello
Could you please try another version of NVDA (ideally 2020.4) before speaking of regression?
Also please try to run COM Registration Fixing Tool.

I do not succeed in reproducing this issue on my side with the following config:
* NVDA Version : last alpha source-master-516706d'] or installed 2020.4
* Excel 2016 (version '16.0.5134.1000')
* Windows 10 1809

@CyrilleB79 the reason why I mention this is a regression is because I don't see this issue in 2020.4.

I've also upgraded to the latest snapshot version and can still reproduce it. Note that after I enable the "Use UI Automation to access Microsoft Excel spreadsheet controls when available" option in advanced settings, the problem goes away.
OK. Still, can you clarify the following points:
* Could you please try to run COM Registration Fixing Tool? If already done, is there any change?
* Regarding 2020.4 did you test before upgrading to last alpha or did you test recently, e.g. with a portable version (since it seems you have alpha installed)?
Thanks.

@CyrilleB79 I've just ran the com registration fixing tool which doesn't change anything, I can still reproduce the problem. I downloaded V2020.4 off the installer as I didn't want to interfere with my already installed copy.

I have enabled debug logging. I pressed right arrow, entered the text "def" in an empty cell then pressed tab. From the output below, the error "_ctypes.COMError: (-2147418111, 'Call was rejected by callee.', (None, None, None, 0, None))" occurs every time a key is pressed.

```
IO - inputCore.InputManager.executeGesture (15:03:09.043) - winInputHook (12008):
Input: kb(laptop):rightArrow
DEBUG - IAccessibleHandler.internalWinEventHandler.winEventCallback (15:03:09.093) - MainThread (15720):
Dropping UIA proxied event for Excel7 window. WinEvent: EVENT_OBJECT_SELECTIONREMOVE, window 328180 (EXCEL7), objectID 20, childID 0, process 13020 (excel), thread 13384
DEBUG - IAccessibleHandler.internalWinEventHandler.winEventCallback (15:03:09.094) - MainThread (15720):
Dropping UIA proxied event for Excel7 window. WinEvent: EVENT_OBJECT_SELECTION, window 328180 (EXCEL7), objectID 21, childID 0, process 13020 (excel), thread 13384
DEBUG - IAccessibleHandler.internalWinEventHandler.winEventCallback (15:03:09.096) - MainThread (15720):
Dropping UIA proxied event for Excel7 window. WinEvent: EVENT_OBJECT_FOCUS, window 328180 (EXCEL7), objectID 22, childID 0, process 13020 (excel), thread 13384
IO - speech.speak (15:03:09.135) - MainThread (15720):
Speaking ['B1', CancellableSpeech (still valid)]
IO - inputCore.InputManager.executeGesture (15:03:10.196) - winInputHook (12008):
Input: kb(laptop):d
DEBUG - IAccessibleHandler.internalWinEventHandler.winEventCallback (15:03:10.222) - MainThread (15720):
Dropping UIA proxied event for Excel7 window. WinEvent: EVENT_OBJECT_FOCUS, window 328180 (EXCEL7), objectID 23, childID 0, process 13020 (excel), thread 13384
DEBUG - IAccessibleHandler.internalWinEventHandler.winEventCallback (15:03:10.223) - MainThread (15720):
Dropping UIA proxied event for Excel7 window. WinEvent: EVENT_OBJECT_FOCUS, window 328180 (EXCEL7), objectID 24, childID 0, process 13020 (excel), thread 13384
DEBUG - IAccessibleHandler.internalWinEventHandler.winEventCallback (15:03:10.228) - MainThread (15720):
Dropping UIA proxied event for Excel7 window. WinEvent: EVENT_OBJECT_FOCUS, window 328180 (EXCEL7), objectID 25, childID 0, process 13020 (excel), thread 13384
DEBUGWARNING - eventHandler.executeEvent (15:03:10.236) - MainThread (15720):
error executing event: typedCharacter on <NVDAObjects.window.excel.ExcelCell object at 0x0783A7F0> with extra args of {'ch': 'd'}
Traceback (most recent call last):
  File "eventHandler.pyc", line 246, in executeEvent
  File "eventHandler.pyc", line 96, in __init__
  File "eventHandler.pyc", line 105, in next
  File "NVDAObjects\window\excel.pyc", line 1382, in event_typedCharacter
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\window\excel.pyc", line 1369, in _get_states
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\window\excel.pyc", line 1176, in _get_excelCellInfo
  File "comtypes\client\lazybind.pyc", line 57, in __call__
  File "comtypes\automation.pyc", line 728, in _invoke
  File "comtypesMonkeyPatches.pyc", line 27, in __call__
_ctypes.COMError: (-2147418111, 'Call was rejected by callee.', (None, None, None, 0, None))
IO - inputCore.InputManager.executeGesture (15:03:10.652) - winInputHook (12008):
Input: kb(laptop):e
DEBUGWARNING - eventHandler.executeEvent (15:03:10.682) - MainThread (15720):
error executing event: typedCharacter on <NVDAObjects.window.excel.ExcelCell object at 0x0783A7F0> with extra args of {'ch': 'e'}
Traceback (most recent call last):
  File "eventHandler.pyc", line 246, in executeEvent
  File "eventHandler.pyc", line 96, in __init__
  File "eventHandler.pyc", line 105, in next
  File "NVDAObjects\window\excel.pyc", line 1382, in event_typedCharacter
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\window\excel.pyc", line 1369, in _get_states
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\window\excel.pyc", line 1176, in _get_excelCellInfo
  File "comtypes\client\lazybind.pyc", line 57, in __call__
  File "comtypes\automation.pyc", line 728, in _invoke
  File "comtypesMonkeyPatches.pyc", line 27, in __call__
_ctypes.COMError: (-2147418111, 'Call was rejected by callee.', (None, None, None, 0, None))
IO - inputCore.InputManager.executeGesture (15:03:10.870) - winInputHook (12008):
Input: kb(laptop):f
DEBUGWARNING - eventHandler.executeEvent (15:03:10.890) - MainThread (15720):
error executing event: typedCharacter on <NVDAObjects.window.excel.ExcelCell object at 0x0783A7F0> with extra args of {'ch': 'f'}
Traceback (most recent call last):
  File "eventHandler.pyc", line 246, in executeEvent
  File "eventHandler.pyc", line 96, in __init__
  File "eventHandler.pyc", line 105, in next
  File "NVDAObjects\window\excel.pyc", line 1382, in event_typedCharacter
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\window\excel.pyc", line 1369, in _get_states
  File "baseObject.pyc", line 42, in __get__
  File "baseObject.pyc", line 146, in _getPropertyViaCache
  File "NVDAObjects\window\excel.pyc", line 1176, in _get_excelCellInfo
  File "comtypes\client\lazybind.pyc", line 57, in __call__
  File "comtypes\automation.pyc", line 728, in _invoke
  File "comtypesMonkeyPatches.pyc", line 27, in __call__
_ctypes.COMError: (-2147418111, 'Call was rejected by callee.', (None, None, None, 0, None))
```
Thanks for the additional information and for the log.
No problem if you tested with the installer of 2020.4 running a temporary version, that remains a valid test.

One last question: did it use to work on this machine some time ago? If yes, any idea when this has changed?

Unfortunately, I have no idea regarding the cause of this error. The forums seem to indicate various causes such as presence of Excel add-ons, incomplete Excel installation or activation, etc.

If someone more experienced than I can investigate, he/she is welcome!

> One last question: did it use to work on this machine some time ago? If yes, any idea when this has changed?

I'm not sure, this is a fresh reinstall of Windows and I don't use excel that often. It so happened that it was the first time I used excel after the reinstall of Windows, so I'm doubting any software issues.

Also doesn't explain why it works in NVDA 2020.4 and not the latest snapshot version.
cc @michaelDCurran 

Resolving patch:
diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py
--- a/source/_UIAHandler.py
+++ b/source/_UIAHandler.py
@@ -58,7 +58,6 @@
 goodUIAWindowClassNames=[
 	# A WDAG (Windows Defender Application Guard) Window is always native UIA, even if it doesn't report as such.
 	'RAIL_WINDOW',
-	"EXCEL6",
 ]
 
 badUIAWindowClassNames=[
diff --git a/source/appModules/excel.py b/source/appModules/excel.py
--- a/source/appModules/excel.py
+++ b/source/appModules/excel.py
@@ -5,6 +5,7 @@
 # For more details see: https://www.gnu.org/licenses/gpl-2.0.html
 
 import time
+import config
 import eventHandler
 import api
 import UIAHandler
@@ -15,6 +16,8 @@
 from NVDAObjects.window.edit import UnidentifiedEdit
 from NVDAObjects.window import Window
 from NVDAObjects.window.excel import ExcelCell
+from NVDAObjects.IAccessible import IAccessible
+
 
 class Excel6(Window):
 	"""
@@ -43,6 +46,17 @@ def _get_focusRedirect(self):
 					self.focusRedirect=obj
 					return obj
 
+
+class Excel6_WhenUIAEnabled(IAccessible):
+	"""
+	#12303: When accessing Microsoft Excel via UI Automation
+	MSAA focus events on the old formula edit window should be completely ignored.
+	UI Automation will fire its own ones.
+	"""
+
+	shouldAllowIAccessibleFocusEvent = False
+
+
 class AppModule(appModuleHandler.AppModule):
 
 	def chooseNVDAObjectOverlayClasses(self, obj, clsList):
@@ -55,4 +69,14 @@ def chooseNVDAObjectOverlayClasses(self, obj, clsList):
 				pass
 			clsList.insert(0, DisplayModelEditableText)
 		if windowClass=="EXCEL6":
-			clsList.insert(0,Excel6)
+			if config.conf["UIA"]["useInMSExcelWhenAvailable"]:
+				# #12303: When accessing Microsoft Excel via UI Automation
+				# MSAA focus events on the old formula edit window should be completely ignored.
+				# UI Automation will fire its own ones.
+				clsList.insert(0, Excel6_WhenUIAEnabled)
+			else:
+				# #12303: The old Formula Edit window in recent versions of Excel
+				# may not be accessible with display models as GDI is no longer used.
+				# However, UI Automation does expose an accessible edit control within the active cell,
+				# So use a class that will redirect focus to that.
+				clsList.insert(0, Excel6)


Test patch: