栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java搜索屏幕上的文本字段

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java搜索屏幕上的文本字段

我无法直接为您提供解决方案,但是我弄乱了一些代码,也许可以为您指明正确的方向。

您可能知道,Java在JVM中运行。这使其可以在任何操作环境中执行。每种操作环境(Windows,Mac等)都有其自己的系统,用于处理编辑框并将焦点设置在右侧窗口等。以下示例代码仅设计用于Windows,不符合Java语言的精神。正如Adriaan指出的那样,这类事情还有其他语言,但仅在Java上(有可能)就可以做到。

在Windows中,您必须了解如何管理所有活动窗口,以及所看到的所有内容(包括编辑框)都在考虑Windows
OS的“窗口”。我并不真正了解事物的幕后运作方式,因此我无法提供更多信息。在诸如C ++之类的本地语言中,Windows OS
API提供了一些功能,这些功能可用于实现您的目标。即,

EnumWindows()
EnumChildWindows()
GetClassName()
,和
SetForegroundWindow()
。您可以通过搜索MSDN文档库找到有关如何在本机语言中使用这些功能的文档。

因此,您需要能够从Java调用这些函数。通常情况下,无法调用这些本机方法。但是,有一个库可以帮助您:JNA库。JNA代表Java Native
Access,它使您可以使用前面提到的闪亮的新功能。

因此,为了以母语实现您的目标,通常会从调用

EnumWindows()
返回操作系统知道的所有父窗口列表开始。此列表将包含父窗口的窗口句柄-名为“
MSN”,“ Eclipse”,“ Microsoft
Office”等的窗口。作为父级,这些窗口中的每个都有子级。在此子级列表中,您会找到所需的“控件”:
Edit
控制。现在,许多应用程序对文本框使用不同的库和非标准的东西-
即Pidgin,我用其测试了一些相关代码的消息传递应用程序,具有每个名为“
gdkWindowChild”的控件,它不能确切告诉我们哪个控件实际上是EditBox或否则是一个允许我们输入文本的地方。那是你想法的主要问题;您无法始终准确地说出您希望将焦点放在哪个控件上,以便您可以输入文本。无论如何,我们将继续:

在找到相关的“父”窗口之后

EnumWindows()
,调用
EnumChildWindows()
将给我们所有属于父级的子窗口和其他“控件”(包括潜在的编辑框)。
EnumChildWindows()
为找到的每个子窗口调用一个回调函数,因此很容易在子窗口列表中“搜索”-使用
GetClassName()
查找控件的名称-
潜在地找到所需控件的HWND(窗口句柄) 。

找到正确的编辑框HWND后(当然,这是问题的总体范围,这是最困难的部分),只需简单调用

SetForegroundWindow(targetHWND)
即可将控件置于最前面,并将光标置于准备就绪状态。类型的编辑框。

这是我为帮助您入门而编写的一些示例代码。此代码将使用遍历所有活动窗口

EnumWindows()
,然后
EnumChildWindows()
在每个父窗口上调用,打印出找到的所有控件。请注意,此代码需要运行JNA库。

import com.sun.jna.Native;import com.sun.jna.Pointer;import com.sun.jna.examples.win32.W32API.HWND;import com.sun.jna.examples.win32.W32API.LPARAM;import com.sun.jna.win32.StdCallLibrary;import com.sun.jna.win32.W32APIOptions;public class IterateChildWindows {    public interface User32 extends StdCallLibrary {        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);        HWND FindWindow(String lpClassName, String lpWindowName);        int GetWindowRect(HWND handle, int[] rect);        int SendMessage(HWND hWnd, int msg, int wParam, byte[] lParam);         HWND FindWindowEx(HWND parent, HWND child, String className, String window);        boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg);        boolean EnumChildWindows(HWND parent, WNDENUMPROC callback, LPARAM info);        interface WNDENUMPROC extends StdCallCallback { boolean callback(HWND hWnd, Pointer arg);        }        int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount);        long GetWindowLong(HWND hWnd, int index);        boolean SetForegroundWindow(HWND in);        int GetClassNameA(HWND in, byte[] lpString, int size);    }    public static void main(String[] args) {     User32.INSTANCE.EnumWindows(new User32.WNDENUMPROC() { public boolean callback(HWND hWnd, Pointer userData) { // this will be called for each parent window found by EnumWindows(). the hWnd parameter is the HWND of the window that was found.     byte[] textBuffer = new byte[512];     User32.INSTANCE.GetWindowTextA(hWnd, textBuffer, 512);     String wText = Native.toString(textBuffer);     System.out.println("Window found: " + wText);     // now call EnumChildWindows() giving the previously found parent window as the first parameter     User32.INSTANCE.EnumChildWindows(hWnd, new User32.WNDENUMPROC() {         public boolean callback(HWND hWnd, Pointer userData) { // this is called for each child window that EnumChildWindows() finds - just like before with EnumWindows().  byte[] textBuffer = new byte[512];  User32.INSTANCE.GetClassNameA(hWnd, textBuffer, 512);  System.out.println(" - Found sub window / control class: " + new String(textBuffer).trim());  return true;         }     }, null);     return true; }        }, null);    }}

这是此代码提供的输出摘录:

Window found: Pidgin - Found sub window / control class: gdkWindowChild - Found sub window / control class: gdkWindowChild - Found sub window / control class: gdkWindowChild - Found sub window / control class: gdkWindowChildWindow found: Malwarebytes Anti-Malware - Found sub window / control class: Static - Found sub window / control class: Static - Found sub window / control class: Button - Found sub window / control class: Button - Found sub window / control class: Button

通过

PostMessage()
和直接将消息发送到HWND控件
SendMessage()
,例如,发送到MalwareBytes
Button
类,将触发程序本身的按钮按下,这与SetForegroundWindow()将编辑框样式控件置于最前面的方式非常相似,从而使您能够输入。有趣的东西玩:)

如果您想形象地表达我在说“父母”,“孩子”和“控制”时的意思,则该程序会有所帮助:Control
Viewer。它可以显示每个控件,并在应用程序窗口以及其他功能中突出显示它-非常有用的工具。

抱歉,如果该帖子离开了Java提供的舒适区域,但在这样的一般范围内,实际上没有其他方法可以实现您的目标。

我希望至少已向您展示了实现目标所需的条件,并为您指明了正确的方向。对于本机Windows
API来说,我不是上帝,所以在某些地方我可能是错的,但是代码确实可以工作。祝好运 :)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/507721.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号