Jump to content
BatMan22

Microsoft Access / MS IUI help

Recommended Posts

BatMan22

Hey guys, so I am trying to use the MS IUI to click a control button, and with my 'wrapper'-free code, the code is super fast, it attempts to click a radio button named "Analytical", which is correct. Except that it apparently is using the wrong radio button, maybe there's two (one not visible?) because Microsoft Access(our version has been customized and is called Omega) gives me the error, "MicrosoftAccess(basically) can't move the focus to the control Option17". I think I'm toggling the wrong thing.. So I tried to add the ControlType in there but then it finds nothing.. (see first code segments).. Simple Spy output is on the second code segment.. The third code segment is the output from Microsoft Inspect Tool. 

 

Thanks guys, I really hate this MS IUI Automation stuff, I feel like autoit is clear and easy to use and the MS IUI stuff is as ugly and complicated as possible :P

My Code: 

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
#include "UIAWrappers.au3"

local $oButton

#forceref $oButton
#AutoIt3Wrapper_UseX64=Y  ;Should be used for stuff like tagpoint having right struct etc. when running on a 64 bits os

local $program="MicrosoftAccess(basically)"

local $cButton1
$cButton1="Analytical"

Local $omega=_UIA_getFirstObjectOfElement($UIA_oDesktop,$program, $treescope_children)

if isobj($omega) Then

    $oButton=_UIA_getFirstObjectOfElement($omega,"name:=Analytical", $treescope_subtree) ; Works but chooses wrong item apparently?
;~  $oButton=_UIA_getFirstObjectOfElement($omega,"name:=Analytical;ControlType:=UIA_RadioButtonControlTypeId", $treescope_subtree) ; Works but chooses wrong item apparently?

    local $oInvokeP=_UIA_getpattern($oButton,$UIA_InvokePatternID)
    $oInvokeP.Invoke
EndIf

 

SimpleSpyOutput: 

https://www.autoitscript.com/forum/topic/153520-iuiautomation-ms-framework-automate-chrome-ff-ie/?do=findComment&comment=1156373 
At least we have an element title: [Analytical] class: []

Having the following values for all properties: 
Title is: <Analytical>  Class   := <>   controltype:= <UIA_RadioButtonControlTypeId>    ,<50013>    , (0000C35D)    359;465;17;16
*** Parent Information top down ***
3: Title is: <McCampbell Omega_Me - [ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Offi]> Class   := <OMain>  controltype:= <UIA_WindowControlTypeId> ,<50032>    , (0000C370)    333;125;1544;831
"Title:=McCampbell Omega_Me - [ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Offi];controltype:=UIA_WindowControlTypeId;class:=OMain""    
2: Title is: <Workspace>    Class   := <MDIClient>  controltype:= <UIA_PaneControlTypeId>   ,<50033>    , (0000C371)    341;270;1528;656
"Title:=Workspace;controltype:=UIA_PaneControlTypeId;class:=MDIClient"" 
1: Title is: <ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=LIMS_BACKEND;>   Class   := <OForm>  controltype:= <UIA_WindowControlTypeId> ,<50032>    , (0000C370)    333;240;1544;694
"Title:=ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=LIMS_BACKEND;;controltype:=UIA_WindowControlTypeId;class:=OForm""  
0: Title is: <SelectTopic>  Class   := <>   controltype:= <UIA_CustomControlTypeId> ,<50025>    , (0000C369)    351;372;172;236
"Title:=SelectTopic;controltype:=UIA_CustomControlTypeId;class:=""  


;~ *** Standard code maintainable ***
#include "UIAWrappers.au3"
AutoItSetOption("MustDeclareVars", 1)

_UIA_setVar("oP1","Title:=McCampbell Omega_Me - [ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Offi];controltype:=UIA_WindowControlTypeId;class:=OMain")  ;McCampbell Omega_Me - [ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Offi]
_UIA_setVar("oP2","Title:=Workspace;controltype:=UIA_PaneControlTypeId;class:=MDIClient")   ;Workspace
_UIA_setVar("oP3","Title:=ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=LIMS_BACKEND;;controltype:=UIA_WindowControlTypeId;class:=OForm")    ;ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=LIMS_BACKEND;
_UIA_setVar("oP4","Title:=SelectTopic;controltype:=UIA_CustomControlTypeId;class:=")    ;SelectTopic

;~ $oUIElement=_UIA_getObjectByFindAll("Analytical.mainwindow", "title:=Analytical;ControlType:=UIA_RadioButtonControlTypeId", $treescope_subtree)
_UIA_setVar("oUIElement","Title:=Analytical;controltype:=UIA_RadioButtonControlTypeId;class:=") ;ControlType:=UIA_RadioButtonControlTypeId;classname:=")

;~ Actions split away from logical/technical definition above can come from configfiles 

;~_UIA_Action("oP1","highlight")
_UIA_Action("oP1","setfocus")
;~_UIA_Action("oP2","highlight")
_UIA_Action("oP2","setfocus")
;~_UIA_Action("oP3","highlight")
_UIA_Action("oP3","setfocus")
;~_UIA_Action("oP4","highlight")
_UIA_Action("oP4","setfocus")

_UIA_action("oUIElement","highlight")
;~_UIA_action("oUIElement","click")


;~ *** Standard code Flexible***
#include "UIAWrappers.au3"
AutoItSetOption("MustDeclareVars", 1)

Local $oP3=_UIA_getObjectByFindAll($UIA_oDesktop, "Title:=McCampbell Omega_Me - [ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Offi];controltype:=UIA_WindowControlTypeId;class:=OMain", $treescope_children) 
_UIA_Action($oP3,"setfocus")
Local $oP2=_UIA_getObjectByFindAll($oP3, "Title:=Workspace;controltype:=UIA_PaneControlTypeId;class:=MDIClient", $treescope_children)   
_UIA_Action($oP2,"setfocus")
Local $oP1=_UIA_getObjectByFindAll($oP2, "Title:=ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=LIMS_BACKEND;;controltype:=UIA_WindowControlTypeId;class:=OForm", $treescope_children)    
_UIA_Action($oP1,"setfocus")
Local $oP0=_UIA_getObjectByFindAll($oP1, "Title:=SelectTopic;controltype:=UIA_CustomControlTypeId;class:=", $treescope_children)    
;~ First find the object in the parent before you can do something
;~$oUIElement=_UIA_getObjectByFindAll("Analytical.mainwindow", "title:=Analytical;ControlType:=UIA_RadioButtonControlTypeId", $treescope_subtree)
Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=Analytical;ControlType:=UIA_RadioButtonControlTypeId", $treescope_subtree)
;~_UIA_action($oUIElement,"highlight")
_UIA_action($oUIElement,"click")


*** Detailed properties of the highlighted element ***
UIA_title:= <Analytical>
UIA_text:= <Analytical>
UIA_regexptitle:= <Analytical>
UIA_iaccessiblechildId:= <0>
UIA_handle:= <0>
UIA_BoundingRectangle:= <359;465;17;16>
 

 

Microsoft Inspect Tool Output: 

How found:  Focus
BoundingRectangle:  {l:18 t:332 r:35 b:348}
ProcessId:  6620
ControlType:    UIA_RadioButtonControlTypeId (0xC35D)
LocalizedControlType:   "radio button"
Name:   "Analytical"
AccessKey:  ""
HasKeyboardFocus:   true
IsKeyboardFocusable:    true
IsEnabled:  true
HelpText:   ""
IsPassword: false
IsOffscreen:    false
ProviderDescription:    "[pid:6620,hwnd:0x0 Main(parent link):Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]"
SelectionItem.IsSelected:   false
LegacyIAccessible.ChildId:  0
LegacyIAccessible.DefaultAction:    "Check"
LegacyIAccessible.Description:  ""
LegacyIAccessible.Help: ""
LegacyIAccessible.KeyboardShortcut: ""
LegacyIAccessible.Name: "Analytical"
LegacyIAccessible.Role: radio button (0x2D)
LegacyIAccessible.State:    focused,focusable (0x100004)
LegacyIAccessible.Value:    ""
IsDockPatternAvailable: false
IsExpandCollapsePatternAvailable:   false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable:   true
IsLegacyIAccessiblePatternAvailable:    true
IsMultipleViewPatternAvailable: false
IsRangeValuePatternAvailable:   false
IsScrollPatternAvailable:   false
IsScrollItemPatternAvailable:   false
IsSelectionItemPatternAvailable:    true
IsSelectionPatternAvailable:    false
IsTablePatternAvailable:    false
IsTableItemPatternAvailable:    false
IsTextPatternAvailable: false
IsTogglePatternAvailable:   false
IsTransformPatternAvailable:    false
IsValuePatternAvailable:    false
IsWindowPatternAvailable:   false
IsItemContainerPatternAvailable:    false
IsVirtualizedItemPatternAvailable:  false
IsSynchronizedInputPatternAvailable:    false
FirstChild: [null]
LastChild:  [null]
Next:   "Analytical" text
Previous:   "Coordination" text
Other Props:    Object has no additional properties
Children:   Container has no children
Ancestors:  "SelectTopic" 
    "ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Off
    "Workspace" pane
    "McCampbell Omega_Me - [ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connectio
    "Desktop" pane
    [ No Parent ]

 

Share this post


Link to post
Share on other sites
LarsJ

BatMan22, When you already use Inspect.exe, be aware that through the Action menu you can test different actions on the selected control. There is a description in this post. You should be able to test if you can click the radio button.

Share this post


Link to post
Share on other sites
BatMan22

@LarsJ Hmm.. you're right, Inspect.exe gives the same error.. " MicrosoftAccess(basically) can't move the focus to the control Option17 " Which is weird because I was under the impression that SimplySpy uses the same MS IUI framework.. and that's able to click the radio button... so.. I guess my question is.. Why is SimpleSpy able to do it but inspect.exe isn't? Is the 'real' radio button not visible or something? 

 

Oh! I just found this.. From the action menu.. Focus.Focus doesn't work, Neither does SelectionItem.Select... but I noticed that Inspect.exe tells you that "LegacyIsAccesible" fucntions state that it's focusable.. so I tried Action.. LegacyIsAccessable.DoDefaultAction. Can I automate that with MS IUI?

Edited by BatMan22
Added legacy info

Share this post


Link to post
Share on other sites
BatMan22

Also in MSAA mode, default action works.

Share this post


Link to post
Share on other sites
BatMan22

bump.. anyone?

Share this post


Link to post
Share on other sites
junkew

Not sure what you tried so in order of preference on finding solution
 

First of all the spy tools give some different output depending on how they travers the hierarchy. MS Access sucks as bigger elements are in front of smaller elements frequently and as such elementfrompoint will not allways return the actual element you mean as a human. Click gets dispatched thru the bigger element to the lower laying child element so from enduser perspective no issue but for automation hard to tackle so thats why you have treewalkers that can do a deep scan of elements.

  1. Simplespy and inspect tells you
    UIA_IsSelectionItemPatternAvailable:= <True>
    So in that case its not likely to use invoke pattern so indeed as you suggest try:  SelectionItem.Select  pattern (not sure what your coding has been for this)
  2.  And inspect tells you
    HasKeyboardFocus:   true
    IsKeyboardFocusable:    true
    IsEnabled:  true
    SelectionItem.IsSelected:   false
    So normally it should be possible to use UIA and determine what the selection state is
  3.  Thru IAccessible (there are some examples made by @LarsJ)
    ; LegacyIAccessible object
    Local $pLegacyIAccessible, $oLegacyIAccessible
    $oUIAutomationElement.GetCurrentPattern( $UIA_LegacyIAccessiblePatternId, $pLegacyIAccessible )
    $oLegacyIAccessible = ObjCreateInterface( $pLegacyIAccessible, $sIID_IUIAutomationLegacyIAccessiblePattern, $dtagIUIAutomationLegacyIAccessiblePattern )
    If Not IsObj( $oLegacyIAccessible ) Then Return ConsoleWrite( "$oLegacyIAccessible ERR" & @CRLF )
    ConsoleWrite( "$oLegacyIAccessible OK" & @CRLF )
    
    ; IAccessible object
    Local $pIAccessible, $oIAccessible
    $oLegacyIAccessible.GetIAccessible( $pIAccessible )
    $oIAccessible = ObjCreateInterface( $pIAccessible, $sIID_IAccessible, $dtagIAccessible )
    If Not IsObj( $oIAccessible ) Then Return ConsoleWrite( "$oIAccessible ERR" & @CRLF )
    ConsoleWrite( "$oIAccessible OK" & @CRLF )

     

  4. As you can determine what the state is and you know the rectangle you can do a mousemove/click action from the autoit functions
     

    mousemove
    click x,y

     

  5. Probably not needed is to do a pixelgetcolor at the location you determine and then do step 4

 

Quote

Thanks guys, I really hate this MS IUI Automation stuff

ok but whats a better alternative ;-)  Its really powerfull build into the OS and besides AutoIt I frequently use it on "closed" company PC's that only have Visual Basic for Applications available (so set reference to UIAutomationCore.Dll). My advice is if you struggle in AutoIt as debugging/stepping thru coding is quite hard to use VBA IDE to see what works and what not on the element you need to deal with (so try first in VBA and then make the end solution in AutoIt)

 

  • Like 1

Share this post


Link to post
Share on other sites
Earthshine

Your alternate is C++ and/or C# And just go after the automation libraries yourself and use Inspect to find everything you need


My resources are limited. You must ask the right questions

 

Share this post


Link to post
Share on other sites
BatMan22

@junkew I appreciate your help.. I'll try and go through the stuff you said and see if I can figure it out... Also please understand that when I said "Thanks guys, I really hate this MS IUI Automation stuff " that I wasn't insulting your work at all, I genuinely appreciate the work you have done. I meant that I hate the MS IUI because it's so tough to understand. I look at the code that I'm using and I just genuinely don't understand it, I look at autoit code and it is all so damn clear, windows/directories/everything in autoit is almost common sense after you see it used for the first time. The MS iui stuff... I look at it and I genuinely understand nothing at all. I'm considering hiring a guy from upwork to literally automate a few button clicks for me to get this stupid project done. 

Share this post


Link to post
Share on other sites
BatMan22

Hey guys.. finally got it working! From 23s to 1s for activation :)

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
#include "UIAWrappers.au3"
Local $oButton
Local $program = "McCampbell Omega_Me - [ODBC;DRIVER=SQL Server Native Client 10.0;SERVER=tcp:MAI-SQL\MAI_BACKEND;UID=huan;PWD=;Trusted_Connection=Yes;APP=Microsoft Offi]"
#forceref $oButton
#AutoIt3Wrapper_UseX64=Y ;Should be used for stuff like tagpoint having right struct etc. when running on a 64 bits os

Local $omega = _UIA_getFirstObjectOfElement($UIA_oDesktop, $program, $treescope_children)
$oButton = _UIA_getFirstObjectOfElement($omega, "name:=Analytical", $treescope_subtree)
local $oLegacyP=_UIA_getPattern($oButton,$UIA_LegacyIAccessiblePatternId)
$oLegacyP.dodefaultaction()

 

Edited by BatMan22
Removing Comments that were wrong.
  • Like 2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×