Rahul Bandopadhyaya
Rahul Bandopadhyaya

Reputation: 79

Java access bridge- issue while using getAccessibleContextAt

In C#.net code, have been trying to use the interface- getAccessibleContextAt in the following manner.

  1. For the Java application in concern, I identify the main windows-handle
  2. I get the pointer for the application context and the vmid using getAccessibleContextFromHWND. These are non zero and getAccessibleContextFromHWND returns true.
  3. With these values and mouse position (x,y) trying to fetch the context of the underlying control using the interface getAccessibleContextAt. This method returns true, but the pointer for the control is zero.

Here is the code I am using:

private void GetJavaElementDetails(IntPtr javaAppHandle, int x, int y)
{
    if (JABHelper.isJavaWindow(javaAppHandle)==1)
    {
        Int32 vmid;
        IntPtr appContextPointer, ctlContextPointer;
        bool result = JABHelper.getAccessibleContextFromHWND(javaAppHandle, out vmid, out appContextPointer);
        result = JABHelper.getAccessibleContextAt(vmid, appContextPointer, x, y, out ctlContextPointer);
        AccessibleContextInfo acinfo = new AccessibleContextInfo();
        IntPtr acinfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(new AccessibleContextInfo()));
        Marshal.StructureToPtr(new AccessibleContextInfo(),acinfoPtr, true);

        if (JABHelper.getAccessibleContextInfo(vmid, ctlContextPointer, acinfoPtr))
        {
            acinfo = (AccessibleContextInfo)Marshal.PtrToStructure(acinfoPtr, typeof(AccessibleContextInfo));
        }
    }
}

Where JABHelper is just a wrapper around the different interfaces exposed by the WindowsAccessBridge.dll.

ctlContextPointer- always happen to be zero. Any resolution for this issue will be highly appreciated. Also please let me know if I am doing something wrongly.

Upvotes: 4

Views: 1858

Answers (2)

Saket Ranjan
Saket Ranjan

Reputation: 11

[DllImport("WindowsAccessBridge-64.dll", SetLastError = true, ThrowOnUnmappableChar = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public extern static unsafe Boolean getAccessibleContextAt(long vmID, IntPtr acParent, Int32 x, Int32 y, out IntPtr ac);```

[DllImport("WindowsAccessBridge-64.dll", SetLastError = true, ThrowOnUnmappableChar = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public extern static unsafe Boolean getAccessibleContextInfo(Int32 vmID, IntPtr accessibleContext, IntPtr acInfo);

--get the control handle using below line of code
--Used @Deepak answer reference

IntPtr retPtrForAC = Marshal.AllocHGlobal(Marshal.SizeOf(new Int32()));
JabApi.getAccessibleContextAt(vmID, CurrentPtr, Xcord, Ycord, out retPtrForAC);


--Now get the Accessible context from retPtrForAC
IntPtr acPtr = Marshal.AllocHGlobal(Marshal.SizeOf(new AccessibleContextInfo()));
JabApi.getAccessibleContextInfo(vmID, retPtrForAC, acPtr);
var accessibleContextInfo = (AccessibleContextInfo)Marshal.PtrToStructure(acPtr, typeof(AccessibleContextInfo));


Upvotes: 0

Deepak Garud
Deepak Garud

Reputation: 1129

See this code on the Oracle Forums.

Check if you are properly declaring required structures and functions and if other functions to get accessible context info are working.

Also, see the definition of GetAccessibleContextAt() in AccessBridgeCalls.c (from the JavaFerret sample):

BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, 
                            jint x, jint y, AccessibleContext *ac)

This means that WindowsAccessBridge.dll is expecting a pointer to memory allocated by you so it will write into that memory. Instead of passing IntPtr object as last parameter, try this:

IntPtr retPtrForAC = Marshal.AllocHGlobal(Marshal.SizeOf(new Int32()));
result = JABHelper.getAccessibleContextAt(vmid, appContextPointer, x, y, out retPtrForAC);

Also use try catch blocks to check for exceptions.

Upvotes: 1

Related Questions