2011-09-15 58 views
2

是否有任何方法從另一個應用程序寫入/讀取應用程序的文本框中的文本? 我能做的是,我可以使用win32 API獲取該文本框的句柄。但不知道如何在文本框中編寫文本。 我的代碼如下。 請參閱WriteTextUsingHandle方法從另一個應用程序的應用程序的文本框中寫入/讀取文本

public class WriteText 
{   
    public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

    [DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle); 

    [DllImport("user32")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i); 

    [DllImport("user32.dll")] 
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, long wParam, [MarshalAs(UnmanagedType.LPStr)] StringBuilder lParam); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    public static extern IntPtr GetParent(IntPtr hWnd); 

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); 

    public static void WriteTextUsingHandle(String text) 
    { 
     Process reqProcess = null; 
     foreach (Process aProcess in Process.GetProcessesByName("any app")) 
     { 
      reqProcess = aProcess; 
      break; 
     } 

     if (reqProcess == null) return; 

     HanldesInfo dialogClasses = WriteText.GetChildWindows(reqProcess.MainWindowHandle, true, "#32770", String.Empty); 
     HanldesInfo editBoxHandle = WriteText.GetChildWindows(dialogClasses.ChildHandles[1], true, "Edit", String.Empty); 

     //now i want to write/Read the text using editBoxHandle. But how ? 
    } 

    /// <summary> 
    /// Returns a list of child windows 
    /// </summary> 
    /// <param name="parent">Parent of the windows to return</param> 
    /// <returns>List of child windows</returns> 
    private static HanldesInfo GetChildWindows(IntPtr parent, bool onlyImmediateChilds, String className, String text) 
    { 
     HanldesInfo result = new HanldesInfo(parent, onlyImmediateChilds, className, text); 
     GCHandle listHandle = GCHandle.Alloc(result); 
     try 
     { 
      EnumChildWindows(parent, WriteText.EnumWindowAllChildCallBackMethod, GCHandle.ToIntPtr(listHandle)); 
     } 
     finally 
     { 
      if (listHandle.IsAllocated) { listHandle.Free(); } 
     } 
     return result; 
    } 

    /// <summary> 
    /// Callback method to be used when enumerating windows. 
    /// </summary> 
    /// <param name="handle">Handle of the next window</param> 
    /// <param name="pointer">Pointer to a GCHandle that holds a reference to the list to fill</param> 
    /// <returns>True to continue the enumeration, false to fail</returns> 
    private static bool EnumWindowAllChildCallBackMethod(IntPtr handle, IntPtr pointer) 
    { 
     GCHandle gch = GCHandle.FromIntPtr(pointer); 
     HanldesInfo list = gch.Target as HanldesInfo; 

     if (list == null) { throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>"); } 

     if (list.OnlyImmediateChilds && list.ParentHandle != WriteText.GetParent(handle)) return true; 

     if (list.ClassName.Length > 0) 
     { 
      StringBuilder className = new StringBuilder(100); 
      WriteText.GetClassName(handle, className, className.Capacity); 

      if (String.Compare(className.ToString().Trim(), list.ClassName, true) != 0) return true; 
     } 

     list.ChildHandles.Add(handle); 

     // if you want to cancel the operation, then return a null here 
     return true; 
    } 
} 

public class HanldesInfo 
{ 
    public IntPtr ParentHandle { get; private set; } 
    public bool OnlyImmediateChilds { get; private set; } 
    public String ClassName { get; private set; } 
    public String Text { get; private set; } 
    public List<IntPtr> ChildHandles { get; private set; } 

    internal HanldesInfo(IntPtr parentHandle, bool onlyImmediateChilds) : this(parentHandle, onlyImmediateChilds, String.Empty, String.Empty) { } 
    internal HanldesInfo(IntPtr parentHandle, bool onlyImmediateChilds, String className) : this(parentHandle, onlyImmediateChilds, String.Empty, String.Empty) { } 
    internal HanldesInfo(IntPtr parentHandle, bool onlyImmediateChilds, String className, String text) 
    { 
     this.ParentHandle = parentHandle; 
     this.OnlyImmediateChilds = onlyImmediateChilds; 
     this.ClassName = (className ?? String.Empty).Trim(); 
     this.Text = (text ?? String.Empty).Trim(); 
     this.ChildHandles = new List<IntPtr>(); 
    } 
} 
+1

你想SendMessage/wm_gettext/wm_settext - 例如,如果你搜索'[c#] wm_settext' –

回答

2

使用GetWindowText方法讀取文本並SetWindowText設置文本。然而,如果你同時控制兩個應用程序,你應該考慮使用老派命名管道,共享內存或最新的WCF來實現某種進程間通信。

1

你應該集中在進程間通信,以實現自己的目標。在同一臺機器上進行兩個進程我建議您創建一個named pipe.

+0

實際上其他應用程序是第三方應用程序,所以我不能使用命名管道。 – Waqar

相關問題