SanCon Posted March 10, 2015 Share Posted March 10, 2015 Hello everyone, I support an application which has an Internet Explorer_Server instance in a pane of the application. There are a few buttons we would like to disable in the application, as it causes many an issue whenever users click on the buttons. The buttons which are part of the application/program are easy to disable (there was a "Print" button which we have disabled this way, thus forcing the user to use the "File->Print" option as that is the preferred method) but those which are part of the Internet Explorer_Server pane were inaccessible. Enter Junkew's IUIAutomation UDF. I've been trying to follow the threads regarding IUIAutomation, and while I've been able to highlight the button (which in itself is a great accomplishment in my view) I can't find a way to disable said button. Is this even possible? If this were a regular button, I could get the handle of the control and manipulate it that way. I understand that the "automation" part doesn't include disabling items (who does that, right?) but I was wondering if someone savvier than myself knew of a method to do this. Below is the code provided by simple spy (which I commented out to use the shorter version of the program at the end) Some information has been removed, but it was mostly to protect innocent servers. :-) Any guidance/assistance would be greatly appreciated. expandcollapse popup#include "UIAWrappers.au3" AutoItSetOption("MustDeclareVars", 1) #cs Local $oP13=_UIA_getObjectByFindAll($UIA_oDesktop, "Title:=[Horizon Ambulatory Care];controltype:=UIA_WindowControlTypeId;class:=WindowsForms10.Window.8.app4", $treescope_children) _UIA_Action($oP13,"setfocus") Local $oP12=_UIA_getObjectByFindAll($oP13, "Title:=Workspace;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.MDICLIENT.app4", $treescope_children) _UIA_Action($oP12,"setfocus") Local $oP11=_UIA_getObjectByFindAll($oP12, "Title:=Horizon Ambulatory Care;controltype:=UIA_WindowControlTypeId;class:=WindowsForms10.Window.8.app4", $treescope_children) _UIA_Action($oP11,"setfocus") Local $oP10=_UIA_getObjectByFindAll($oP11, "Title:=;controltype:=UIA_PaneControlTypeId;class:=Shell Embedding", $treescope_children) _UIA_Action($oP10,"setfocus") Local $oP9=_UIA_getObjectByFindAll($oP10, "Title:=;controltype:=UIA_PaneControlTypeId;class:=Shell DocObject View", $treescope_children) _UIA_Action($oP9,"setfocus") Local $oP8=_UIA_getObjectByFindAll($oP9, "Title:=info.sys:12200/hac/clinical/frame/showMainFrame;controltype:=UIA_PaneControlTypeId;class:=Internet Explorer_Server", $treescope_children) _UIA_Action($oP8,"setfocus") Local $oP7=_UIA_getObjectByFindAll($oP8, "Title:=HAC;controltype:=UIA_PaneControlTypeId;class:=", $treescope_children) Local $oP6=_UIA_getObjectByFindAll($oP7, "Title:=info.sys:12200/hac/clinical/frame/showRootFrame;controltype:=UIA_CustomControlTypeId;class:=", $treescope_children) Local $oP5=_UIA_getObjectByFindAll($oP6, "Title:=Root Frame Page;controltype:=UIA_PaneControlTypeId;class:=", $treescope_children) Local $oP4=_UIA_getObjectByFindAll($oP5, "Title:=info.sys:12200/hac/clinical/workFlow/worklist/tabBarHandler/showFrameSet?activeTab=0;controltype:=UIA_CustomControlTypeId;class:=", $treescope_children) Local $oP3=_UIA_getObjectByFindAll($oP4, "Title:=;controltype:=UIA_PaneControlTypeId;class:=", $treescope_children) Local $oP2=_UIA_getObjectByFindAll($oP3, "Title:=info.sys:12200/hac/clinical/workFlow/worklist/showWorklist;controltype:=UIA_CustomControlTypeId;class:=", $treescope_children) Local $oP1=_UIA_getObjectByFindAll($oP2, "Title:=Worklist;controltype:=UIA_PaneControlTypeId;class:=", $treescope_children) Local $oP0=_UIA_getObjectByFindAll($oP1, "Title:=;controltype:=UIA_CustomControlTypeId;class:=", $treescope_children) ;~ First find the object in the parent before you can do something ;~$oUIElement=_UIA_getObjectByFindAll("Delete.mainwindow", "title:=Delete;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree) Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=Delete;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree) ConsoleWrite("Value: " & _UIA_action($oUIElement,"right") & @CRLF) #ce _UIA_SetVAR("HACWindow","Title:=[Horizon Ambulatory Care];controltype:=UIA_WindowControlTypeId;class:=WindowsForms10.Window.8.app4") _UIA_SetVAR("TaskListPane","Title:=Worklist;controltype:=UIA_PaneControlTypeId;class:=") _UIA_SetVAR("DeleteButton","title:=Delete;ControlType:=UIA_ButtonControlTypeId") ConsoleWrite("HAC? " & _UIA_Action("HACWindow","setfocus") & @CRLF) ConsoleWrite("Pane? " & _UIA_Action("TaskListPane","setfocus") & @CRLF) ConsoleWrite("Button? " & _UIA_Action("DeleteButton","highlight") & @CRLF) Link to comment Share on other sites More sharing options...
SanCon Posted November 25, 2015 Author Share Posted November 25, 2015 Some views, but no replies. I'm guessing it's not possible to do this. Still...@junkew: Found an MSDN article about Registering Custom Properties, Events, and Control Patterns, but not sure how to implement this approach in AutoIt. I may not be understanding this correctly, but would this allow one to add a custom property to a button which UIAutomation is able to click/highlight/etc? In the snippet above, your libraries can highlight and click on the button. But I've found no way to disable it. So, could a custom property be added to disable any button seen by the Automation library?Thank you all for your time! Link to comment Share on other sites More sharing options...
LarsJ Posted November 25, 2015 Share Posted November 25, 2015 A custom property must be implemented by the provider of the application before it can be used by the client. A client cannot create a custom property. This method does not seem to be a solution.If you can disable the button manually, you can probably automate the process too.A button is usually supplied with an enabled property ($UIA_IsEnabledPropertyId). You can use the Spy tool or Inspect.exe to figure out, if you can set the value ($UIA_ValuePatternId) of this property. SanCon 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
SanCon Posted November 25, 2015 Author Share Posted November 25, 2015 (edited) @LarsJ,Thank you for the reply. Upon further examination of the output of simplespy, I see the following:UIA_IsValuePatternAvailable:= <False> UIA_IsWindowPatternAvailable:= <False> UIA_ValueIsReadOnly:= <True>Edited entry: could the Legacy IAccessiblePattern part be used for my purpose?UIA_IsLegacyIAccessiblePatternAvailable:= <True> UIA_LegacyIAccessibleChildId:= <0> UIA_LegacyIAccessibleName:= <Delete> UIA_LegacyIAccessibleRole:= <43> UIA_LegacyIAccessibleState:= <1048576> UIA_LegacyIAccessibleDefaultAction:= <Press>Your help is greatly appreciated! Edited November 25, 2015 by SanCon Link to comment Share on other sites More sharing options...
LarsJ Posted November 25, 2015 Share Posted November 25, 2015 I don't think it looks too good. The role value = 43 = 0x2b = $ROLE_SYSTEM_PUSHBUTTON and the state value = 1048576 = 0x100000 = $STATE_SYSTEM_FOCUSABLE does not seem to be of any help. I'm afraid it's not possible to disable the button. At least not with usual automation code.Maybe it's possible to catch a mouse click on the button with some kind of hook procedure and simply cancel the click event. You probably need a DLL file to do that. This excludes AutoIt. Another problem with such a solution is, that the user can't see that the mouse click is cancelled. The user will probably click a lot of times until he gives up. Unless you display a msgbox or something for the user. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
SanCon Posted November 25, 2015 Author Share Posted November 25, 2015 Thank you again, @LarsJ. With my limited understanding, I thought as much, but I know that some of the members in the AutoIt community are quite resourceful. I thought about monitoring mouse activity, but now that you mention that it may not be possible to do it within AutoIt, I may have to give up on this endeavor.Thank you again for your help! Link to comment Share on other sites More sharing options...
LarsJ Posted November 26, 2015 Share Posted November 26, 2015 A systemwide low level mouse hook (WH_MOUSE_LL) where you (more or less) hook into the mouse driver can be implemented in pure AutoIt code. You'll find examples if you search.A less intrusive method (WH_GETMESSAGE, WH_MSGFILTER, WH_SYSMSGFILTER) where you only hook into the processes of the specific application cannot be implemented entirely in AutoIt code. In this example you can see which part of the code you can implement in AutoIt code and which part must be implemented in a DLL. It was this way I had in mind.If such a hook procedure is implemented in pure AutoIt code, you can only hook into a GUI which is running in the same process (or thread) as the hook procedure. SanCon 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
junkew Posted November 26, 2015 Share Posted November 26, 2015 WMGetObject should be possible to get the native ie object. Then you can reach dom object and us ie.au3 stuff on the object retrieved. If your application has an adressbar you can manipulate thru javascript in addressbarhttps://www.autoitscript.com/forum/topic/99533-explain-this-function-to-me/http://www.programmershare.com/2523017/ SanCon 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now