The following code shows three Office applications accessible from their windows handle (please ensure you have them running before testing). They work via the Accessibility API. I had some fun writing code to find the general pattern and that generic code follows in the next post.
- Option Explicit
- Option Private Module
- Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc.dll" ( _
- ByVal hwnd As LongPtr, ByVal dwId As Long, ByRef riid As Any, ByRef ppvObject As Object) As Long
- Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
- (ByVal hWnd1 As Long, ByVal hwnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
- Public Function GetExcelAppObjectByIAccessible() As Object
- Dim guid(0 To 3) As Long, acc As Object
- guid(0) = &H20400 : guid(1) = &H0 : guid(2) = &HC0 : guid(3) = &H46000000
- Dim alHandles(0 To 2) As Long
- alHandles(0) = FindWindowEx(0, 0, "XLMAIN", vbNullString)
- alHandles(1) = FindWindowEx(alHandles(0), 0, "XLDESK", vbNullString)
- alHandles(2) = FindWindowEx(alHandles(1), 0, "EXCEL7", vbNullString)
- If AccessibleObjectFromWindow(alHandles(2), -16&, guid(0), acc) = 0 Then
- Set GetExcelAppObjectByIAccessible = acc.Application
- End If
- End Function
- Public Function GetWordAppObjectByIAccessible() As Object
- Dim guid(0 To 3) As Long, acc As Object
- guid(0) = &H20400 : guid(1) = &H0 : guid(2) = &HC0 : guid(3) = &H46000000
- Dim alHandles(0 To 3) As Long
- alHandles(0) = FindWindowEx(0, 0, "OpusApp", vbNullString)
- alHandles(1) = FindWindowEx(alHandles(0), 0, "_WwF", vbNullString)
- alHandles(2) = FindWindowEx(alHandles(1), 0, "_WwB", vbNullString)
- alHandles(3) = FindWindowEx(alHandles(2), 0, "_WwG", vbNullString)
- If AccessibleObjectFromWindow(alHandles(3), -16&, guid(0), acc) = 0 Then
- Set GetWordAppObjectByIAccessible = acc.Application
- End If
- End Function
- Public Function GetPowerPointAppObjectByIAccessible() As Object
- Dim guid(0 To 3) As Long, acc As Object
- guid(0) = &H20400 : guid(1) = &H0 : guid(2) = &HC0 : guid(3) = &H46000000
- Dim alHandles(0 To 2) As Long
- alHandles(0) = FindWindowEx(0, 0, "PPTFrameClass", vbNullString)
- alHandles(1) = FindWindowEx(alHandles(0), 0, "MDIClient", vbNullString)
- alHandles(2) = FindWindowEx(alHandles(1), 0, "mdiClass", vbNullString)
- If AccessibleObjectFromWindow(alHandles(2), -16&, guid(0), acc) = 0 Then
- Set GetPowerPointAppObjectByIAccessible = acc.Application
- End If
- End Function
- Sub TestGetExcelAppObjectByIAccessible()
- Dim obj As Object
- Set obj = GetExcelAppObjectByIAccessible()
- Debug.Print obj.Name
- End Sub
- Sub TestGetWordAppObjectByIAccessible()
- Dim obj As Object
- Set obj = GetWordAppObjectByIAccessible()
- Debug.Print obj.Name
- End Sub
- Sub TestGetPowerPointAppObjectByIAccessible()
- Dim obj As Object
- Set obj = GetPowerPointAppObjectByIAccessible()
- Debug.Print obj.Name
- End Sub
We can visualise what is going on with the following output reports, first the Excel windows handles report ...

Next the Word windows handles report ...

Finally the PowerPoint windows handles report ...

No comments:
Post a Comment