1

I'm trying to add accessibility support to the WC_LISTVIEW control in my Win32/MFC application. I'm using Windows Narrator tool in Windows 10 to test the results. And by default it only reads the main item name of a selected row. For instance, in this case:

enter image description here

it will read only the country, when I need it to read the whole line.

So I found that I can set up a Server annotation for the list-view control using this example.

I would first set it up as such:

CAccPropServer_ListView* pMyPropSrv = NULL;
HRESULT hr;

CComPtr<IAccPropServices> pAccPropSvc = NULL;
hr = ::CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, IID_IAccPropServices, (void **)&pAccPropSvc);
if(SUCCEEDED(hr) &&
    pAccPropSvc )
{
    pMyPropSrv = new (std::nothrow) CAccPropServer_ListView( pAccPropSvc );
    if( pMyPropSrv )
    {

        MSAAPROPID propids[] = {
            PROPID_ACC_NAME,
        };

        hr = pAccPropSvc->SetHwndPropServer( hWndListCtrl, OBJID_CLIENT,
            CHILDID_SELF, propids, 1, pMyPropSrv, ANNO_CONTAINER);

        pMyPropSrv->Release();
    }
}

where the CAccPropServer_ListView class does all the work:

class CAccPropServer_ListView: public IAccPropServer
{
    ULONG               m_Ref;
    IAccPropServices *  m_pAccPropSvc;

public:

    CAccPropServer_ListView( IAccPropServices * pAccPropSvc )
        : m_Ref( 1 ),
          m_pAccPropSvc( pAccPropSvc )
    {
        m_pAccPropSvc->AddRef();
    }

    ~CAccPropServer_ListView()
    {
        m_pAccPropSvc->Release();
    }


    /* TODO: Addref/Release/QI go here...
           Skipped them for brevity...
     */


    HRESULT STDMETHODCALLTYPE GetPropValue (const BYTE * pIDString,
        DWORD dwIDStringLen, MSAAPROPID idProp, VARIANT * pvarValue,
        BOOL * pfGotProp )
    {
        if(!pfGotProp)
            return E_POINTER;

        pvarValue->vt = VT_EMPTY;
        *pfGotProp = FALSE;

        HWND  hwnd;
        DWORD idObject;
        DWORD idChild;

        if( S_OK != m_pAccPropSvc->DecomposeHwndIdentityString( pIDString, 
                  dwIDStringLen, &hwnd, &idObject, &idChild ) )
        {
            return S_OK;
        }

        if( idChild != CHILDID_SELF )
        {
            if( idProp == PROPID_ACC_NAME )
            {
                CString str;
                str.Format(L"Line index %d", idChild);

                BSTR bstr = ::SysAllocString((LPCTSTR)str.GetString());
                pvarValue->vt = VT_BSTR;
                pvarValue->bstrVal = bstr;

                *pfGotProp = TRUE;
            }
        }

        return S_OK;
    }



};

So my question is concerning GetPropValue method above that actually generates the text prompt for Narrator to read out loud.

How do I get an index of a row read by the Narrator from the idChild that is returned by DecomposeHwndIdentityString?

In my example above, purely experimentally, I was getting the following values:

"Line index 17"
"Line index 33"
"Line index 49"
"Line index 65"
and so on

which would translate to 0x11, 0x21, 0x31, 0x41 that are not row indexes. Are those IDs documented anywhere for a SysListView32?

c00000fd
  • 20,994
  • 29
  • 177
  • 400

0 Answers0