The C++ IAccessible interface offers a handful of methods that allow you to gather information or perform actions on an object. Each of these methods are well documented on MSDN, but it is up to the creator of an object to implement them correctly. In this article, I’ll be talking about a couple of the inconsistencies you may run into when using these methods due to improper implementations and a lack of restrictions on how they should be implemented.
IAccessible::get_accRole
In the documentation for this method, it is clearly stated that it accepts two parameters. The first is the accessible objects child id. This variant is either equal to CHILDID_SELF, which defines that you are seeking information about the current object, or the child ID, which will get the role of the defined child. This parameter should be of variant type VT_I4. The second parameter is a variant pointer that will return the accessibility role of the object. In the documentation this is stated as being an object role constant such as ROLE_SYSTEM_WINDOW or ROLE_SYSTEM_CLIENT. This parameter is where I have run into problems with how get_accRole has been implemented by the creator of the object.
In addition to stating the second parameter should return an object role constant, it also states that the variant type MUST be of type VT_I4. This does not seem to be enforced though. I have run into numerous situations (developing in Microsoft Office) where the variant type is VT_BSTR. A string is considered invalid for this variant and can cause quite a headache when unexpected. This occurs in a Microsoft product none the less, the creators of MSAA. This is just one case that I have run into where the value is invalid, and it begs the question, what other variant types might this return? That is totally up to the developer implemented get_accRole in his object. The simple solution to this problem is to always check the variant type that is returned before doing any operations on it to avoid errors.
IAccessible::get_accState
After research into the get_accRole method, it came as no surprise the get_accState suffers from the same issues. As with get_accRole, get_accState takes two parameters. The first is the child id, and the second is the out variable to hold the state constant. The documentation for get_accState states that the second argument will return a variant type of VT_I4 that corresponds to one of the object state constants. Though in using the accState with Microsoft Office and Lotus Notes I have run into times where the state is of variant type VT_BSTR (string). Again the solution is to always check the variant type that is returned before using it in any operations.
—–
As I continue to dive deeper into the world of MSAA, I’ll keep this blog up to date with the inconsistencies I find. If you have any that you have come across in working with MSAA tell me about them. I’ll be glad to look into them to see if there is a workaround or a clean way to handle them. I’ll leave with you with a code snippet that shows how to get the accRole and compare it with an object role constant.
Compare accessibility role:
//Code below assumes that IAccessible object and ChildID are both passed in parameters. bool CompareAccRole(IAccessible* pIAccessible, VARIANT childID, LONG objectRoleConstant) { VARIANT accObjectRole; HRESULT hr = pIAccessible->get_accRole(childID, &accObjectRole); if(hr == S_OK && accObjectRole.vt == VT_I4) { if(accObjectRole.lVal & objectRoleConstant) return true; } return false; }
Useful Links: