gpt4 book ai didi

c# - 捕获从另一个应用程序键入的文本

转载 作者:行者123 更新时间:2023-11-30 21:55:37 25 4
gpt4 key购买 nike

我正在开发一个窗口应用程序来读取通过 C# 在屏幕上的任何应用程序上键入的文本。我使用的是 Win32 API,如下所示 - 我在 Google 上找到的解决方案:

private const int WM_GETTEXTLENGTH = 0x000E;
private const int WM_GETTEXT = 0x000D;

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

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

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, StringBuilder lParam);

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

public Terminal()
{
InitializeComponent();

IntPtr pFoundWindow = GetForegroundWindow();

IntPtr notepad = FindWindow("notepad", null);
IntPtr editx = FindWindowEx(notepad, IntPtr.Zero, "edit", null);
int length = SendMessage(editx, WM_GETTEXTLENGTH, 0, 0);
StringBuilder text = new StringBuilder(length);
int hr = SendMessage(editx, WM_GETTEXT, length, text);
Console.WriteLine(text);
}

但这只能从记事本中读取现有的文本。在任何程序、任何窗口上打字时,我应该如何阅读文本?

最佳答案

示例中的以下代码

IntPtr notepad = FindWindow("notepad", null);

意思是获取一个名为notepad的进程的句柄。

还有下一个

IntPtr editx = FindWindowEx(notepad, IntPtr.Zero, "edit", null);

也意味着您尝试从记事本中找到一个窗口句柄,并且窗口标题是editedit窗口是记事本的可编辑区域。

如果您要使您的应用程序适用于任何进程,则不能声明您的目标是源代码。换句话说,您需要另一种方法来指定要获取文本的窗口。

我的建议是:您需要以下 Windows API 才能在运行时获取目标窗口。

例如,您可以使用SetWindowsHookEx 在您的应用程序外部获取鼠标事件,然后当用户点击目标窗口时它会触发回调。接下来触发回调函数,可以使用GetCursorPos获取鼠标位置,使用WindowFromPoint获取要读取文本的窗口。

更新

我提供了我在其他项目中的示例代码,并挑选了一些对您有用的部分。

    /// <summary>
/// A hook handle for grabbing mouse click, used to get the position of target window.
/// </summary>
private IntPtr _hook = IntPtr.Zero;

//button click event
private void selectWindow_Click(object sender, EventArgs e)
{
if (_hook != IntPtr.Zero)
return;
using (Process p = Process.GetCurrentProcess())
{
using (ProcessModule m = p.MainModule)
{
_hook = SafeNativeMethods.SetWindowsHookEx(SafeNativeMethods.WH_MOUSE_LL, hookCallback, SafeNativeMethods.GetModuleHandle(m.ModuleName), 0);
}
}
}

/// <summary>
/// Callback method of mouse hook.
/// </summary>
private IntPtr hookCallback(int code, IntPtr w, IntPtr l)
{
if (code >= 0 && (WMessages)w == WMessages.WM_LBUTTONDOWN)
{
CPoint pt;
SafeNativeMethods.GetCursorPos(out pt);
//hey man! the _windowHandle is what you need
_windowHandle = SafeNativeMethods.WindowFromPoint(pt);
SafeNativeMethods.UnhookWindowsHookEx(_hook);
_hook = IntPtr.Zero;
//...and do your stuff here!
}
return SafeNativeMethods.CallNextHookEx(_hook, code, w, l);
}

还有定义。 Windows API 的数量

    /// <summary>
/// Window Hook ID 14 - Low level mouse proc.
/// </summary>
internal const int WH_MOUSE_LL = 14;

/// <summary>
/// Get the window handle from a specified point.
/// </summary>
/// <param name="point">Specified point</param>
/// <returns>Window handle</returns>
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr WindowFromPoint(CPoint point);

/// <summary>
/// Register a hook.
/// </summary>
/// <param name="idHook">Hook type</param>
/// <param name="lpfn">Function pointer</param>
/// <param name="hMod">Module ID</param>
/// <param name="dwThreadId">Thread ID</param>
/// <returns>Hook handle</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

/// <summary>
/// Unregister a hook.
/// </summary>
/// <param name="hhk">Hook handle</param>
/// <returns>Successful</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool UnhookWindowsHookEx(IntPtr hhk);

/// <summary>
/// Call next hook (if needed).
/// </summary>
/// <param name="hhk">Hook handle</param>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

/// <summary>
/// Get moudle handle by module name.
/// </summary>
/// <param name="lpModuleName">Module name</param>
/// <returns>Module handle</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr GetModuleHandle(string lpModuleName);

/// <summary>
/// Get current cursor position.
/// </summary>
/// <param name="lpPoint">Output position</param>
/// <returns>Successful</returns>
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(out CPoint lpPoint);

更新 2

我忘记了 CPoint 结构 lol。

/// <summary>
/// Win32 POINT structure.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct CPoint
{
public int x;
public int y;
}

关于c# - 捕获从另一个应用程序键入的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32131471/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com