Hi @Molchanov, Pavel ,
Thanks for sharing the configuration. I understand that the overlay's empty areas need to remain click-through while its rendered controls stay interactive. I have not found a documented public UIA API that exempts that HWND from GetClickablePoint hit-testing while preserving this selective interaction.
Mouse hit-testing and UIA clickable-point detection are not interchangeable. HTTRANSPARENT is a WM_NCHITTEST response, not a documented UIA exclusion flag. Separately, the layered-window documentation explains that hit testing of a layered window is based on its shape and transparency, so areas whose alpha value is zero let mouse messages through. Since AllowsTransparency=true produces a layered window, a click passing through does not, by itself, establish how UIA will resolve that point.
I tested a standalone WPF reproduction, but did not reproduce Access is denied. With the overlay hidden, and with it transparent while the HTTRANSPARENT hook was enabled, GetClickablePoint returned a point. With the hook disabled, and with an opaque overlay, it threw NoClickablePointException. InvokePattern.Invoke() activated the target button in every configuration tested.
The screenshots below show the complete comparison and the transparent-overlay case with the hook enabled:
One observation may be relevant: the runner (PID 8632) and the overlay (PID 10808) ran in separate processes, yet the runner's native WindowFromPoint returned the target HWND rather than the overlay. The harness records the native HWND lookup and the UIA point lookup separately, so this does not establish the execution path GetClickablePoint takes internally.
The test ran on Windows build 26200 and .NET 10.0.12, with an MTA UIA runner. All three processes were elevated at the same high integrity level, with uiAccess=false. It therefore did not test a lower-integrity runner accessing a higher-integrity target or overlay. Not reproducing access denied under matched privileges does not rule out a security-boundary issue in your environment; the UI Automation Security Overview provides the relevant background. The harness also uses ShowActivated=false, covers only the primary screen, and does not verify physical mouse click-through.
The GetClickablePoint documentation lists NoClickablePointException when no clickable point is available. Its transparent-window example concerns controls inside that window, not controls underneath a separate overlay. It does not establish that your access-denied failure is by design.
To distinguish these errors, add this diagnostic method to your test class and call it from your existing UIA worker thread:
using System;
using System.ComponentModel;
using System.Windows.Automation;
static void CheckClickablePoint(AutomationElement target)
{
try
{
var point = target.GetClickablePoint();
Console.WriteLine($"Clickable point: {point.X}, {point.Y}");
}
catch (NoClickablePointException exception)
{
Console.WriteLine("No clickable point was found.");
Console.WriteLine(exception);
}
catch (Win32Exception exception)
{
Console.WriteLine($"NativeErrorCode: {exception.NativeErrorCode}");
Console.WriteLine($"HRESULT: 0x{exception.HResult:X8}");
Console.WriteLine(exception);
}
}
This is a diagnostic, not a fix. Compare the same target with the overlay visible and actually hidden, keeping privileges unchanged. If hiding it removes the error, that helps isolate the overlay's involvement; if the error remains, the investigation should extend beyond overlay hit-testing.
If your test only needs to activate a control, its supported InvokePattern.Invoke() may avoid the clickable-point lookup. It does not replace a physical-click test or bypass access restrictions.
Could you share:
- The diagnostic output, including the stack trace and any inner exception.
- Your Windows/.NET versions, target UI framework, and
WM_NCHITTESThook implementation. - Each process's elevation/UIAccess settings, especially whether the runner has a lower integrity level than the target or overlay.
Remove private paths or application data from the output. These details will help locate the failing call and determine whether the local test missed a relevant configuration or security boundary; they are not a recommendation to change your privilege settings.
If you found my explanation above was truly helpful or informative to you, I would greatly appreciate it if you could follow this guidance so others with the same issue could benefit as well.
Thank you.