如何在Windows中的光标下获取单词?

ble*_*lez 49 c# windows ocr hook winapi

我想创建一个应用程序,它获取光标下的单词(不仅仅是文本字段),但我找不到如何做到这一点.使用OCR非常困难.我见过的唯一工作就是Deskperience组件.他们支持'本土'方式,但我花了很多钱.现在我想弄清楚这种"原生"方式是什么(也许某种程度上是挂钩).任何帮助将不胜感激.

编辑: 我找到了一种方法,但它只获得控件的整个文本.知道如何只从整个文本中获取光标下的单词吗?

Sim*_*ier 50

在最新版本的Windows中,将信息从一个应用程序收集到另一个应用程序(如果您当前没有目标应用程序)的推荐方法是使用UI自动化技术.维基百科非常适合获得更多相关信息:Microsoft UI Automation

基本上,UI自动化将使用所有必要的手段来收集可以收集的内容

这是一个小型控制台应用程序代码,它将监视其他应用程序的UI.运行它并将鼠标移动到不同的应用程序.每个应用程序对各种"UI自动化模式"都有不同的支持.例如,这里展示了Value模式和Text模式.

static void Main(string[] args)
{
    do
    {
        System.Drawing.Point mouse = System.Windows.Forms.Cursor.Position; // use Windows forms mouse code instead of WPF
        AutomationElement element = AutomationElement.FromPoint(new System.Windows.Point(mouse.X, mouse.Y));
        if (element == null)
        {
            // no element under mouse
            return;
        }

        Console.WriteLine("Element at position " + mouse + " is '" + element.Current.Name + "'");

        object pattern;
        // the "Value" pattern is supported by many application (including IE & FF)
        if (element.TryGetCurrentPattern(ValuePattern.Pattern, out pattern))
        {
            ValuePattern valuePattern = (ValuePattern)pattern;
            Console.WriteLine(" Value=" + valuePattern.Current.Value);
        }

        // the "Text" pattern is supported by some applications (including Notepad)and returns the current selection for example
        if (element.TryGetCurrentPattern(TextPattern.Pattern, out pattern))
        {
            TextPattern textPattern = (TextPattern)pattern;
            foreach(TextPatternRange range in textPattern.GetSelection())
            {
                Console.WriteLine(" SelectionRange=" + range.GetText(-1));
            }
        }
        Thread.Sleep(1000);
        Console.WriteLine(); Console.WriteLine();
    }
    while (true);
}
Run Code Online (Sandbox Code Playgroud)

实际上,Internet Explorer和Firefox支持UI自动化,但据我所知,Chrome不支持.查看此链接:Google Chrome何时可以访问?

现在,这只是你工作的开始:-),因为:

  • 大多数时候,所有这些都具有严重的安全隐患.使用此技术(或直接Windows技术,如WindowFromPoint)将需要足够的权限(例如作为管理员).我不认为DExperience有任何方法可以克服这些限制,除非他们在计算机上安装内核驱动程序.

  • 即使有适当的权利,某些应用程序也不会向任何人公开任何内容 例如,如果我正在编写银行应用程序,我不希望您监视我的应用程序将显示的内容:-).其他应用程序(如带DRM的Outlook)不会出于同样的原因暴露任何内容.

  • 只有UI自动化文本模式支持才能提供更多信息(如单词)而不仅仅是整个文本.唉,IE和FF都不支持这种特定模式,即使它们支持全局UI自动化.

因此,如果所有这些对您不起作用,您将不得不深入研究并使用OCR或形状识别技术.即便如此,在某些情况下,您根本无法完成此操作(因为安全权利).


小智 9

如果您想要"窥探"的应用程序自己绘制文本,这是非常重要的.一种可能的解决方案是通过使光标正下方的区域无效来触发另一个应用程序绘制其窗口的一部分.

当其他应用程序绘制时,您将不得不拦截文本绘制调用.一种方法是在另一个应用程序中注入代码,并拦截调用到绘制文本的GDI函数.调试本机应用程序时,这是visual studio实现断点的方法.为了测试这个想法,你可以使用像绕道一样的库(但这不是免费的商业用途).

您还可以检查应用程序是否支持Windows中的某个可访问性API,以便为盲人屏幕阅读器等内容提供便利.

提醒一句:我自己没有做过这些.

  • 绕道而行的免费版本(续读)是EasyHook(http://easyhook.codeplex.com) (2认同)

baa*_*mon 7

如果应用程序不仅需要处理.Net应用程序,我将从导入函数(P/Invoke)开始:

稍后您可以迭代控件并尝试根据类型从内部获取文本.如果我找到一些时间,我会尝试发布这样的代码.

经过一些检查,看起来最好的方式(不幸的是,也很难)是挂钩到GDI文本呈现一些讨论

  • System.Windows.Automation API 也适用于非 .NET 应用程序;它建立在 COM 自动化 API (http://msdn.microsoft.com/en-us/library/ff486375%28v=VS.85%29.aspx) 之上,所以任何最终创建 win32 控件的东西都可以工作,因为以及其他没有自动化“提供程序”的小部件集(例如,IE 窗口、WPF 等) (2认同)

Jon*_*ood 5

我会回应Patricker所说的,但我认为没有可靠的方法来做你想做的事.

您可能获得了窗口文本或类似的东西.但是如果光标位于不使用窗口文本存储其内容的窗口上呢?Windows没有义务以特定方式存储数据.

这最终会指向字符识别,您可以在其中查看光标下的像素,并尝试找出哪些字符.但这不仅非常重要,而且也不是万无一失的.如果单词的一部分因为它延伸到窗外而不可见怎么办?

这绝对不是微不足道的.有几种方法可以解决它.但是没有可靠的方法可以适用于所有窗口.