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

我想创build一个应用程序,它获取光标下的单词(不仅用于文本字段),但我找不到如何做到这一点。 使用OCR非常困难。 我见过的唯一工作是Deskperience组件。 他们支持“本地”的方式,但我花费了很多。 现在我试图找出这种“本地”方式(也许某种程度上是钩)。 任何帮助将不胜感激。

编辑:我find了一种方式,但它只获取控件的整个文本。 任何想法如何从整个文本只获得光标下的单词?

在最近的Windows版本中,从一个应用程序到另一个应用程序收集信息的推荐方式(当然,如果您不拥有目标应用程序)是使用UI自动化技术。 维基百科对于这方面的更多信息是非常好的: Microsoft 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); } 

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

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

  • 大多数情况下,这一切都具有沉重的安全隐患。 使用这种技术(或直接Windows技术,如WindowFromPoint)将需要足够的权利(如作为pipe理员)。 我不认为DExperience有办法克服这些限制,除非他们在计算机上安装内核驱动程序。

  • 有些应用程序不会向任何人暴露任何东西,即使有适当的权利。 例如,如果我正在编写银行应用程序,我不希望你监视我的应用程序将显示的内容:-)。 其他应用程序(如带DRM的Outlook)不会因相同的原因而暴露任何内容。

  • 只有UI自动化文本模式支持可以提供更多的信息(如单词)而不仅仅是整个文本。 唉,即使支持全球的UI自动化,这种特定的模式也不被IE或FF所支持。

所以,如果这一切都不适合你,你将不得不更深入地使用OCR或形状识别技术。 即使这样,也会有一些你根本无法做到的情况(因为担保权利)。

如果您要“窥探”的应用程序正在自己绘制文本,这是不平凡的。 一种可能的解决scheme是触发其他应用程序通过使光标下方的区域无效来绘制其窗口的一部分。

当其他应用程序绘制时,您将不得不截取文本绘图调用。 一种方法是在另一个应用程序中注入代码,并将调用拦截到绘制文本的GDI函数中。 当您debugging本机应用程序时,这是Visual Studio实现断点的function。 为了testing这个想法,你可以使用像走弯路这样的图书馆(但这不是免费的商业用途)。

您还可以检查应用程序是否支持Windows中的其中一个可访问性API,以便为盲人使用屏幕阅读器。

谨慎的一句话:我自己也没有做过这样的事情。

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

  • WindowFromPoint
  • ChildWindowFromPointEx

稍后,您可以遍历控件并尝试从基于types的内部获取文本。 如果我会find一些时间,我会尝试发布这样的代码。

经过一番检查,看起来像最好的方式(不幸的是也很难)是钩入GDI文本渲染一些讨论

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

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

这最终将您指向字符识别,您可以查看光标下的像素,然后尝试找出哪些字词在那里。 但这不仅非常不平凡,也不是万无一失的。 如果单词的一部分不可见,因为它伸出窗外?

这绝对不是微不足道的。 有几种方法来处理它。 但是没有可靠的方法可以与所有窗口一起使用。

有一个使用OCR获取文本的SDK。 它不是免费的,但与其他产品相比,它是相当便宜的: http : //www.screenocr.com/screen-ocr-library-sdk.htm他们有一个应用程序提供相同的function,所以你也可以尝试演示。

要实现这一点,你需要一个多pipe齐下的方法。

UIA在许多应用程序中都可以工作,但是您需要尝试查看文本的返回位置。 它可能在元素,值或范围中。 即使在办公室应用程序中也没有一致性。

如果UIA失败,则枚举运行对象表(ROT)并将COM指针检索到注册在ROT中的各种应用程序。 然后,您可以将这些指针转换为基本的办公室types:
例如:

 enumerate ROT - then wb = (Excel._Workbook)enumerator.Value; string strText = wb.Application.ActiveCell.Text.ToString(); 

如果上述两种方法都失败了,那么在MODI(Microsoft Office Document Imaging 12.0 Type Library)中使用免费的OCR系统,