diff --git a/change/react-native-windows-38181227-9db6-47e6-bd4b-9dcf4721c299.json b/change/react-native-windows-38181227-9db6-47e6-bd4b-9dcf4721c299.json new file mode 100644 index 00000000000..ff5913ed35d --- /dev/null +++ b/change/react-native-windows-38181227-9db6-47e6-bd4b-9dcf4721c299.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Implement announceForAccessibility for Fabric using Win32 UIA", + "packageName": "react-native-windows", + "email": "198982749+Copilot@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp index 9e287550eee..f3f24c265ec 100644 --- a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp @@ -79,6 +79,54 @@ void AccessibilityInfo::announceForAccessibility(std::wstring announcement) noex xaml::Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, hstr, hstr); +#else + // Fabric implementation using Win32 UIA + if (!UiaClientsAreListening()) { + return; + } + + HWND hwnd = ::GetActiveWindow(); + if (!hwnd) { + return; + } + + IRawElementProviderSimple *provider = nullptr; + HRESULT hrProvider = UiaHostProviderFromHwnd(hwnd, &provider); + if (FAILED(hrProvider) || !provider) { + return; + } + + // Convert announcement string to BSTR + BSTR bstrAnnouncement = SysAllocString(announcement.c_str()); + if (!bstrAnnouncement) { + provider->Release(); + return; + } + + // Create a GUID and get string form for activityId + GUID guid; + wchar_t guidString[40] = {}; + BSTR bstrActivityId = nullptr; + + if (SUCCEEDED(CoCreateGuid(&guid))) { + int len = StringFromGUID2(guid, guidString, ARRAYSIZE(guidString)); + if (len > 1) { + bstrActivityId = SysAllocString(guidString); + } + } + + if (!bstrActivityId) { + SysFreeString(bstrAnnouncement); + provider->Release(); + return; + } + + HRESULT hr = UiaRaiseNotificationEvent( + provider, NotificationKind_Other, NotificationProcessing_ImportantMostRecent, bstrAnnouncement, bstrActivityId); + + SysFreeString(bstrAnnouncement); + SysFreeString(bstrActivityId); + provider->Release(); #endif }); }