Automating applications using messages |
Written by Harry Fairhead | ||||||
Thursday, 16 July 2009 | ||||||
Page 3 of 5
Finding a dialogOur next problem is to find the window handle of the dialog box we have just opened. It’s easy to find a child windows of a given window, there’s an API call for it, but a dialog box is harder because it isn’t a child window – it’s an “owned top level” window. The only way that I know of finding a dialog box is to write a function that examines each top level window in turn until we find one with the right characteristics. To scan through all of the top level windows we can use EnumWindows and its associated callback function, the definitions of which need to be added to the start of the program: [DllImport("user32.dll")] EnumWindows will call the callback function with the window handle in hWnd for each top level window. The final parameter lParam is passed to the callback function and can be used to get a result back. The enumeration can be stopped when you have found the window you are looking for by getting the callback to return false. The best way to use this API call is to create a new method that searches for a dialog box with a specified title and with the specified window as its Owner: public IntPtr getDialog( A timeout in milliseconds is included because we have to deal with the possibility that the dialog window we are looking for hasn’t been created yet and we might need to try to find it more than once. The first thing we have to do is create the callback function and this is most easily done using the “anonymous method” facility introduced in .NET 2.0. This allows us to define a delegate without having to first create a separate named function. You can think of this as a direct or “in-line” definition of the delegate object: EnumWindowsProc enumProc = delegate( We need to test that the windows title matches the one we are looking for: int length = GetWindowTextLength(handle); If it does we next check that it is a dialog box by retrieving its class name, which for most dialogs is #32770. You can find the class name of any window using Spy++ or Winspector. int max = 100; If the class name proves that we have a dialog box the final test is to check that its owner is the specified window: IntPtr Parent = GetParent(handle); Notice that the GetParent API call returns either the owner or parent window depending on the type of window. This completes the callback function and all that now remains is to use EnumWindows to make use of it: DateTime end = Notice the use of Sleep to give other threads time to open dialogs and complete other processing. To make all of this work we need the following API function definitions: [DllImport("user32.dll", <ASIN:078214134X> <ASIN:1572316950> |
||||||
Last Updated ( Sunday, 19 July 2009 ) |