[RESOLVED] What declaration for AccessibleObjectFromEvent?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: [RESOLVED] What declaration for AccessibleObjectFromEvent?

  1. #1
    Join Date
    Jun 2004
    Location
    NH
    Posts
    674

    [RESOLVED] What declaration for AccessibleObjectFromEvent?

    Does anyone know of a working declaration for the API "AccessibleObjectFromEvent"? Or a good .net equivelant?

    I've spent so much time getting the other main Accessible API to work on .NET, that I'm hoping to start with a good declare on this one.
    I've built a really good narrator, for totally blind people so that they can interface and use the computer in a substantial way. The innovation is a static mouse that controls category input, rather than free mouse movement, and the middle wheel selectes items of that category.
    But I need the last access API for events and voice feedback when the event occurs.


    I'm guessing it's something like this, according to what works for the other API:
    Code:
    Private Declare Function apiAccessibleObjectFromEvent Lib "oleacc" Alias "AccessibleObjectFromEvent" (ByVal hwnd As Int32, ByVal dwObjectID As Int32, ByVal dwChildID As Int32, ByRef ppacc As Global.Accessibility.IAccessible, ByRef pvarChild As Object) As Int32
    In case anyone is interested in the other API's, I've included a project zip file, with:
    AccessibleObjectFromWindow, AccessibleChildren, & AccessibleObjectFromPoint.
    This is loosely based upon microsoft AAccess example written in vb6, available as an online download. I've have not seen a .NET example online, so it might proove useful for someone.

    Code:
    Option Strict On
    Option Explicit On
    Module Accessibility
        Const CHILDID_SELF As Int32 = 0
        Const CHILDID_1 As Int32 = 1
        Const OBJID_CLIENT As Int32 = &HFFFFFFFC
        Const OBJID_CARET As Int32 = &HFFFFFFF8
        Const OBJID_CURSOR As Int32 = &HFFFFFFF7
        Const OBJID_MENU As Int32 = &HFFFFFFFD
        Const OBJID_NATIVEOM As Int32 = &HFFFFFFF0
        Const OBJID_SYSMENU As Int32 = &HFFFFFFFF
        Const OBJID_TITLEBAR As Int32 = &HFFFFFFFE
        Const OBJID_WINDOW As Int32 = 0
        Const OBJID_VSCROLL As Int32 = &HFFFFFFFB
        Const OBJID_HSCROLL As Int32 = &HFFFFFFFA
        Const OBJID_SIZEGRIP As Int32 = &HFFFFFFF9
        Const OBJID_ALERT As Int32 = &HFFFFFFF6
        Const OBJID_SOUND As Int32 = &HFFFFFFF5
        Public Structure POINTAPI
            Public x, y As Int32
        End Structure
        Public Structure RECT
            Public rLeft, rTop, rRight, rBottom As Int32
        End Structure
        Public Structure ACCOBJINFO
            Public Text, Value, DefaultAction, KeyShortcut, Description, Help As String
            Public State, Selection As Double
            Public Parent As Global.Accessibility.IAccessible
            Public Position As POINTAPI
            Public Size As Size
            Public ItemPosition As POINTAPI
            Public ItemSize As Size
        End Structure
        ' Private Declare Function apiAccessibleObjectFromEvent Lib "oleacc" Alias "AccessibleObjectFromEvent" (ByVal hwnd As Int32, ByVal dwObjectID As Int32, ByVal dwChildID As Int32, ByRef ppacc As Global.Accessibility.IAccessible, ByRef pvarChild As Object) As Int32
        Private Declare Function apiAccessibleObjectFromWindow Lib "oleacc" Alias "AccessibleObjectFromWindow" (ByVal Hwnd As Int32, ByVal dwId As Int32, ByRef riid As Guid, ByRef ppacc As Global.Accessibility.IAccessible) As Int32
        Private Declare Function apiAccessibleChildren Lib "oleacc" Alias "AccessibleChildren" (ByVal paccContainer As Global.Accessibility.IAccessible, ByVal iChildStart As Int32, ByVal cChildren As Int32, <System.Runtime.InteropServices.[Out]()> ByVal rgvarChildren() As Object, ByRef pcObtained As Int32) As UInteger
        Private Declare Function apiAccessibleObjectFromPoint Lib "oleacc" Alias "AccessibleObjectFromPoint" (ByVal pt As POINTAPI, ByRef ppacc As Global.Accessibility.IAccessible, ByRef pvarChild As Object) As Int32
        Private Declare Function apiGetCursorPos Lib "user32" Alias "GetCursorPos" (ByRef lpPoint As POINTAPI) As Boolean
        Private Declare Function apiGetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Int32, ByVal lpString As String, ByVal cch As Int32) As Int32
        Private Declare Function apiGetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Int32) As Int32
        Public Declare Function apiFindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Int32, ByVal hWnd2 As Int32, ByVal lpsz1 As String, ByVal lpsz2 As String) As Int32
        Private IID_IAcce As Guid = New Guid("618736E0-3C3D-11CF-810C-00AA00389B71")
        Private IID_IDispatch As Guid = New Guid("00020424-0000-0000-C000-000000000046")
    
        Public Function GetObjectFromPoint(ByVal pt As POINTAPI) As ACCOBJINFO
            On Error Resume Next : GetObjectFromPoint = Nothing ' Not all the acc properties will work  with all the returned objects.
            Dim accObj As Global.Accessibility.IAccessible = Nothing
            Dim objChild As Object = Nothing
            Dim objInf As New ACCOBJINFO
            If pt.x = 0 AndAlso pt.y = 0 Then apiGetCursorPos(pt) ' Get the cursor position where the mouse was clicked.
            apiAccessibleObjectFromPoint(pt, accObj, objChild) ' Get the IAccessible interface of the object located under the cursor position.
            GetObjectFromPoint.Text = accObj.accName(objChild)
            GetObjectFromPoint.Value = accObj.accValue(objChild)
            GetObjectFromPoint.DefaultAction = accObj.accDefaultAction(objChild)
            GetObjectFromPoint.KeyShortcut = accObj.accKeyboardShortcut(objChild)
            GetObjectFromPoint.Description = accObj.accDescription(objChild)
            GetObjectFromPoint.Help = accObj.accHelp(objChild)
            GetObjectFromPoint.State = CDbl(accObj.accState(objChild))
            GetObjectFromPoint.Selection = CDbl(accObj.accSelection())
            GetObjectFromPoint.Parent = CType(accObj.accParent(), IAccessible)
            accObj.accLocation(GetObjectFromPoint.Position.x, GetObjectFromPoint.Position.y, 0, 0, 0)
            accObj.accLocation(0, 0, GetObjectFromPoint.Size.Width, GetObjectFromPoint.Size.Height, 0)
            accObj.accLocation(GetObjectFromPoint.ItemPosition.x, GetObjectFromPoint.ItemPosition.y, 0, 0, objChild)
            accObj.accLocation(0, 0, GetObjectFromPoint.ItemSize.Width, GetObjectFromPoint.ItemSize.Height, objChild)
            accObj = Nothing : objChild = Nothing
        End Function
    
        Public Function GetFormControls(ByVal hwnd As Int32) As ACCOBJINFO() 'This is loosely based upon microsoft AAccess example written in vb6, available as an online download.  No .NET version known though, except this one
            On Error Resume Next
            Dim numCtrls, numCtrlsRet As Int32
            Dim accObj As Global.Accessibility.IAccessible = Nothing
            Dim newAccObj As Global.Accessibility.IAccessible = Nothing
            Dim objChildren() As Global.Accessibility.IAccessible = Nothing
            Dim objControls() As Global.Accessibility.IAccessible = Nothing
            Dim objArray As ACCOBJINFO()
            Dim wText As String = GetWindowText(hwnd)
            If wText = "" Then Return Nothing
            apiAccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAcce, accObj) ' Get forms IAccessible interface
            numCtrls = accObj.accChildCount 'set count to children count
            ReDim objChildren(numCtrls - 1) 'Array length is the number of children parented by object
            apiAccessibleChildren(accObj, 0, numCtrls, objChildren, numCtrlsRet) ' Get all children
            For i As Int32 = 0 To numCtrlsRet - 1 ' Get main client object , since the previous call got all system info etc
                If objChildren(i).accName = wText Then
                    newAccObj = objChildren(i)
                    numCtrls = newAccObj.accChildCount
                End If 'Could get titlebar stuff here
                ' Dim left, top, width, height As Int32
                ' objChildren(i).accLocation(left, top, width, height)
                ' MessageBox.Show( left.ToString & " " & top.ToString & " " & width.ToString & " " & height.ToString)
                ' DrawRectangle(left, top, width, height)
            Next
            ReDim objControls(numCtrls - 1) 'Re dimension, so that we can actually get children controls of the forms IAccessible interface
            apiAccessibleChildren(newAccObj, 0, numCtrls, objControls, numCtrlsRet) 'Get controls
            ReDim objArray(numCtrlsRet - 1)
            For i As Int32 = 0 To numCtrlsRet - 1 'Gather properties of the returned IAccessible objects
                objArray(i).Text = objControls(i).accName
                objArray(i).Value = objControls(i).accValue
                objArray(i).DefaultAction = objControls(i).accDefaultAction
                objArray(i).KeyShortcut = objControls(i).accKeyboardShortcut
                objArray(i).Description = objControls(i).accDescription
                objArray(i).Help = objControls(i).accHelp
                objArray(i).State = CDbl(objControls(i).accState)
                objArray(i).Selection = CDbl(objControls(i).accSelection)
                objArray(i).Parent = CType(objControls(i).accParent, IAccessible)
                objControls(i).accLocation(objArray(i).Position.x, objArray(i).Position.y, 0, 0, 0)
                objControls(i).accLocation(0, 0, objArray(i).Size.Width, objArray(i).Size.Height, 0)
            Next
            accObj = Nothing : newAccObj = Nothing : objChildren = Nothing : objControls = Nothing
            Return objArray 'Return with an array of controls, containing property information of each control
        End Function
    
        Private Function GetWindowText(ByVal hwnd As Int32) As String
            On Error Resume Next
            Dim tLength, rValue As Int32 : GetWindowText = "" 'Initialize string for text name
            tLength = apiGetWindowTextLength(hwnd) + 4 'Get length
            GetWindowText = GetWindowText.PadLeft(tLength) '''''Pad with buffer
            rValue = apiGetWindowText(hwnd, GetWindowText, tLength) 'Get text
            GetWindowText = GetWindowText.Substring(0, rValue) 'Strip buffer
        End Function
    
    End Module
    Attached Files Attached Files

  2. #2
    Join Date
    Jan 2006
    Location
    Chicago, IL
    Posts
    14,999

    Re: What declaration for AccessibleObjectFromEvent?

    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  3. #3
    Join Date
    Jun 2004
    Location
    NH
    Posts
    674

    Re: What declaration for AccessibleObjectFromEvent?

    Thanks dglienna, it was a fair read.
    But I'm actually in the later stages of a full narrator/static mouse, and I just need the one API really.
    Pinvoke, doesn't have it listed, and the vb6 style doesn't work ofcourse, so all previous vb6 examples are obsolete.

    How to do this in .NET?

  4. #4
    Join Date
    Jun 2004
    Location
    NH
    Posts
    674

    Re: What declaration for AccessibleObjectFromEvent?

    I got it!
    Wow that was pretty easy using SetWinEventHook along with the delegate.

    This example snatches the text of the foreground window immediately after it changes. It then displays the foregrounds text in the forms titlebar.
    Project zip file attached below.
    Code:
    Option Strict On
    Option Explicit On
    Public Class Form1 ' Public Class AcessibilityHook
        Const WINEVENT_32BITCALLER As Int32 = &H8000
        Const WINEVENT_INCONTEXT As Int32 = &H4
        Const WINEVENT_OUTOFCONTEXT As Int32 = &H0
        Const WINEVENT_SKIPOWNPROCESS As Int32 = &H2
        Const WINEVENT_SKIPOWNTHREAD As Int32 = &H1
        Const WINEVENT_VALID As Int32 = &H8007
        Const EVENT_MIN As Int32 = 1
        Const EVENT_MAX As Int32 = &H7FFFFFFF
        Const SYS_SOUND As Int32 = 1
        Const SYS_ALERT As Short = 2
        Const SYS_FOREGROUND As Int32 = 3 'active window changing.
        Const SYS_MENUSTART As Int32 = 4  '--entering menu mode.
        Const SYS_MENUEND As Int32 = 5  '--leaving menu mode.
        Const SYS_MENUPOPUPSTART As Int32 = 6 '--popup menu popping up.
        Const SYS_MENUPOPUPEND As Int32 = 7 'popup menu about to close.
        Const SYS_CAPTURESTART As Int32 = 8  '--window took capture.
        Const SYS_CAPTUREEND As Int32 = 9   '--window released capture.
        Const SYS_MOVESIZESTART As Int32 = &HA '-- beginning move or resize.
        Const SYS_MOVESIZEEND As Int32 = &HB  '--ending move or resize.
        Const SYS_CONTEXTHELPSTART As Int32 = &HC
        Const SYS_CONTEXTHELPEND As Int32 = &HD
        Const SYS_DRAGDROPSTART As Int32 = &HE
        Const SYS_DRAGDROPEND As Int32 = &HF
        Const SYS_DIALOGSTART As Int32 = &H10  '--dialogue opens.
        Const SYS_DIALOGEND As Int32 = &H11  '--dialogue about to close.
        Const SYS_SCROLLINGSTART As Int32 = &H12  '--scrolling.
        Const SYS_SCROLLINGEND As Int32 = &H13
        Const SYS_SWITCHSTART As Int32 = &H14  ' Sent when beginning and ending alt-tab mode with the switch window.
        Const SYS_SWITCHEND As Int32 = &H15
        Const SYS_MINIMIZESTART As Int32 = &H16     '--window minimizing.
        Const SYS_MINIMIZEEND As Int32 = &H17    '--window about to restore.
        Const OB_CREATE As Int32 = &H8000  '-- hwnd + ID + idChild is created item
        Const OB_DESTROY As Int32 = &H8001  '-- hwnd + ID + idChild is destroyed item
        Const OB_SHOW As Int32 = &H8002  '-- hwnd + ID + idChild is shown item
        Const OB_HIDE As Int32 = &H8003  '-- hwnd + ID + idChild is hidden item
        Const OB_REORDER As Int32 = &H8004  '-- hwnd + ID + idChild is parent of zordering children
        Const OB_FOCUS As Int32 = &H8005   '--  hwnd + ID + idChild is focused item
        Const OB_SELECTION As Int32 = &H8006 '-- hwnd + ID + idChild is selected item (if only one), or idChild is OBJID_WINDOW if complex
        Const OB_SELECTIONADD As Int32 = &H8007 '-- hwnd + ID + idChild is item added
        Const OB_SELECTIONREMOVE As Int32 = &H8008 '-- hwnd + ID + idChild is item removed
        Const OB_SELECTIONWITHIN As Int32 = &H8009 '-- hwnd + ID + idChild is parent of changed selected
        Const OB_STATECHANGE As Int32 = &H800A ' hwnd + ID + idChild is item w/ state change
        Const OB_LOCATIONCHANGE As Int32 = &H800B  '-- hwnd + ID + idChild is moved/sized item
        Const OB_NAMECHANGE As Int32 = &H800C  '-- hwnd + ID + idChild is item w/ name change
        Const OB_DESCRIPTIONCHANGE As Int32 = &H800D  '-- hwnd + ID + idChild is item w/ desc change
        Const OB_VALUECHANGE As Int32 = &H800E  '-- hwnd + ID + idChild is item w/ value change
        Const OB_PARENTCHANGE As Int32 = &H800F  '-- hwnd + ID + idChild is item w/ new parent
        Const OB_HELPCHANGE As Int32 = &H8010  '-- hwnd + ID + idChild is item w/ help change
        Const OB_DEFACTIONCHANGE As Int32 = &H8011  '-- hwnd + ID + idChild is item w/ def action change
        Const OB_ACCELERATORCHANGE As Int32 = &H8012 '  hwnd + ID + idChild is item w/ keybd accel change
        Private Declare Function apiSetWinEventHook Lib "user32" Alias "SetWinEventHook" (ByVal eventMin As Int32, ByVal eventMax As Int32, ByVal hmodWinEventProc As Int32, ByVal pfnWinEventProc As EventFunc, ByVal idProcess As Int32, ByVal idThread As Int32, ByVal dwFlags As Int32) As Int32
        Private Declare Function apiUnhookWinEvent Lib "user32" Alias "UnhookWinEvent" (ByVal lHandle As Int32) As Int32
        Private Declare Function apiAccessibleObjectFromEvent Lib "oleacc" Alias "AccessibleObjectFromEvent" (ByVal hwnd As Int32, ByVal dwId As Int32, ByVal dwChildId As Int32, ByRef ppacc As Global.Accessibility.IAccessible, ByRef pvarChild As Object) As Int32
        Private Delegate Function EventFunc(ByVal HookHandle As Int32, ByVal LEvent As Int32, ByVal hwnd As Int32, ByVal idObject As Int32, ByVal idChild As Int32, ByVal idEventThread As Int32, ByVal dwmsEventTime As Int32) As Int32
        Private eHook As Int32
        <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.FunctionPtr)> Private mEventFunc As EventFunc
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            HookEvents()
        End Sub
    
        Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
            UnHookEvents()
        End Sub
    
        Public Sub HookEvents()
            If eHook <> 0 Then Exit Sub
            mEventFunc = New EventFunc(AddressOf WinEventFunc)
            eHook = apiSetWinEventHook(SYS_FOREGROUND, SYS_FOREGROUND, 0, mEventFunc, 0, 0, WINEVENT_SKIPOWNPROCESS)
        End Sub
    
        Public Sub UnHookEvents()
            If eHook <> 0 Then apiUnhookWinEvent(eHook)
        End Sub
    
        Private Function WinEventFunc(ByVal eHandle As Int32, ByVal lEvent As Int32, ByVal hWnd As Int32, ByVal objId As Int32, ByVal childId As Int32, ByVal eThreadId As Int32, ByVal eTime As Int32) As Int32
            Dim acc As Global.Accessibility.IAccessible = Nothing
            Dim cId As Object = Nothing
            Dim sName As String = ""
            apiAccessibleObjectFromEvent(hWnd, objId, childId, acc, cId)
            If Not acc Is Nothing Then
                If Not cId Is Nothing Then
                    Try
                        sName = acc.accName(cId)
                        Me.Text = sName
                    Catch ex As System.Runtime.InteropServices.COMException When ex.ErrorCode = -2146827864 'weird 
                    Catch ex As System.Runtime.InteropServices.COMException When ex.ErrorCode = -2147467259  'null
                    Catch ex As System.Runtime.InteropServices.COMException When ex.ErrorCode = -2147417848  'rpc disconnected
                    Catch ex As ArgumentException 'null
                    Catch ex As NullReferenceException
                    End Try
                End If
            End If
            WinEventFunc = 0
        End Function
    
    
    End Class
    Attached Files Attached Files
    Last edited by TT(n); July 6th, 2010 at 07:12 AM.

  5. #5
    Join Date
    Sep 2014
    Posts
    1

    Re: [RESOLVED] What declaration for AccessibleObjectFromEvent?

    Hi, I analized this amazing code. Thanks for this update, Can I contact you? In this code the Accessibiliy properties are more powerful than other source codes. I want to hook the keyboard to these winevents. Can you help me please? I studied this code, the timer is helpful for mouse hook. But I have some problems using the private declare functions "user32", I searched for an example with a keyboard hook, but there is no one with the results of yours. I see a VB6 code, but this one is .NET. I studied the VB6 version and I understood , but I have problems to make an update of this version or a Keyboard hook winevent accesible project.

    Sorry for my english, but I really hope you can help me, I really want to share every update for new purposes, my little brother is blind and I want to learn about accesible programming.

    Any support or update for this code will be huge, thanks!!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center