My own Excel Automation Framework(GUI FUNCTIONS )

Part 3     Building an object Map:

Approaches to GUI Automation

Microsoft Windows offers two API specifications for user interface accessibility and software test automation: Microsoft Active Accessibility, and Microsoft UI Automation. Microsoft Active Accessibility is the legacy API that was introduced in Windows 95 as a platform add-in. UI Automation is a Windows implementation of the UI Automation specification

      • Using Microsoft Active Accessibility
      • Using Microsoft UI Automation.
  • I have used win32 API functions for UI Automation. Before explaining my functions few points on Automation Approach.
  • All UI Elements (user controls) on your desktop are windows. To manipulate a control you need to have the nos. of its handle (window handle) .Window handles are numerical digits of type long. The handle value changes each time the control is created ,Hence one needs to access it programmatically. To retrieve a window handle programmatically we have to uniquely identify a user control, The challenge here is some user controls /elements have window names, but many don’t, typical attributes available for identification are as under. Visit for more details.


  • Window Text (Name):It is the text/caption on a UI element / control, for example “&Next” on a button, though this attribute has a lot of utility while using it in identification of button elements one must use it keeping in mind that quiet a few UI element / control do not have this attribute populated, while in some cases this attribute is dynamic and keeps changing at run time.
  • Window Class : For more details on window classes pls refer   It should be noted that class alone is not a unique identifier as a form can have many buttons. A class along with window text is often used for identifying a UI element / control.
  •  Control Id: Control index number is the internal numeric identifier that the operating system gives to each UI element / control, they       are created by the order in which they are coded to the main window, Traditionally, it has been the most widely used       identifier for UI. as it persisted across multiple instances of the form, and was unique over 90 percent of the time. However, in Windows Forms (Dot Net), the control ID is a mirror image of the HWND for that particular UI element / control. Hence for dot net applications the control ID may be different every time you launch the form.
  • Windows Position/Hierarchy Order :  Another   option is to use child ordering in the UI element /control tree. That is, if you knew that the textbox you wanted to read was the second child of the parent main form, you could get the first sibling of the first child by using the appropriate parameters to find the HWND of the textbox. While using this approach one has to be wary that the ordering of UI elements changes whenever the developer adds new control or new level.


Typically the value of the above mentioned attributes of a UI element/control is accessed by a spy tool, some of the freely available spy tools are as under.

I have created my own spytool using 2 subs, currently it captures details of all windows upto 3 level deep. You too can create the same by following the steps below.


  • I will continue to work further on MyOwnExcelFramework.xlsm workbook, as we did in the part 1 and 2 of the tutorial, Here I will just put in a note of caution that going forward it is mandatory that you read part 1 and 2 of the tutorial, as in this and the next tutorial, I will be using the same base and extending its functionality to handle UI elements /control.
  • Rename sheet1 as ObjectMap


  • We will move to VBA module.
  • In the project window ,click at VBAProject (MyOwnExcelframework.xlsm)       highlighting the same, right click VBAProject (MyOwnExcelframework.xlsm),click Insert Module, It will insert a module with default name Module1.
  • All our Spy/Object Map code will reside in the module ” Module1″ which has an extension .bas and is a text file. This will help us address the version control challenges.
  • The project references remain same as mentioned in part 2.
  • In the code window ,first declare the  public variables as below.


Public Declare Function GetWindowText Lib “User32” Alias “GetWindowTextA” (ByVal hwnd As Long, ByVal lpString As String, ByVal cchar As Long) As Long

Public Declare Function GetWindowTextLength Lib “User32” Alias “GetWindowTextLengthA” (ByVal hwnd As Long) As Long

Public Declare Function GetClassName Lib “User32” Alias “GetClassNameA” (ByVal hwnd As Long, ByVal lpString As String, ByVal cchar As Long) As Long

Public Declare Function GetWindowLong Lib “User32” Alias “GetWindowLongA” (ByVal hwnd As Long, ByVal nindex As Long) As Long

Private Declare Function FindWindow Lib “User32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) 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


Private intRowNo As Integer

‘Const for Dialog (Form) Data

Const GWL_WNDPROC = -4



Const GWL_STYLE = -16

Const GWL_EXSTYLE = -20

Const GWL_USERDATA = -21

Const GWL_ID = -12

Option Base 1

  • Copy our first procedure for creating an Object Map as below

 Private Sub Object_Map()

Dim lngParenthandle As Long

Dim lngChildhandle As Long

Dim lngControlid As Long

Dim strParentwindowtitle As String

Dim lngWindHndlArray3(15, 50, 75) As Long

Dim lngWindHndlArray1(15) As Long

Dim lngWindHndlArray2(15, 50) As Long

Dim intx As Integer

Dim inty As Integer

Dim intz As Integer

10   On Error GoTo Error_Handler

20   intx = 1

30   inty = 1

40   intz = 1

50   intRowNo = 1

60   strParentwindowtitle = Worksheets(“RunManager”).Cells(m, 5)

70   lngParenthandle = FindWindow(vbNullString, strParentwindowtitle)

80   If lngParenthandle <> 0 Then ‘ Parent found

90   lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

100   Else

110   Log_Test “While executing list windows, parent window not found for parent: ” & strParentwindowtitle

120   Exit Sub

130   End If

140       Do While lngChildhandle <> 0   ‘1st Level Child Foundd

150       Print_Window lngParenthandle, lngChildhandle, CStr(intx)

160       lngWindHndlArray1(intx) = lngChildhandle

170       lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

180               If lngChildhandle = 0 Then ‘ 1st dimension over

190               Exit Do

200               End If

210       intx = intx + 1

220       Loop

‘ procedure for second level child

 230      For n = 1 To intx

240       lngParenthandle = lngWindHndlArray1(n)

250        lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

260        inty = 1

270       Do While lngChildhandle <> 0

280       Print_Window lngParenthandle, lngChildhandle, n & “,” & inty

290       lngWindHndlArray2(n, inty) = lngChildhandle

300       lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

310                     If lngChildhandle = 0 Then ‘ 1st dimension over

320                    Exit Do

330                    End If

340     inty = inty + 1

350      Loop

360      Next n

‘procedure for third level child


370    For n = 1 To intx

380    For o = 1 To UBound(lngWindHndlArray2, 2)

390     lngParenthandle = lngWindHndlArray2(n, o)

400               If lngParenthandle = 0 Then

410                   Exit For

420               End If

430      lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

440      intz = 1

450      Do While lngChildhandle <> 0

460       Print_Window lngParenthandle, lngChildhandle, n & “,” & o & “,” & intz

470        lngWindHndlArray3(n, o, intz) = lngChildhandle

480        lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

490                  If lngChildhandle = 0 Then ‘ 1st dimension over

500                  Exit Do

510                   End If

520         intz = intz + 1

530        Loop

540        Next o

550        Next n

560   Exit Sub


570   Handle_Error “Object_Map”, Erl

End Sub

  • The second procedure is “Print_Window” to write the window attributes in excel sheet “Object Map”

Private Sub Print_Window(lngParenthandle As Long, lngChildhandle As Long, strposition As String)

Dim strClassname As String

Dim strWindowtext As String

10     On Error GoTo Error_Handler

20     strWindowtext = Space(GetWindowTextLength(lngChildhandle) + 1)

30     strClassname = Space(256)

40     GetWindowText lngChildhandle, strWindowtext, Len(strWindowtext)

50     GetClassName lngChildhandle, strClassname, Len(strClassname)

60     Worksheets(“ObjectMap”).Cells(intRowNo, 1) = “Window Position :” & strposition

70     Worksheets(“ObjectMap”).Cells(intRowNo, 2) = “Window Text:” & strWindowtext

80     Worksheets(“ObjectMap”).Cells(intRowNo, 3) = “Window ClassName:” & strClassname

90     Worksheets(“ObjectMap”).Cells(intRowNo, 4) = “Window Parent Handle:” & lngParenthandle

100   Worksheets(“ObjectMap”).Cells(intRowNo, 5) = “Window Handle:” & lngChildhandle

110    Worksheets(“ObjectMap”).Cells(intRowNo, 6) = “Controls ID:” & GetWindowLong(lngChildhandle, GWL_ID)

120   intRowNo = intRowNo + 1

130   Exit Sub


140   Handle_Error “Print_Window”, Erl

End Sub

  • Finally to run the Object Map procedure Go back to the excel worksheet, In Worksheet “Run Manager” Your Test case starts from Row nos 10.
  • Test Step       1 as under..
    • Row       10 Column   C as         “Object_Map”
    • Row       10 Column   D as         “Y”
    • Row       10 Column   E  as         “Calculator”
  • We have our test case ready to execute. before you click RunManager please ensure you have the calculator app up and running.
  • Just click at RunManager

  • After execution click at worksheet ObjectMap to see details of UI elements / controls

Part2 Part4

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s