Share via


Win32: Setting supplemental information on an control

This article is referenced directly by Microsoft Accessibility Insights for Windows. Microsoft Accessibility Insights for Windows can help spotlight many accessibility issues in UI, and guide you to the relevant UI framework-specific code sample to help you resolve the issue. Learn more about Microsoft Accessibility Insights for Windows.

Problem

When a screen reader moves to the control, its announcement does not include some helpful information that's associated visually with the control. For example, the error status text associated with an edit field. If my customer is not made aware of that information when the screen reader encounters the control, their task is disrupted.

Suggested Fix

Consider using IAccPropServices::SetHwndPropStr() to set specific string properties on the hwnd associated with the edit field, such that the string will get exposed through the UI Automation (UIA) API.

The code sample below shows the UIA FullDescription property being set on the edit field, based on the text label shown visually near the edit field. This is only possible on versions of Windows where support the FullDescription property exists. For earlier version of Windows where that property is not available, the HelpText or ItemStatus property could be set instead. That would be done by supplying HelpText_Property_GUID or ItemStatus_Property_GUID instead of FullDescription_Property_GUID.

Code Sample: Setting the control's FullDescription from a nearby visual label.

Note that this approach can also be taken to set the UIA HelpText and ItemStatus properties for the control.

// At the top of the C++ file.
#include <initguid.h> 
#include "objbase.h"
#include "uiautomation.h" 
IAccPropServices* _pAccPropServices = NULL;


// Run when the UI is created.
void SetFullDescriptionProperty(HWND hDlg)
{
    HRESULT hr = S_OK;

    hr = CoCreateInstance(
        CLSID_AccPropServices,
        nullptr,
        CLSCTX_INPROC,
        IID_PPV_ARGS(&_pAccPropServices));

    if (SUCCEEDED(hr))
    {
	    // Get the text from the label shown visually near the control.
        WCHAR szControlDescription[MAX_LOADSTRING];
        GetDlgItemText(
            hDlg, 
            IDC_LABEL_CONTROLDESCRIPTION, 
            szControlDescription, 
            ARRAYSIZE(szControlDescription));

		// Set the UIA FullDescription property on the control, from the visual label text.
		// (Note that other UIA properties such as HelpText or ItemStatus could be set in 
		// a similar way.)
        hr = _pAccPropServices->SetHwndPropStr(
            GetDlgItem(hDlg, IDC_CONTROL),
            OBJID_CLIENT,
            CHILDID_SELF,
            FullDescription_Property_GUID,
            szControlDescription);
    }
}

// Run when the UI is destroyed.
void ClearFullDescriptionProperty(HWND hDlg)
{
    if (_pAccPropServices != nullptr)
    {
        // We only added the one property to the hwnd. 
        MSAAPROPID props[] = { FullDescription_Property_GUID };
        _pAccPropServices->ClearHwndProps(
            GetDlgItem(hDlg, IDC_CONTROL),
            OBJID_CLIENT,
            CHILDID_SELF,
            props,
            ARRAYSIZE(props));

        _pAccPropServices->Release();
        _pAccPropServices = NULL;
    }
}