Modal Dialogs and UI automation
Hi,
I am playing around with WPF and Automation trying to do the following.
Application A: Display a WPF window with a Button. The button has a handler - when clicked you get a message box.
Application B: Automation Controller (unit test). The code starts an in instance of A, and programatically (AutomationElement) pushes the button, which launches the message box. So far all of this works.
When I use the UI Spy program, I notice that when I do things manually, the message box is a child of the main window in the visual tree. When I run things through the automation controller, the message box seems to be a sibling of A in terms of Window hierarchy (and no longer modal!). This sort of makes sense, but the documentation (Invoke) says that a modal dialog will stop everything. Is the behaviour I am seeing correct?
I would like Application B not only to launch the 'modal' dialog, but also to test (get) that both Window title and message are correct; then I would like to programmatically push the OK button to make the message box disappear -- is this is possible?
Friedrich Brunzema
Hi Friedrich,
The behavior you are seeing is correct.
The InvokePattern.Invoke() documentation you are referring to should state that the Invoke method 'does' return without blocking. The note associated with the remark states the outcome if the call actually did block.
I ran a test with UI Spy based on the description of your scenario. I started a WPF application with a button that, when invoked, would launch a modal message box. I confirmed that the Invoke() method does not block by using UI Spy to call the Invoke() method of the button a number of times. This series of Invoke() calls launched multiple, simultaneous instances of the message box. After refreshing the control view of UI Spy I was then able to invoke the 'OK' button for each of the message boxes, causing the respective message box to disappear.
I hope this answers your question.
Karl
Hi Karl,
When I used UI Spy to "invoke" a button that pops up a modal message box, UI Spy was blocked (or not responding) until I close the modal message box manually.
Is this what you are seeing? How do we prevent blocking?
Any sample code will be appreciated.
Thanks,
FY
The same thing happens in WinXP. Before the code clicks the button which brings up the dialog and stops everything, invoke FindWindow/EnumChildWindows. After the button is clicked it can continue looping until it sees the dialog, checks to make sure it's the right one, and closes it. If you're interested, I have some Excel 2003 VBA/Win XP code which does this. Not very good but it does the job and you can improve on it.
As Karl mentioned, it works without blocking when you use UISpy to click a button that opens a modal dialog on a WPF (XAML) application.When you use UISpy to click a button on a standard Windows Application that is not using WPF, then the UISpy tool is blocked until the message box returns. This seems to be what Farn Yu, is seeing.This seems to limit the usefulness of the automation layer quite a bit. I am still investigating what can be done. Creating a separate thread to call the invoke function does not change this behaviour; it seems that the message pump of the UI Automation Client [caller application] is blocked.
In my automation I am working around the issue by having the scripts actually click on the button instead of using Invoke.
I get the clickable point from the Automation Framework, and then I call Win32 API to move the mouse to the spot, send a click and move the mouse back where it was.
I am not sure this is the right thing to do, but it is working so far.
I used a "window open" eventhandler to get around this issue
Register for window open event
Do invoke operation in a thread
The modal dialog which opens, will be caught by the event handler, do the desired operations
Unregister the event
~JK