Monday, 28 January 2019

VBA - Code to get Excel, Word, PowerPoint from window handle

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.

  1. Option Explicit
  2. Option Private Module
  3.  
  4. Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc.dll" ( _
  5.     ByVal hwnd As LongPtr, ByVal dwId As LongByRef riid As Any, ByRef ppvObject As ObjectAs Long
  6.  
  7. Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
  8.     (ByVal hWnd1 As LongByVal hwnd2 As LongByVal lpsz1 As StringByVal lpsz2 As StringAs Long
  9.  
  10. Public Function GetExcelAppObjectByIAccessible() As Object
  11.     Dim guid(0 To 3) As Long, acc As Object
  12.     guid(0) = &H20400 : guid(1) = &H0 : guid(2) = &HC0 : guid(3) = &H46000000
  13.  
  14.     Dim alHandles(0 To 2) As Long
  15.     alHandles(0) = FindWindowEx(0, 0, "XLMAIN", vbNullString)
  16.     alHandles(1) = FindWindowEx(alHandles(0), 0, "XLDESK", vbNullString)
  17.     alHandles(2) = FindWindowEx(alHandles(1), 0, "EXCEL7", vbNullString)
  18.     If AccessibleObjectFromWindow(alHandles(2), -16&, guid(0), acc) = 0 Then
  19.         Set GetExcelAppObjectByIAccessible = acc.Application
  20.     End If
  21. End Function
  22.  
  23.  
  24. Public Function GetWordAppObjectByIAccessible() As Object
  25.     Dim guid(0 To 3) As Long, acc As Object
  26.     guid(0) = &H20400 : guid(1) = &H0 : guid(2) = &HC0 : guid(3) = &H46000000
  27.  
  28.     Dim alHandles(0 To 3) As Long
  29.     alHandles(0) = FindWindowEx(0, 0, "OpusApp", vbNullString)
  30.     alHandles(1) = FindWindowEx(alHandles(0), 0, "_WwF", vbNullString)
  31.     alHandles(2) = FindWindowEx(alHandles(1), 0, "_WwB", vbNullString)
  32.     alHandles(3) = FindWindowEx(alHandles(2), 0, "_WwG", vbNullString)
  33.     If AccessibleObjectFromWindow(alHandles(3), -16&, guid(0), acc) = 0 Then
  34.         Set GetWordAppObjectByIAccessible = acc.Application
  35.     End If
  36. End Function
  37.  
  38.  
  39. Public Function GetPowerPointAppObjectByIAccessible() As Object
  40.     Dim guid(0 To 3) As Long, acc As Object
  41.     guid(0) = &H20400 : guid(1) = &H0 : guid(2) = &HC0 : guid(3) = &H46000000
  42.  
  43.     Dim alHandles(0 To 2) As Long
  44.     alHandles(0) = FindWindowEx(0, 0, "PPTFrameClass", vbNullString)
  45.     alHandles(1) = FindWindowEx(alHandles(0), 0, "MDIClient", vbNullString)
  46.     alHandles(2) = FindWindowEx(alHandles(1), 0, "mdiClass", vbNullString)
  47.     If AccessibleObjectFromWindow(alHandles(2), -16&, guid(0), acc) = 0 Then
  48.         Set GetPowerPointAppObjectByIAccessible = acc.Application
  49.     End If
  50. End Function
  51.  
  52. Sub TestGetExcelAppObjectByIAccessible()
  53.     Dim obj As Object
  54.     Set obj = GetExcelAppObjectByIAccessible()
  55.     Debug.Print obj.Name
  56. End Sub
  57.  
  58.  
  59. Sub TestGetWordAppObjectByIAccessible()
  60.     Dim obj As Object
  61.     Set obj = GetWordAppObjectByIAccessible()
  62.     Debug.Print obj.Name
  63. End Sub
  64.  
  65.  
  66. Sub TestGetPowerPointAppObjectByIAccessible()
  67.     Dim obj As Object
  68.     Set obj = GetPowerPointAppObjectByIAccessible()
  69.     Debug.Print obj.Name
  70. End Sub
  71.  
  72.  
  73.  
  74.  

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