Background: I have a C# automation client (.NET Framework 4.8) using System.Windows.Automation to invoke a button in a Microsoft Access (VBA) application. The target control is non-standard / windowless (AutomationElement.Current.NativeWindowHandle == 0).
Problem: InvokePattern.Invoke() runs without exception and UIA diagnostics look identical when the target window is on the same monitor and when it is on a secondary monitor. However, when the Access window is on a secondary monitor, the button does not actually perform its action even though Invoke() returned normally. When the window is on the same monitor, the action runs as expected.
Environment
- .NET Framework 4.8
- References:
UIAutomationClient,UIAutomationTypes - Target app: Microsoft Access (VBA), windowless controls
- OS: Windows 10/11 (multi-monitor, possibly per-monitor DPI)
Minimal code used
public void ClickButton(AutomationElement button)
{
object patternObj;
if (button.TryGetCurrentPattern(InvokePattern.Pattern, out patternObj))
{
InvokePattern invokePattern = patternObj as InvokePattern;
if (invokePattern != null)
{
invokePattern.Invoke();
Application.DoEvents();
Thread.Sleep(200);
}
}
}
Diagnostics logs when it works (same monitor):
=== Diagnostics start ===
IsOffscreen: False
IsEnabled: True
HasKeyboardFocus: False
BoundingRectangle: 0;23;109;24
NativeWindowHandle: 0x0
Supported patterns: InvokePatternIdentifiers.Pattern
TryGetClickablePoint: True -> 54,5;35
Top-level window hwnd: 0x2046A
Foreground window hwnd: 0x2046A
InvokePattern invoked — check whether the button was activated.
=== Diagnostics end ===
When it does NOT work (secondary monitor):
=== Diagnostics start ===
IsOffscreen: False
IsEnabled: True
HasKeyboardFocus: False
BoundingRectangle: 0;23;109;24
NativeWindowHandle: 0x0
Supported patterns: InvokePatternIdentifiers.Pattern
TryGetClickablePoint: True -> 54,5;35
Top-level window hwnd: 0x2046A
Foreground window hwnd: 0x2046A
InvokePattern invoked — check whether the button was activated.
=== Diagnostics end ===
What I already tried
- Verified
IsOffscreen,BoundingRectangle,TryGetClickablePoint— they are all identical in both cases SetForegroundWindow(topHwnd)andbutton.SetFocus()AutomationElement.FromPoint(clickablePoint)andInvokeon that element.AttachThreadInput+SetForegroundWindowbeforeInvokeLegacyIAccessiblePattern.DoDefaultActionvia reflection (type not available in my runtime)- As a fallback I used
SendInputto simulate a real mouse click — that reliably triggers the button
Observations
InvokePattern.Invokeexecutes without throwing in both scenariosElement.Current.NativeWindowHandle == 0(windowless control) —SendMessage(BM_CLICK)to the control is not possible- The control is exposed to UIA but apparently the provider/target does not perform the action when the window is on the secondary monitor
Questions
Has anyone encountered
InvokePattern.Invokereturning normally but having no effect when the target is on a different monitor (multi-monitor) ?Are there known UIA / MS Access provider issues with windowless controls or multi-monitor setups?
What additional diagnostics would you recommend (ETW, UIA Verifier, MSAA checks, specific properties to compare)?
Are there any "clean" alternatives (without moving the mouse) to trigger Access/VBA windowless control actions reliably?