我正在尝试从其他应用程序中提取文本。这个应用程序现在可能是简单的,我只是想让它工作(现在)。
我使用的代码:
IntPtr MytestHandle = new IntPtr(0x00788600);
HandleRef hrefHWndTarget = new HandleRef(null, MytestHandle);
我使用以下方法调用此代码:
0x00788600
其中{{1}}是我正在运行的其中一个应用程序的示例(我100%确定这是主窗口句柄)。
我需要从"其他"中的一个文本框中获取文本。应用程序,但是当我使用我的代码时,它每次都返回一个空字符串
建议?
答案 0 :(得分:1)
我无法看到您的代码有任何错误。我建议检查你的手柄是否正确。
但是,为了获取TextBox
的文本,您必须使用实际控件的句柄。 MainWindowHandle只返回表单标题。
我创建了一个虚拟应用程序" WindowsFormsApplication1"其中包含一些控件,并使用以下代码获取所有文本:
[Flags]
internal enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0,
SMTO_BLOCK = 0x1,
SMTO_ABORTIFHUNG = 0x2,
SMTO_NOTIMEOUTIFNOTHUNG = 0x8,
SMTO_ERRORONEXIT = 0x20
}
// Specific import for WM_GETTEXTLENGTH
[DllImport("user32.dll", EntryPoint = "SendMessageTimeout", CharSet = CharSet.Auto)]
internal static extern int SendMessageTimeout(
IntPtr hwnd,
uint Msg, // Use WM_GETTEXTLENGTH
int wParam,
int lParam,
SendMessageTimeoutFlags flags,
uint uTimeout,
out int lpdwResult);
// Specific import for WM_GETTEXT
[DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern uint SendMessageTimeoutText(
IntPtr hWnd,
uint Msg, // Use WM_GETTEXT
int countOfChars,
StringBuilder text,
SendMessageTimeoutFlags flags,
uint uTImeoutj,
out IntPtr result);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
// callback to enumerate child windows
private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr parameter);
private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer)
{
// this method will be called foreach child window
// create a GCHandle from pointer
var gcHandle = GCHandle.FromIntPtr(pointer);
// cast pointer as list
var list = gcHandle.Target as List<IntPtr>;
if (list == null)
throw new InvalidCastException("Invalid cast of GCHandle as List<IntPtr>");
// Adds the handle to the list.
list.Add(handle);
return true;
}
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 the children
EnumChildWindows(parent, EnumChildWindowsCallback, GCHandle.ToIntPtr(listHandle));
}
finally
{
// free unmanaged list handle
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
internal static string GetText(IntPtr hwnd)
{
const uint WM_GETTEXTLENGTH = 0x000E;
const uint WM_GETTEXT = 0x000D;
int length;
IntPtr p;
var result = SendMessageTimeout(hwnd, WM_GETTEXTLENGTH, 0, 0, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5, out length);
if (result != 1 || length <= 0)
return string.Empty;
var sb = new StringBuilder(length + 1);
return SendMessageTimeoutText(hwnd, WM_GETTEXT, sb.Capacity, sb, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5, out p) != 0 ?
sb.ToString() :
string.Empty;
}
public static void Main(string[] args)
{
var p = Process.GetProcessesByName("WindowsFormsApplication1").First();
Console.WriteLine(GetText(p.MainWindowHandle)); // main window handle of form, returns "Form1"
Console.WriteLine(GetText(new IntPtr(0x70BA0))); // actual textbox handle, used Winspector, returns "quertz"
// iterate through dynamic handles of children
foreach (var hwnd in GetChildWindows(p.MainWindowHandle))
Console.WriteLine($"{hwnd}:{GetText(hwnd)}");
Console.ReadLine();
}
答案 1 :(得分:0)
要保存大量代码,可以使用Autoit库。
安装名为__qualname__
的nuget软件包
x