In Windows environment, adding an accessibility support to a program means you’ll have to do a lot of COM coding. For example, IRawElementProviderSimple is the most fundamental interface you should implement for every provider. So at first I started developing providers with ATL and throughout the process I learned few tips I’d like to share here:
1. Add the ‘_ATL_DEBUG_INTERFACES’ macro
_ATL_DEBUG_INTERFACES
MSDN link: http://msdn.microsoft.com/en-us/library/vstudio/sycfy8ec(v=vs.110).aspx
One thing should remember. If you add the _ATL_DEBUG_INTERFACES to your project, then you cannot use ‘static_cast’ to get an interface pointer between interfaces you inherited and always should get it via QueryInterface. If not, the code will crash instantly. Please refer to following forum quote more details:
Before using _ATL_DEBUG_INTERFACES, the code did a risky "static_cast" (which itself should be a crime!) to convert a interface pointer to the coclass object pointer. It apparently worked fine with AddRef/Release and so one. However, as soon as _ATL_DEBUG_INTERFACES is defined, the _QI_Thunk interface goes in between and the simple single inheritance didn't work out any more. Thus the attempt to AddRef caused first-chance access violations because the address of the function call was invalid and the reference count were less than expected since. After you released and released it again, you got the crash. The fix for this is never do such cast. If you definitely need to get the pointer to the class object, use a hidden method or get property to return the this pointer.
Link: http://marc.info/?l=ms-dcom&m=103440653613791&w=2
2. Use CAdapt to contain CComPtr in std::vector
Consider wrapping CComPtr instances with CAdapt in order to maintain CComPtr instances within std::vector to avoid & operator problem.
CAdapt MSDN Link: http://msdn.microsoft.com/en-us/library/bs6acf5x.aspx
Typically, you will use CAdapt when you want to store CComBSTR, CComPtr, CComQIPtr, or _com_ptr_t objects in a container-style class. This was most commonly necessary for C++ Standard Library containers prior to support for the C++11 Standard, but C++11 Standard Library containers automatically work with types that have overloaded operator&(). The Standard Library achieves this by internally usingstd::addressof() to get the true addresses of objects