If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

How to Marshal AccessibleObjectFromWindow

Hi all,

I've been trying to marshal AccessibileObjectFromWindow without luck. The code compiles but I get an exception at the line Marshal.Queryinterface which reads "System.NullReferenceException, Object reference not set to an instance of an object". What did I do wrong?

Re: How to Marshal AccessibleObjectFromWindow

Hello

In your code the cleanup is completely missing.
But even if I add the three missing
Marshal.FreeCoTaskMem(...);
the code will have a strange behaviour :

When I call it once, it returns the IAccessible interface.
When I call it a second and a third time it still works.
But at the fourth time AccessibleObjectFromWindow()
will return error 0x80040002L (OLE_E_ENUM_NOMORE)
I have no explanation for this really strange behaviour.

I always put my navtive code into a Managed C++ DLL where programming all the Win32 stuff is much easier than in C#:

Please note that ::IAccessible is unmanaged while Accessibility::IAccessible is managed!!!

Even if I call this code in an endless loop, there is no error ever occurring
___________________

If you do NOT call p_Acc->Release(); you will produce a memory leak !!!

If you omit this line of code and call GetAccessibleFromWindow() in an endless loop from C#, you can see in Taskmanager that your process aquires more and more memory (500 MB and more) until your system will hang!!!

On my PC Taskmanager shows that the above function called in an endless loop will not consume more than 80 MB total memory. (physical + virtual) This is the limit at which the garbage collector starts its work.

But you don't have to worry that the COM object in p_Acc will be deleted after calling Release() so the caller of the function would work with a dead COM object :

To check this insert these lines at different locations in the function:
int RefCount = p_Acc->AddRef() - 1;
p_Acc->Release();

Then RefCount will contain the current reference count without modifying it.

You wil see that after calling
AccessibleObjectFromWindow()
RefCount is = 1

And that GetTypedObjectForIUnknown() will increase the refcount by 2, so afterwards it is = 3.

So when the function GetAccessibleFromWindow() exits, RefCount will be = 2 and these 2 references will be decremented when the garbage collector destroys Accessibility::IAccessible

___________

In ThrowError() I call
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, hr, 0, s8_Buf, u32_BufLen, 0);
and throw it then
throw new Exception(s8_Buf);
to display human readable errors.

Re: How to Marshal AccessibleObjectFromWindow

Hi,

I want to access the IDispatch interface from an accessible object and I came across your code. Can you explain how to compile it? I am using Visual Studio 2008, creating a CLR Class Library. Thanks very much.

* The Perfect Platform for Game Developers: Android
Developing rich, high performance Android games from the ground up is a daunting task. Intel has provided Android developers with a number of tools that can be leveraged by Android game developers.

* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.