UI Automation monitoring - c#

I'm trying to monitor an external WPF application(no source-code) from a local app, and see when a button is clicked in c#.
So far i've been exploring UI Automation's options, and i saw that it works similar if not same to the Inspect.exe tool.
The problem i have is, the WPF form i need to monitor does not contain the button i need directly, as a sub-control. Instead, first you need to log in, then click a few buttons and then finally a new window opens, and it contains the button i need to check.
So my question is, is there a way this to be monitored with the UI Automation? I know i can trigger an event when the main form starts a new process, and the button is clicked, but how do i handle all the steps in between?
(Or in other words how can i trigger an event when the final window containing the button i need to check is actually open)

Related

Detect whenever click event is fired in fully transparent window

I have a transparent controls and window where I can click through as it would not even exist. My question is: Is it possible to detect whenever click event is fired no matter where on the screen I click, while the wpf applicaton is running?
The reason why I need this is because I'm making an agent that will collect all information about actions made by user. Any suggestions, hacks, tricks will do.
You would need to create an event hook so that you could snoop all system wide messages before they are dispatched to the target window. Check the following link for more information...

Windows Phone 8 show MessageBox when app closing (deactivated)

I am trying to show user MessageBox just before app is closed (or deactivated). So I added this to both events:
if (AppSettings.ShouldShowAlertTransfer)
{
MessageBox.Show("...");
}
But the MessageBox is not shown. I am adding this because then I am adding background transfers and I must inform user that I created some background trasnfers. I know I can add this code to OnKeyBackPressed in every page. But it's working just for back key and not middle button. And it wouldn't be nice to have same code copied in every page.
So is it possible to show this MessageBox in App.xaml.cs? How can I do that? If it's not how can I show MessageBox when user pressed middle button?
I was intrigued by your question so I opened up a solution and attempted every single override available and every single page event. I also tried all of the methods in the App.xaml.cs.
I can unequivocally say, based on the MSDN documentation and my own personal testing that there is no way to detect the home button press or search button press. Furthermore there is no way to display a message box to temporarily stop one of these actions.
This testing was done on Windows Phone 8 with the WVGA 512MB Emulator in Visual Studio 2013 Ultimate.

Preventing user to click on a particular button when an action is being performed

Here's the scenario:
Platform: Windows
IDE: Microsoft Visual Studio 2008
Language: C#
.NET framework: 3.5
My application contains 2 buttons - "Load Data" and "Stop Loading Data" and a multi-line textbox. Upon clicking "Load Data" button some data starts getting loaded in the textbox. To prevent the user clicking on the "Load Data" button multiple times, I have disabled that button once it is clicked. When the entire data gets loaded in the textbox then the "Load Data" button gets activated again. On the other hand on clicking "Stop Loading Data" button the loading of data is stopped (if user wishes to stop it before loading the entire content).
As stated earlier, to prevent the user clicking on the "Load Data" button multiple times, I have disabled that button with the intention that user can only click on "Stop Loading Data" button or else wait for the entire data to be loaded in the textbox. I implemented this. At first glance it seemed to work well. But while testing I found that even though the "Load Data" button is disabled, if the user clicks on that button, although nothing happens at that instant but as soon as the entire data gets loaded and the button becomes enabled again, that click made during the disabled state is found to be executed. As if the program was recording the keystrokes and mouse clicks and waiting for the button to become active again. But there are no such keystrokes or mouse-clicks recording facility in my program. What is causing such an activity? How can I prevent such behavior?
Thanks.
One option would be to work with a reentrancy sentinel:
You could define an int field (initialize with 0) and update it via Interlocked.Increment on entering the method and only proceed if it is 1. At the end just do a Interlocked.Decrement.
To make it visible for the user you can disable the button at the beginning of execution and enable it when the execution is finished...
BTW: long-running tasks should be done async (via a separate thread for example)...
if you make your call a synchronous one, it will lock up the entire page until loading finishes.
Otherwise you'd be just doing the method you've already tried, i'd like to see your code for the disabled state, because something tells me you just made it appear to be disabled, and it was still a functional button
Check out this post:
http://www.codeguru.com/forum/showthread.php?t=480279
My first thought was removing the event handler and rebinding it at the end of the click event. This thread suggests using a BackgroundWorker and making it async.
I bet that you can't even move the form until data is loaded, and you also can't stop loading data. The problem is that the whole form freezes until loading is done. You must move the loading part in separate thread.
Well, another silution again:
On begin load simply hide a load button and in place of it (say) show a progress bar. On finish of loading or on stop loading click make load button visible again. In this case you avoid "chain clicks" management you complains about.
Or manage one button. First it is load, on click, instead, becomes stop load. Solution like this you would find often in mobile environment, considering the limited screen space. But I think it can be applied to desktop with great sucess too. Why not?

invoke back button press from code behind in WP7

Is it possible to invoke a back button press from code?
I want to simulate a physical back button press from the code behind for a page.
NavigationService.GoBack() will do just that.
You can't simulate a physical back button press. What I mean is you won't be able to navigate back from the first page, i.e. exit the application. Currently the only way for a WP7 Silverlight application to exit is to throw an exception. That said, if you just want to navigate back to another page in your app NavigationService.GoBack() will do the trick as keyboardP said.
By the way, why do you need to simulate a back button press? If you want to exit the app here's a nice article by Peter Torr explaining the various ways a WP7 app can exit. He also analyses scenarios that need exit functionality and talks about what can be done instead. In general, if you have some page with an ok/cancel buttons and you want the cancel to go back or exit, you can just remove it and let the user press the back button.

Buffer button changing forms

this is my first post. I have a huge problem which make me headaches. I have an app uses WinForms, a TTS (Text-To-Speech) voice and custom-buttons with states.
In my 1st form -main- when I click a button, the app opens a 2nd form above the 1st. Ok.
When I close the 2nd form trough a button, I tell the TTS say something and the form closed itself, viewing again the 1st form. Ok.
The problem starts when I click two times in the button on the 2nd form: the TTS says something, the button closes and the 'second click' is still in the click buffer (or somewhere) and it makes click in the 1st form (which appears 4 seconds later when I hit the button for the first time).
I am using the voice in a Sync mode; if I use the voice in an Async mode, the application ends wit h a nice exception.
If I click three or four times in the 2nd form, the other clicks still remains in buffer and clicks in the 1st form all the times.
I tried to (1) delete the DoubleClick event, (2) delete the event associated to the button and (3) hide the button which is clicked automatically when I return from the 2nd form, (4) hide the 1st form before create the 2nd and restore when it finishes.
Suggestions?
Thanks!
PD: I'm sorry by my English :S
PD2: I've uploaded a very simple example of what happens.
EDIT 2
Having looked at the code I understand the issue you're having now. The reason button clicks are being stacked up is when you call Speak within TTS the application locks up while it waits for the function to finish. Any presses in that time are stacked up until the application is free again to process them, you then close the form instanly before the messages are handled and these are then dealt with in the first form.
I've come up with a few solutions which could work for you:
Use only the SpeakAsync command within your TTS class and introduce a Waiting system where you wait for the speech to finish before doing anything. This will free the application and won't cause the mouse click events to stack up.
After you trigger a Speak command you could access the Windows message list and clear all the mouse click events that occurred before the process finished. Unfortunately, I'm not sure how you'd implement this as I've not done this before. I think you need to overwrite the WndProc function but again I'm not sure. This might be also be a bit dangerous as you may end up clearing a perfectly valid or important system message by mistake. Sorry can't provide any more help on that one.
Implement a background worker in your second form which will process the Speak commands seperately on a background thread. This again will free the application so the mouse click events won't stack up. I've modified your sample project and zipped it up for you to take a look. If you want I can explain further but essentially it does the following:
Form 2 loads and creates a background worker.
Worker_DoWork and Worker_WorkComplete delegates are created and set in the background worker. These functions are called when the worker is started and after the worker has finished.
Form 2 triggers the background worker to start. The background worker then sits in an infinite loop waiting for commands to process.
When the "Hello" button is pressed this sets a SayHello boolean to true, the worker spots this, carrys out the appropriate speak function and then resets the boolean ready for the next press.
When the "Close" button is pressed a CancelASync request is called in the background worker.
CancelASync interupts the BackgroundWorker's main loop (CancellationPending becomes true). The appropriate speak command is sent and the cancel property of the DoWorkEventArgs is set to true before breaking out of the BackgroundWorker's main loop.
Breaking out of the main loop causes Worker_WorkComplete to be called where the form is then closed.
I hope you can follow the example (linked below) and I've explained it well enough here. I prefer this solution as its quite extendable, you can add more conditions within the main worker thread for example.
Like I said, if you have any questions please ask and I'll try help as much as possible.
Hope this helps.
Example Link: http://www.mediafire.com/?2mf1yahto50ljs6
Use a boolean flag to track whether the form is in a state that accepts the click.
IE - when you open the 2nd form, 'boolean canPlaySound = true;' When the button click event fires, only play the sound if canPlaySound is true (and set it to false before playing the sound).
The next click will be ignored because canPlaySound = false. You won't play the sound.

Categories