2011-09-15 20 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

は、あなたがあなたの目標を達成するためのプロセス間通信に集中する必要があります参照してください。同じマシンで2つのプロセスを作成することをお勧めします。named pipe.

+0

実際には他のアプリケーションはサードパーティアプリケーションなので、名前付きパイプは使用できません。 – Waqar

関連する問題