Search code examples
pythonpywinauto

Need a way to access control in a window with control id using pywinauto


By using class name, value of control is retrieved from window using pywinauto functions. Recently this seems to be problem when trying to use for SAP because class name are dynamic. Is there a way to get dynamic class name of a control or is there way to access control using control ID instead of class name.

from pywinauto.application import Application

app = Application().Connect(title=u'Create Purchase Order', class_name='SAP_FRONTEND_SESSION')
sapfrontendsession = app.SAP_FRONTEND_SESSION
print sapfrontendsession.PrintControlIdentifiers()

it gives

Control Identifiers:
Afx:62F20000:0:00010003:00000010:00000000 - ''   (L14, T38, R1352, B69)
	'' '0' '1' 'Afx:62F20000:0:00010003:00000010:00000000' ()
ComboBox - ''   (L54, T43, R196, B65)
	'2' 'ComboBox' ()
Edit - ''   (L57, T46, R174, B62)
	'3' 'Edit' ()
AfxWnd110 - ''   (L14, T69, R1352, B78)
	'6' 'AfxWnd1103' ()
AfxWnd110 - ''   (L65, T78, R1352, B109)
	'7' 'AfxWnd1104' ()
Afx:62F20000:8:00010003:00000000:00000000 - ''   (L14, T109, R1352, B143)
	'8' 'Afx:62F20000:8:00010003:00000000:00000000' ()
Button - ''   (L24, T115, R170, B135)
	'9' 'Button' 'Button0' 'Button1' ()
Button - ''   (L174, T115, R180, B135)
	'10' 'Button2' ()
Button - ''   (L184, T115, R204, B135)
	'11' 'Button3' ()
Button - ''   (L208, T115, R228, B135)
	'12' 'Button4' ()
Button - ''   (L232, T115, R270, B135)
	'13' 'Button5' ()
Button - ''   (L274, T115, R294, B135)
	'14' 'Button6' ()
Button - ''   (L298, T115, R304, B135)
	'15' 'Button7' ()
Button - ''   (L308, T115, R414, B135)
	'16' 'Button8' ()
Button - ''   (L418, T115, R483, B135)
	'17' 'Button9' ()
Button - ''   (L487, T115, R507, B135)
	'18' 'Button10' ()
Button - ''   (L511, T115, R634, B135)
	'19' 'Button11' ()
Button - ''   (L638, T115, R644, B135)
	'20' 'Button12' ()
Button - ''   (L648, T115, R761, B135)
	'21' 'Button13' ()
Button - ''   (L765, T115, R890, B135)
	'22' 'Button14' ()
Afx:62F20000:8:00010003:00000010:00000000 - 'Standard PO created under the number 4500018380'   (L14, T699, R1352, B728)
	'Afx:62F20000:8:00010003:00000010:00000000' 'Standard PO created under the number 4500018380' 'Standard PO created under the number 4500018380Afx:62F20000:8:00010003:00000010:00000000' ()
Afx:62F20000:1008 - ''   (L14, T143, R1352, B699)
	'27' 'Afx:62F20000:1008' ()
Custom Container Class - 'Custom  Container'   (L17, T151, R44, B172)
	'Custom  Container4' 'Custom  ContainerCustom Container Class4' 'Custom Container Class4' ()
Shell Window Class - 'Control  Container'   (L17, T151, R44, B172)
	'Control  Container4' 'Control  ContainerShell Window Class4' 'Shell Window Class4' ()
SAPImage - ''   (L17, T151, R44, B172)
	'34' 'SAPImage2' ()
GOSContainer Class - 'Gos Container'   (L14, T78, R65, B109)
	'GOSContainer Class' 'Gos Container' 'Gos ContainerGOSContainer Class' ()
Shell Window Class - 'Control  Container'   (L24, T82, R65, B104)
	'Control  Container6' 'Control  ContainerShell Window Class6' 'Shell Window Class6' ()
ATL:664AB3D8 - ''   (L24, T82, R66, B104)
	'40' 'ATL:664AB3D8' ()
SysPager - 'SAPPagerForToolbar'   (L24, T82, R95, B104)
	'Pager' 'SAPPagerForToolbar' 'SAPPagerForToolbarPager' ()
ToolbarWindow32 - ''   (L24, T82, R95, B104)
	'41' 'Toolbar' ()

control need is Afx:62F20000:8:00010003:00000010:00000000 but its getting changed for every run.when inspected with swapy,controlID is same.Is there a possiblity using controlID Text on this control can be retrieved.


Solution

  • Control ID is usually not guaranteed to be permanent. I believe matching class_name by regular expression would be more reliable.

    app.Dialog.child_window(class_name_re='^constant_part.*$').some_method()
    
    # though Control ID can be used so
    app.Dialog.child_window(control_id=0x5D).some_method()
    # or
    app.Dialog.child_window(class_name_re='^constant_part.*$', found_index=0).some_method()
    

    The same should work for title_re. In your particular case:

    sapfrontednsession.child_window(title_re='^Standard PO created under the number \d+$').click()
    

    Control ID can be found using Spy++ utility included into MS Visual Studio (available from Start menu).

    sapfrontednsession.child_window(control_id=<found ID in hex>).click()