tags:

views:

719

answers:

4

Hi Gurus,

This is with reference to the below question

http://stackoverflow.com/questions/924289/how-to-read-output-and-give-input-to-a-program-from-c-program

I found the answer to the above question very usefull. In the same way can I do it for windows applications. Like can I give input into a windows form(like .net, C# applications) application's text box programmatically? Can I do the action of button click from a program. If so can I do it from a C program (with Tiny C compiler or any other on windows platform)?. If not how and in which language can I do it? Please dont take it as a silly question. Any example codes will be very much usefull. Thanks in advance. edit: can I do the same with web applications and web pages?

+2  A: 
fretje
Isn't it mad that applications can be interfered with like that? Is there any sort of process-level protection in Windows, or can every process see every process?
dreamlax
Not that I know of no... That's e.g. how Revelation (http://www.snadboy.com/) works to reveal passwords in password fields... Although there are other measures in place to prevent that now...
fretje
It's not mad at all to allow windows to be controlled remotely. Without an API to allow this you couldn't have things like debuggers, task managers, automated testing tools, and innumerably useful other applications. Heck, without the ability to send windows messages to any window you couldn't even shut down unresponsive apps.
Ron Warholic
@BlodBath, you obviously do not know what I mean. If the application was unresponsive, why would it respond to a message that you sent it? Killing a process is done entirely independently from messaging. Also, debugging is done by spawning a sub-process, or by attaching to a process, not by messaging windows. Not all processes have window procedures yet these can still be debugged and killed.
dreamlax
+1  A: 

As fretje pointed out, you can certainly do it.

It's much more challenging for windows apps. Because individual controls also count as windows, the total window count will be much higher than you might expect; and finding the specific control you want to send input to can take a lot of work.

But you can programmatically move, resize, check, fill, maximize or otherwise affect an app's windows, once you know which one is your target.

I wrote code to do the discovery process a few years ago. It found all the windows of a target app, then using their size & location data, produced a translucent overlay of each child window, along with the handle number. So I could visually tell which control went with which handle.

EDIT: Added some code. This is some basic C# interop code that will let you make easy calls into user32.dll, which holds the fns to which fretje referred. This just gives you the basic calls for discovery and manipulation; you'll still have to do the hard work of enumerating and examining what you find. If you can find a 3rd-party package that does the job for you, save yourself the trouble; I only did it as a learning experience, and it was pretty laborious.

using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;

namespace WinAPI
{
 [Flags] public enum WindowStyleFlags : uint
 {
  WS_OVERLAPPED      = 0x00000000,
  WS_POPUP           = 0x80000000,
  // more...
 }

 [Flags] public enum ExtendedWindowStyleFlags: int
 {
  WS_EX_DLGMODALFRAME    = 0x00000001,
  WS_EX_NOPARENTNOTIFY   = 0x00000004,
  // more...
 }

 [StructLayout(LayoutKind.Sequential, Pack = 4)]
 public struct RECT
 {
  public int Left;
  public int Top;
  public int Right;
  public int Bottom;
 }

 [StructLayout(LayoutKind.Sequential, Pack = 4)]
 public struct POINT
 {
  public int Left;
  public int Top;
 }

 [StructLayout(LayoutKind.Sequential, Pack = 4)]
 public struct FLASHWINFO
 {
  public int cbSize;
  public IntPtr hwnd;
  public int dwFlags;
  public int uCount;
  public int dwTimeout;
 }

 public delegate int EnumWindowsCallback( IntPtr hwnd, int lParam );

 public class User32Dll
 {
  // Constants & fields
  public const int FLASHW_STOP = 0;
  public const int FLASHW_CAPTION = 0x00000001;
  // lots, lots more, web search for them...

  // Self-added, don't know if correct
  [DllImport("user32")]
  public extern static bool CloseWindow( IntPtr hWnd );
  [DllImport("user32")]
  public extern static IntPtr GetDesktopWindow();
  [DllImport("user32")]
  public extern static IntPtr GetForegroundWindow();
  [DllImport("user32")]
  public extern static int GetDlgItem( IntPtr hWnd, int wMsg );
  [DllImport("user32")]
  public extern static int GetListBoxInfo( IntPtr hWnd );
  [DllImport("user32")]
  public extern static bool MoveWindow( IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint );
  [DllImport( "user32" )]
  public static extern int SendMessage( IntPtr hWnd, int uMsg, IntPtr wParam, StringBuilder lpString );
  [DllImport("user32")]
  public static extern bool SetWindowPos( IntPtr hWnd, IntPtr afterWnd, int X, int Y, int cX, int cY, uint uFlags );

  [DllImport("user32")]
  public extern static int BringWindowToTop (IntPtr hWnd);
  [DllImport("user32")]
  public extern static int EnumWindows( EnumWindowsCallback lpEnumFunc, int lParam );
  [DllImport("user32")]
  public extern static int EnumChildWindows( IntPtr hWndParent, EnumWindowsCallback lpEnumFunc, int lParam );
  [DllImport( "user32.dll" )]
  public static extern int EnumThreadWindows( IntPtr hWndParent, EnumWindowsCallback callback, int lParam );
  [DllImport( "user32.dll" )]
  public static extern int FindWindow( string lpClassName, string WindowName );
  [DllImport( "user32.dll" )]
  public static extern int FindWindowEx( IntPtr hWnd, IntPtr hWnd2, string lpsz, string lpsz2 );
  [DllImport("user32")]
  public extern static int FlashWindow ( IntPtr hWnd, ref FLASHWINFO pwfi);
  [DllImport("user32")]
  public extern static IntPtr GetAncestor( IntPtr hWnd, uint gaFlags );
  [DllImport("user32", CharSet = CharSet.Auto)]
  public extern static int GetClassName ( IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
  [DllImport("user32", CharSet = CharSet.Auto)]
  public extern static uint GetWindowLong( IntPtr hwnd, int nIndex);
  [DllImport("user32")]
  public extern static int GetClientRect( IntPtr hWnd, ref RECT lpRect);
  [DllImport("user32")]
  public extern static int GetWindowRect( IntPtr hWnd, ref RECT lpRect);
  [DllImport("user32", CharSet = CharSet.Auto)]
  public extern static int GetWindowText( IntPtr hWnd, StringBuilder lpString, int cch );
  [DllImport("user32", CharSet = CharSet.Auto)]
  public extern static int GetWindowTextLength( IntPtr hWnd );
  [DllImport("user32")]
  public extern static int IsIconic(IntPtr hWnd);
  [DllImport("user32")]
  public extern static int IsWindowVisible( IntPtr hWnd );
  [DllImport("user32")]
  public extern static int IsZoomed(IntPtr hwnd);
  [DllImport("user32", CharSet = CharSet.Auto)]
  public extern static int PostMessage( IntPtr hWnd, int wMsg, int wParam, int lParam);
  [DllImport( "user32.dll" )]
  public static extern int RealGetWindowClass( IntPtr hWnd, StringBuilder pszType, uint bufferSize );
  [DllImport("user32")]
  public extern static int ScreenToClient( IntPtr hWnd, ref POINT lpPoint);
  [DllImport("user32", CharSet = CharSet.Auto)]
  public extern static int SendMessage( IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
  [DllImport("user32.dll")]
  public extern static int SetForegroundWindow (IntPtr hWnd);
  [DllImport( "user32.dll" )]
  public static extern int SetWindowText( IntPtr hWnd, string lpsz );
 }
}
John Pirie
Thank you very much for your warm hearted reply. Any example codes please..
Enjoy coding
+2  A: 

If your application mainly just needs to manipulate other windows, by sending keystrokes etc. i would use AutoIt. It's mainly function is exactly this job and it does it very well.

So maybe you should give it a try, cause not every problem is a nail and can be solved with a hammer (C#) ;-))

Oliver
A: 

Check out the following SO question. There are numerous vendor and open-source tools to do this for you, so you don't have to code at to the Win32 API.

automated-testing-of-windows-forms

Tom E