PInvoke Help Needed

Posted on 2005-03-05
Medium Priority
Last Modified: 2012-08-13
I'm trying to utilize the AccessibleObjectFromWindow method of the Active Accessiblity SDK.   It is defined as follows (from the sdk documentation):

STDAPI AccessibleObjectFromWindow(
  HWND hwnd,
  DWORD dwObjectID,
  REFIID riid,
  void** ppvObject

I have defined it in my C# code as:

[DllImport("Oleacc.dll", EntryPoint="AccessibleObjectFromWindow")]
    private static extern int _AccessibleObjectFromWindow(int hwnd,
        int dwObjectID,
        System.Guid riid,
        out System.IntPtr ppvObject);

I also have the following defined to pass parameters for dwObjectID and riid:

public static Guid IDD_IACCESSIBLE = new Guid(0x618736e0, 0x3c3d, 0x11cf, 0x81, 0x0c, 0x00,0xaa, 0x00, 0x38, 0x9b,0x71);
            public static int OBJID_WINDOW = 0x00000000;

Now I've written a function to wrap that as follows:

public static int AccessibleObjectFromWindow(int hwnd, int dwObjectID, System.Guid riid, IAccessible ppvObject)
                  //IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
                  IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
                  Marshal.WriteIntPtr(ptr, IntPtr.Zero);

                  int result = _AccessibleObjectFromWindow(hwnd, dwObjectID, riid, out ptr);
                  if (result == 0)
                        ppvObject = (IAccessible)Marshal.GetObjectForIUnknown(Marshal.ReadIntPtr(ptr));
                  return result;

And call it with:

int hr = WAccessible.AccessibleObjectFromWindow(hwnd, WAccessible.OBJID_WINDOW, WAccessible.IDD_IACCESSIBLE ,acc);

In this call, the hwnd is set from a call to FindWindow from User32.dll, acc is defined as IAccessible and is null.

The result of the _AccessibleObjectFromWindow(hwnd, dwObjectID, riid, out ptr); call turns out to be an Invalid Argument Exception and I can't figure out why.  The only possiblity I can think of is that possibly doing something wrong with the pointers.  

Please help!


I just want to add that the SDK documentation on AccessibleObjectFromWindow is available Here:  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaaccrf_2r7b.asp

Question by:andyalmq
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
LVL 18

Expert Comment

ID: 13468967
Try this declaration....

 [DllImport("oleacc.dll", ExactSpelling=true, PreserveSig=false)]
 [return: MarshalAs(UnmanagedType.Interface)]
 public static extern object AccessibleObjectFromWindow(
    IntPtr hwnd,
    uint dwObjectID,
    [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
LVL 18

Expert Comment

ID: 13469061
Then you can try to cast the returned object as IAccessible

Author Comment

ID: 13471038
That appears to have worked correctly, but could you please try to explain what I was doing wrong?  I understand what ExactSpelling and PreserveSig did.  

Was there a specific reason for returning the out parameter as the return value? (other than as the framework documentation says of not needing it)

Why return the object as an interface rather than a pointer to it?  is this due to the fact that that it was originally defined as void**?

I'd really appreciate these answers.

LVL 18

Accepted Solution

testn earned 2000 total points
ID: 13471226
It's more difficult that way. Basically, ppvObject is IUnknown object and needed to be marshalled to IAccessible which makes it more difficult.

To implement like the one i proposed make it easier since we can specify the return argument and choose to ignore HRESULT from the api. When PreservSig is set to false, a call that returns an HRESULT of S_OK is transformed such that the [out, retval] parameter is used as the function return value.

Featured Post

Linux Academy Android App Now Supports Chromecast

We have some fantastic news for our Android fans. We’re so excited to announce that the Linux Academy Android app is now available with Chromecast support. That’s right – simply download the latest update of the Linux Academy App and start casting your favorite course videos!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A basic question.. “What is the Garbage Collector?” The usual answer given back: “Garbage collector is a background thread run by the CLR for freeing up the memory space used by the objects which are no longer used by the program.” I wondered …
This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question