views:

150

answers:

2

I am coding up a program for automated testing which randomly clicks an open application window using various User32.dll library calls. My current problem is this, if a click would open a dialog, using Process.WaitForInputIdle() does not wait long enough for that dialog to be detected the next trip around the loop, which means several clicks get cued and if those clicks happen to be on something in the dialog I want to avoid (say an exit button) there is no way of telling that in advance. My question is this. Is there a way of waiting for the process or thread to finish all processing and only be waiting in the message loop again?

I hope that made sense.

Cheers

Ross

EDIT

Failing this, would it be somehow possible to set the process / threads of the target program and my program to both use the same processor and adjust the prioritorys of each so that the target program gets preference?

+1  A: 

WaitForInputIdle will unfortunately return as soon as the app is in a message loop with no input messages waiting.

If you own the code to the dialog, you could have the dialog call SetEvent in its WM_INITDIALOG to signal your automation that it is ready for testing. Alternatively, you could look at using SetWinEventHook on the process and wait for the dialog to actually be created before sending input events to it.

Michael
Thanks for your input, the program I am writing is meant to be a fairly generic monkey tester, not for any specific program. As such it will not know in advance if a dialog will show up as a result of any action. If there is a hook which can detect the process going idle that would be ideal.
Ross
A: 

The way around this it seems is to use the SendMessage API instead of the mouse_event or SendInput API. The reason for this is that SendMessage blocks until it has been processed. Just make sure you always get the handle of the window immediatly under where you want to click (using WindowFromPoint) and convert the mouse coordinates from screen to client coords using ScreenToClient. Pack the coordinates into the lParam parameter by using ((pt.Y << 16) + pt.X). This will block until processed and so any modal dialogs shown will block this call.

Ross
This method seems to have a built in disadvantage in that responses to the messages sent are inconsistent at best. For example trying to use this method with WM_NCLBUTTONDOWN/UP to click on the file menu in notepad causes the menu loop to begin and then end immediatly without actually showing the menu.
Ross