我整天都在和这件事打架。我仍然无法找到确切的解决方案。帮帮我。
我的目标非常简单。我想得到其他应用程序的文本框中的文本。它可能是gtalk客户端或soap UI屏幕的文本框。
我用谷歌搜索,大多数论坛建议winapi是我必须用来实现这一目标的概念。我从来没有使用过这个概念,也没有得到任何好的例子。请帮助我解决这个问题,并完成这件事。还有其他方法可以达到这个目的吗?
等待你的回复...
答案 0 :(得分:11)
以下是如何通过窗口标题从窗口中获取所有文本的示例。
请参阅评论以获得有关其工作原理的说明。
public class GetWindowTextExample
{
// Example usage.
public static void Main()
{
var allText = GetAllTextFromWindowByTitle("Untitled - Notepad");
Console.WriteLine(allText);
Console.ReadLine();
}
// Delegate we use to call methods when enumerating child windows.
private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, [Out] StringBuilder lParam);
// Callback method used to collect a list of child windows we need to capture text from.
private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer)
{
// Creates a managed GCHandle object from the pointer representing a handle to the list created in GetChildWindows.
var gcHandle = GCHandle.FromIntPtr(pointer);
// Casts the handle back back to a List<IntPtr>
var list = gcHandle.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
// Adds the handle to the list.
list.Add(handle);
return true;
}
// Returns an IEnumerable<IntPtr> containing the handles of all child windows of the parent window.
private static IEnumerable<IntPtr> GetChildWindows(IntPtr parent)
{
// Create list to store child window handles.
var result = new List<IntPtr>();
// Allocate list handle to pass to EnumChildWindows.
var listHandle = GCHandle.Alloc(result);
try
{
// Enumerates though all the child windows of the parent represented by IntPtr parent, executing EnumChildWindowsCallback for each.
EnumChildWindows(parent, EnumChildWindowsCallback, GCHandle.ToIntPtr(listHandle));
}
finally
{
// Free the list handle.
if (listHandle.IsAllocated)
listHandle.Free();
}
// Return the list of child window handles.
return result;
}
// Gets text text from a control by it's handle.
private static string GetText(IntPtr handle)
{
const uint WM_GETTEXTLENGTH = 0x000E;
const uint WM_GETTEXT = 0x000D;
// Gets the text length.
var length = (int)SendMessage(handle, WM_GETTEXTLENGTH, IntPtr.Zero, null);
// Init the string builder to hold the text.
var sb = new StringBuilder(length + 1);
// Writes the text from the handle into the StringBuilder
SendMessage(handle, WM_GETTEXT, (IntPtr)sb.Capacity, sb);
// Return the text as a string.
return sb.ToString();
}
// Wraps everything together. Will accept a window title and return all text in the window that matches that window title.
private static string GetAllTextFromWindowByTitle(string windowTitle)
{
var sb = new StringBuilder();
try
{
// Find the main window's handle by the title.
var windowHWnd = FindWindowByCaption(IntPtr.Zero, windowTitle);
// Loop though the child windows, and execute the EnumChildWindowsCallback method
var childWindows = GetChildWindows(windowHWnd);
// For each child handle, run GetText
foreach (var childWindowText in childWindows.Select(GetText))
{
// Append the text to the string builder.
sb.Append(childWindowText);
}
// Return the windows full text.
return sb.ToString();
}
catch (Exception e)
{
Console.Write(e.Message);
}
return string.Empty;
}
}
答案 1 :(得分:0)
你是对的。您需要使用Windows API。例如:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
但首先,您可能需要从桌面递归地使用FindWindow或FindWindowEx(?),直到窗口中的文本框hieracrchy,以获得正确的窗口句柄。
看起来http://www.pinvoke.net/有一个很好的Win API数据库。
希望有所帮助。
答案 2 :(得分:0)
一种选择是使用UI自动化框架TestStack.White。它基于项目白色,原始文档为here。