一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

窗口元素抓取方法、装置以及存储介质与流程

2022-06-01 13:46:20 来源:中国专利 TAG:


1.本技术涉及自动控制技术领域,特别是涉及一种窗口元素抓取方法、装置以及存储介质。


背景技术:

2.rpa是robotic process automation的首字母缩写,即机器人流程自动化。rpa要自动的同屏幕上的各种窗口、按钮、下拉列表等不同元素进行交互,首先就要定位到元素的位置(这里的位置不仅包括元素在屏幕上的坐标位置还包括元素在整个程序窗口的结构位置),然后获取元素信息,再对元素做相应的操作。所以定位及获取元素信息的抓屏技术作为rpa技术的基础显得尤为重要。由于用户在不同的操作系统,不同的软件窗口上作业,所以要求rpa能在不同的操作系统和不同的软件窗口上进行操作,那么对窗口元素的抓取也是在不同操作系统和不同的窗口上进行,这使得抓屏是多种方法实现的复合技术。目前抓屏的技术主要包含:1.通过系统的api基于窗口元素的树形结构来定位窗口元素及获取窗口元素的信息;2.使用图像识别和ocr的技术来定位和获取元素信息;3.直接使用窗口元素的坐标位置来定位窗口元素。目前使用频率最高,操作最稳定的抓屏技术是通过系统的api基于窗口元素的树形结构来定位窗口元素及获取窗口元素的信息。rpa的抓屏程序通过窗口的可访问技术(如uia、msaa)或程序的api及程序脚本(如ie浏览器、chrome浏览器)和窗口元素进行交互;这种方法一般直接调用系统或相应程序的api函数来获取窗口的可访问对象,通过窗口元素的可访问对象,获取窗口元素的坐标位置和窗口元素的信息,定位元素在整个窗口元素中的结构位置。
3.然而,现有的rpa的抓屏程序和用户操作的业务程序是在两个进程中的,抓屏程序要获取其他程序窗口的信息,就需要和其他程序进行进程间通信,进程间通信耗时是远大于进程内的数据访问的。抓屏程序直接使用系统和程序api函数获取只有少量窗口元素的程序窗口信息的时效性是勉强可以接受的。但对于复杂的窗口程序或者丰富的网页,直接使用api函数获取元素信息特别是定位元素在整个窗口中的结构位置时,抓屏程序会和业务窗口进行大量的进程间通信,消耗大量时间,这使得抓屏程序无法正常使用。目前rpa的抓屏技术也向着和用户无交互,用户无感知的智能抓屏方向发展,即在后台运行抓屏程序自动抓取用户的业务操作,这对抓屏技术的时效性提出了更高的要求。同时现在的一些程序故意在窗口上做一些改动使得系统或程序api函数无法直接定位到窗口内的窗口元素,导致抓屏失败。故直接使用系统或程序api抓屏存在许多的问题。
4.针对上述的现有技术中存在的抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信,尤其是面对复杂的程序窗口,会消耗大量时间,影响窗口元素抓取效率的技术问题,目前尚未提出有效的解决方案。


技术实现要素:

5.本公开的实施例提供了一种窗口元素抓取方法、装置以及存储介质,以至少解决
现有技术中存在的抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信,尤其是面对复杂的程序窗口,会消耗大量时间,影响窗口元素抓取效率的技术问题。
6.根据本公开实施例的一个方面,提供了一种窗口元素抓取方法,包括:响应于用户选择程序的第一触发操作,确定目标窗口应用程序;获取目标窗口应用程序包含的窗口元素,并根据窗口元素在内存中构建树形结构,其中树形结构中的节点与窗口元素在目标窗口应用程序中的排列相关并且包含窗口元素的结构信息;以及响应于用户选择抓取的目标窗口元素的第二触发操作,根据树形结构确定与目标窗口元素相关的窗口元素信息。
7.根据本公开实施例的另一个方面,还提供了一种存储介质,存储介质包括存储的程序,其中,在程序运行时由处理器执行以上任意一项所述的方法。
8.根据本公开实施例的另一个方面,还提供了一种窗口元素抓取装置,包括:窗口程序确定模块,用于响应于用户选择程序的第一触发操作,确定目标窗口应用程序;树形结构构建模块,用于获取目标窗口应用程序包含的窗口元素,并根据窗口元素在内存中构建树形结构,其中树形结构中的节点与窗口元素在目标窗口应用程序中的排列相关并且包含窗口元素的结构信息;以及窗口信息抓取模块,用于响应于用户选择抓取的目标窗口元素的第二触发操作,根据树形结构确定与目标窗口元素相关的窗口元素信息。
9.根据本公开实施例的另一个方面,还提供了一种窗口元素抓取装置,包括:处理器;以及存储器,与处理器连接,用于为处理器提供处理以下处理步骤的指令:响应于用户选择程序的第一触发操作,确定目标窗口应用程序;获取目标窗口应用程序包含的窗口元素,并根据窗口元素在内存中构建树形结构,其中树形结构中的节点与窗口元素在目标窗口应用程序中的排列相关并且包含窗口元素的结构信息;以及响应于用户选择抓取的目标窗口元素的第二触发操作,根据树形结构确定与目标窗口元素相关的窗口元素信息。
10.在本公开实施例中,在进行窗口元素的抓取的过程中,首先获取待抓取的目标窗口应用程序中的窗口元素,并在内存中根据窗口元素构建树形结构。在用户选择待抓取的窗口元素时,可以从该树形结构中获取抓取的窗口元素的窗口元素信息。因此,在用户操作选择窗口元素的同时可以同时抓取窗口元素信息,相当于用户操作窗口应用程序和抓取的过程在同一个进程中进行。与现有技术中抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信相比,本方案只需要在内存中的树形结构获取窗口信息,不需要进行跨进程操作。因此可以达到提升窗口元素抓取效率的技术效果。此外,树形结构是根据窗口元素而创建的,因此即使面对复杂的窗口元素,本方案也可以快速地进行窗口元素抓取。进而解决了现有技术中存在的抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信,尤其是面对复杂的程序窗口,会消耗大量时间,影响窗口元素抓取效率的技术问题。
附图说明
11.此处所说明的附图用来提供对本公开的进一步理解,构成本技术的一部分,本公开的示意性实施例及其说明用于解释本公开,并不构成对本公开的不当限定。在附图中:
12.图1是用于实现根据本公开实施例1所述的方法的计算设备的硬件结构框图;
13.图2是根据本公开实施例1的第一个方面所述的窗口元素抓取方法的流程示意图;
14.图3示意性地示出了本公开实施例1窗口元素结构的示意图;
15.图4是根据本公开实施例1所述的窗口元素抓取的整体流程示意图;
16.图5是根据本公开实施例1所述的构建树形结构的过程示意图;
17.图6a是根据本公开实施例1所述的元素抓取的程序实现过程示意图;
18.图6b是根据本公开实施例1所述的树形结构构建的程序实现过程示意图;
19.图7是根据本公开实施例2所述的窗口元素抓取装置的示意图;以及
20.图8是根据本公开实施例3所述的窗口元素抓取装置的示意图。
具体实施方式
21.为了使本技术领域的人员更好地理解本公开的技术方案,下面将结合本公开实施例中的附图,对本公开实施例中的技术方案进行清楚、完整地描述。显然,所描述的实施例仅仅是本公开一部分的实施例,而不是全部的实施例。基于本公开中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本公开保护的范围。
22.需要说明的是,本公开的说明书和权利要求书及上述附图中的术语“第一”、“第二”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本公开的实施例能够以除了在这里图示或描述的那些以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。
23.实施例1
24.根据本实施例,还提供了一种窗口元素抓取方法实施例,需要说明的是,在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行,并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。
25.本实施例所提供的方法实施例可以在移动终端、计算机终端或者类似的计算设备中执行。图1示出了一种用于实现窗口元素抓取方法的计算设备的硬件结构框图。如图1所示,计算设备可以包括一个或多个处理器(处理器可以包括但不限于微处理器mcu或可编程逻辑器件fpga等的处理装置)、用于存储数据的存储器、以及用于通信功能的传输装置。除此以外,还可以包括:显示器、输入/输出接口(i/o接口)、通用串行总线(usb)端口(可以作为i/o接口的端口中的一个端口被包括)、网络接口、电源和/或相机。本领域普通技术人员可以理解,图1所示的结构仅为示意,其并不对上述电子装置的结构造成限定。例如,计算设备还可包括比图1中所示更多或者更少的组件,或者具有与图1所示不同的配置。
26.应当注意到的是上述一个或多个处理器和/或其他数据处理电路在本文中通常可以被称为“数据处理电路”。该数据处理电路可以全部或部分的体现为软件、硬件、固件或其他任意组合。此外,数据处理电路可为单个独立的处理模块,或全部或部分的结合到计算设备中的其他元件中的任意一个内。如本公开实施例中所涉及到的,该数据处理电路作为一种处理器控制(例如与接口连接的可变电阻终端路径的选择)。
27.存储器可用于存储应用软件的软件程序以及模块,如本公开实施例中的窗口元素抓取方法对应的程序指令/数据存储装置,处理器通过运行存储在存储器内的软件程序以
及模块,从而执行各种功能应用以及数据处理,即实现上述的应用程序的窗口元素抓取方法。存储器可包括高速随机存储器,还可包括非易失性存储器,如一个或者多个磁性存储装置、闪存、或者其他非易失性固态存储器。在一些实例中,存储器可进一步包括相对于处理器远程设置的存储器,这些远程存储器可以通过网络连接至计算设备。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。
28.传输装置用于经由一个网络接收或者发送数据。上述的网络具体实例可包括计算设备的通信供应商提供的无线网络。在一个实例中,传输装置包括一个网络适配器(network interface controller,nic),其可通过基站与其他网络设备相连从而可与互联网进行通讯。在一个实例中,传输装置可以为射频(radio frequency,rf)模块,其用于通过无线方式与互联网进行通讯。
29.显示器可以例如触摸屏式的液晶显示器(lcd),该液晶显示器可使得用户能够与计算设备的用户界面进行交互。
30.此处需要说明的是,在一些可选实施例中,上述图1所示的计算设备可以包括硬件元件(包括电路)、软件元件(包括存储在计算机可读介质上的计算机代码)、或硬件元件和软件元件两者的结合。应当指出的是,图1仅为特定具体实例的一个实例,并且旨在示出可存在于上述计算设备中的部件的类型。
31.在上述运行环境下,根据本实施例的第一个方面,提供了一种窗口元素抓取方法,该方法可以应用在终端设备(例如:智能手机、平板、pc机等设备)上运行,根据用户的触发操作,抓取对应的窗口元素的相关信息。图2示出了该方法的流程示意图,参考图2所示,该方法包括:
32.s202:响应于用户选择程序的第一触发操作,确定目标窗口应用程序;
33.s204:获取目标窗口应用程序包含的窗口元素,并根据窗口元素在内存中构建树形结构,其中树形结构中的节点与窗口元素在目标窗口应用程序中的排列相关并且包含窗口元素的结构信息;以及
34.s206:响应于用户选择抓取的目标窗口元素的第二触发操作,根据树形结构确定与目标窗口元素相关的窗口元素信息。
35.正如背景技术中所述的,现有的rpa的抓屏程序和用户操作的业务程序是在两个进程中的,抓屏程序要获取其他程序窗口的信息,就需要和其他程序进行进程间通信,进程间通信耗时是远大于进程内的数据访问的。故直接使用系统或程序api抓屏存在许多的问题。
36.针对背景技术中存在的技术问题,结合图3所示,本市实施例技术方案在步骤s202中,在需要进行窗口元素抓取的情况下,操作人员(用户)首先可以选择需要进行抓取的目标窗口应用程序。其中,目标窗口程序例如可以有多个,例如:word程序、excel程序以及其他的窗口应用程序,操作人员可以通过触发的方式选择目标窗口应用程序。在一个具体实例中,目标窗口应用程序运行在pc端(台式电脑或者笔记本电脑等终端设备),因此操作人员可通过鼠标的移动选择目标窗口应用程序(对应于第一触发操作)。在另一个实例中,目标窗口应用程序例如还可以运行在支持触屏操作的终端设备上(例如智能手机或者平板等终端设备),因此操作人员还可以通过触控的方式选择目标窗口应用程序(对应于第一触发操作)。在这种情况下,终端设备可以响应于用户选择程序的第一触发操作,确定目标窗口
应用程序。
37.进一步地,在步骤s204中,终端设备获取目标窗口应用程序包含的窗口元素,并根据窗口元素在内存中构建树形结构。在一个具体实例中,图3示例性地示出了目标窗口应用程序包含的窗口元素,例如:窗口元素200、窗口元素210以及窗口元素211等。终端设备在确定目标窗口应用程序之后,首先获取目标窗口应用程序包含的窗口元素。进一步地,终端设备根据窗口元素在内存中构建树形结构,即按照窗口元素在目标窗口应用程序中的排列将窗口元素构建成树形结构。由于每个窗口元素在窗口应用程序都对应有结构信息,在一个具体实例中,结构信息例如包括窗口元素类型、文本等。因此,构建的树形结构中的节点还包含窗口元素的结构信息。
38.最终,在步骤s206中,用户可以在该目标窗口应用程序中选择需要进行抓取的窗口元素,例如:用户需要抓取窗口元素211,则用户可以通过鼠标点击或者通过触控的方式(对应于第二触发操作)选择该窗口元素211(即目标窗口元素)。在用户进行第二触发操作的情况下,终端设备可以响应该触发操作,根据树形结构确定与目标窗口元素相关的窗口元素信息,其中窗口元素信息例如包括窗口元素的类型、文本以及窗口元素在该树形结构中的位置信息等。从而完成窗口元素的抓取操作。
39.从而通过这种方式,在进行窗口元素的抓取的过程中,首先获取待抓取的目标窗口应用程序中的窗口元素,并在内存中根据窗口元素构建树形结构。在用户选择待抓取的窗口元素时,可以从该树形结构中获取抓取的窗口元素的窗口元素信息。因此,在用户操作选择窗口元素的同时可以同时抓取窗口元素信息,相当于用户操作窗口应用程序和抓取的过程在同一个进程中进行。与现有技术中抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信相比,本方案只需要在内存中的树形结构获取窗口信息,不需要进行跨进程操作。因此可以达到提升窗口元素抓取效率的技术效果。此外,树形结构是根据窗口元素而创建的,因此即使面对复杂的窗口元素,本方案也可以快速地进行窗口元素抓取。进而解决了现有技术中存在的抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信,尤其是面对复杂的程序窗口,会消耗大量时间,影响窗口元素抓取效率的技术问题。
40.可选地,窗口元素包括主窗口元素和至少一级子窗口元素,并且根据窗口元素在内存中构建树形结构,包括:根据主窗口元素在内存中构建树形结构的根节点;根据至少一级子窗口元素在内存中构建树形结构的子节点;以及根据根节点和子节点以及主窗口元素和至少一级子窗口元素在目标窗口应用程序中的排列构建树形结构。
41.具体地,一般性地窗口元素包括主窗口元素和至少一级子窗口元素,其中每一级子窗口元素例如可以包括至少一个子窗口元素。参考图3所示,例如:窗口元素200对应于主窗口元素,窗口元素210等对应于第一级子窗口元素,窗口元素211等对应于第二级子窗口元素,此外可以包括多级窗口元素,此处不再赘述。在根据窗口元素在内存中构建树形结构的操作中,终端设备首先根据主窗口元素在内存中构建树形结构的根节点,即:将主窗口元素构建成该树形结构的根节点(也可以称为父节点)。然后,终端设备根据至少一级子窗口元素在内存中构建树形结构的子节点,其中将每一级子窗口元素构建成树形结构的每一层子节点,例如将窗口元素210等第一级子窗口元素构建成该树形结构的第一层子节点,将窗口元素211等第二级子窗口元素构建成该树形结构的第二层子节点(也可以称为孙子节点),依次对每一级子窗口元素进行构建,直至将最后一级子窗口元素构建成子节点,完成
节点的构建。最终,根据根节点和子节点以及主窗口元素和至少一级子窗口元素在目标窗口应用程序中的排列构建树形结构。从而,可以依次的对窗口元素进行节点的构建,最终构建成树形结构。
42.可选地,窗口元素的结构信息包括以下至少一项:窗口元素的元素信息、运行id、外包矩形、父节点指针、子节点指针。
43.具体地,每个窗口元素包括对应的结构信息,树形结构的每个节点包括窗口元素的结构信息,其中结构信息可以构成结构体。在一个具体实例中,树形结构的节点(或者窗口元素)结构信息组成的结构体形式如下所示:
44.treenode
45.struct treenode
46.{
47.info;
48.rid;
49.rect;
50.rectadjust;
51.pparent;
52.pchildrenlist;
53.};
54.info包含窗口元素的元素类型,元素名称,文本信息等;
55.rid表示窗口元素的运行时id,窗口元素从创建到销毁过程中的唯一编号;
56.rect表示窗口元素的外包矩形,即窗口的左上角点的坐标(left,top)和右下角点的坐标(right,bottom);
57.rectadjust表示修正后的窗口元素外包矩形;
58.pparent指向窗口元素的父节点;
59.pchildrenlist包含窗口元素所有的子节点指针。
60.通过该结构体的设计,在窗口元素抓取的过程中可以快速地确定窗口元素信息。
61.可选地,根据主窗口元素在内存中构建树形结构的根节点,包括:在内存中构建树形结构的根节点;获取与主窗口元素对应的句柄并根据句柄获取主窗口元素的可访问对象,根据可访问对象获取与主窗口元素对应的元素信息;确定主窗口元素的运行id和外包矩形,并设置主窗口元素的父节点指针为空,设置主窗口元素的子节点指针为第一级子窗口元素;将与主窗口对应的元素信息、运行id、外包矩形、父节点指针为空、子节点指针为第一级子窗口元素作为根节点的结构信息。
62.具体地,在根据主窗口元素在内存中构建树形结构的根节点的操作中,终端设备首先在内存中构建树形结构的根节点(tree_node_top)。然后,终端设备获取与主窗口元素对应的句柄。再具体操作中,终端设备开启线程,当鼠标移动时,向上逐级获取鼠标所在位置的窗口句柄直到获取到程序的最上层主窗口句柄(hwnd_top)。然后,终端设备调用系统api使用主窗口句柄hwnd_top作为参数获取主窗口的可访问对象(acc_obj_top)。进一步地,根据可访问对象acc_obj_top获取与主窗口元素对应的元素信息,即info信息(例如元素类型,元素名称,文本信息等)。进一步地,终端设备确定主窗口元素的运行id和外包矩
元素n)的结构信息存储至内存中预先设置的第二队列(queue),并计算第二队列中节点的数量。然后,根据预先设置的线程数量和第二队列中节点的数量,将第一级子窗口元素的子节点存储至每个线程对应的第一队列。在一个具体实例中,系统会预先分配maxthreadnum数量的线程,终端设备首先获取第二队列queue的元素个数num(即第一级子窗口元素对应的子节点的个数),那么avg=maxthreadnum/num(这里是整除),rem=maxthreadnum-avg*num,如果rem》0,那么1到rem的线程分配avg 1个第二队列queue中的元素(第一级子窗口元素对应的子节点),rem 1到maxthreadnum的线程分配avg个第二队列queue中的元素,如果rem==0,所有线程都分配avg个第二队列queue中的元素。进一步地,每个线程分配到的queue元素放入自己的第一队列queue_in中。然后,通过每个线程,根据每个线程对应的第一队列中的第一级子窗口元素的可访问对象获取第二级子窗口元素的可访问对象,并根据第二级子窗口元素的可访问对象构建与第二级子窗口元素对应的子节点。在具体操作中,maxthreadnum个线程并发执行,在每个线程中依次取出第一队列queue_in中的元素,使用第一级窗口元素的可访问对象acc_obj_child获取第二级子窗口元素的可访问对象acc_obj_grandchild。然后确定第二级子窗口元素对应的元素信息、运行id、外包矩形,并设置第二级子窗口元素的父节点指针为第一级子窗口元素的子节点,设置第二级子窗口元素的的子节点指针为第三级子窗口元素,作为第二级子窗口元素的子节点的结构信息。从而完成第二级子窗口元素的子节点的构建。所有线程执行完毕后,清空之前的第二队列,将每个第一队列中的元素汇总依次放入第二队列中。此处需要说明的是,可以将每个第一队列中的元素首先放入图5中的队列queue_out中,然后将每个队列queue_out中的元素依次汇总到第二队列queue中(此时的第二队列中包括元素1-元素m)。循环进行树形结构的下一层的构建操作,直至第一队列中的元素为空,即完成所有的窗口元素的构建操作。从而通过这种方式,在构建树形结构的子节点的过程中,可以利用多个线程并行的进行构建每一层的子节点,因此可以提升构建的效率。
66.可选地,还包括:根据主窗口元素和至少一级子窗口元素的外包矩形对树形结构进行修正操作。
67.具体地,正如上面内容所述的,结构信息还包括rectadjust(表示修正后的窗口元素外包矩形),其作用是为了使父节点修正后的外包刚好包含所有子节点的外包。在一个具体应用场景中可能会出现子节点的外包矩形面积大于父节点的外包矩形面积,例如:子节点是一个下拉菜单窗口元素,当下拉菜单展开的情况下,面积可能会超出上一级节点(父节点)的外包矩形。因此在这种情况下还需要根据主窗口元素和至少一级子窗口元素的外包矩形对树形结构进行修正操作。在外包矩形修正的操作中,从根节点开始,上一级节点(相当于父节点tree_node_parent)对每个相邻的下一级节点(相当于子节点tree_node_child)递归的调用修正方法进行修正,每个子节点修正完之后,使用父节点的外包矩形rect和子节点修正后的外包矩形rect进行比较,如果子节点修正后的外包没有被父节点的外包包含,那么父节点修正后的外包取子节点修正后的外包。更具体的代码实现如下所示:
68.tree_node_parent.rectadjust left=
69.min(tree_node_parent.rectadjust.left,tree_node_child.rectadjust.left);
70.tree_node_parent.rectadjust.top=min(tree_node_parent.rectadjust.top,
tree_node_child.rectadjust.top);
71.tree_node_parent.rectadjust.right=
72.max(tree_node_parent.rectadjust.right,tree_node_child.rectadjust.right);
73.tree_node_parent.rectadjust.bottom=
74.max(tree_node_parent.rectadjust.bottom,tree_node_child.rectadjust.bottom);
75.从而通过这种方式,在树形结构构建完成之后,还可以对树形结构进行修正操作,因此修正后的树形结构更加的正确,使得最终抓取的窗口元素更加准确。
76.可选地,还包括:设置监听线程对窗口元素进行监听;以及在窗口元素发生变化的情况下,根据发生变化的窗口元素对树形结构进行局部调整。
77.具体地,窗口应用程序的窗口元素还可能会根据用户的操作而改变,例如:窗口元素可能会根据用户的拖拽操作改变窗口位置,还可能根据用户的缩放操作改变窗口大小。为了使得树形结构与窗口元素相对应,因此本方案还可以根据窗口元素的变化对树形结构进行局部调整。具体地,参考图4所示,终端设备还可以设置监听线程对窗口元素进行监听,在实际应用中,开启监听线程监听窗口元素变化,该监听线程和构建树形结构的线程做线程互斥的操作。在监听到窗口元素发生变化的情况下,通过变化的窗口元素的可访问对象acc_obj的rid,直接找到对应的树形结构节点tree_node=map[rid],使用tree_node的pparent找到其父节点tree_node_parent,清除父节点tree_node_parent及其子孙节点的数据,即:清除该父节点的下层节点的数据。然后使用acc_obj对父节点对应的窗口元素及其所有子孙窗口元素根据上述的节点构建方法重新建树,由于这里只是对发生变化的窗口元素及发生变化的窗口元素的下级窗口元素进行重新建树,而不影响发生变化的窗口元素的上级窗口元素,因此是一个局部建树的过程。在局部建树完毕后,用新生成的局部树替换之前父节点tree_node_parent处的树。从而通过这种方式,可以根据窗口元素的变化对构建的树形结构进行调整,使得窗口元素的抓取更加准确。此外,在调整的过程中只是对发生变化的窗口元素进行局部调整,不需要对整个树形结构进行重新构建,因此还可以加快树形结构的调整速度,节省计算资源。
[0078]
可选地,响应于用户选择抓取的目标窗口元素的第二触发操作,还包括:对树形结构的节点进行遍历,确定不包含第二触发操作的位置信息并且外包矩形面积最小的窗口元素作为目标窗口元素;以及突出显示目标窗口元素。
[0079]
在实际应用中,有的窗口应用程序为了防止窗口元素被抓取,因此在窗口元素上覆盖一层透明的窗口元素,使得无法定位到真正的窗口元素。为了解决该问题,本方案在响应于用户选择抓取的目标窗口元素的第二触发操作中,需要确定不包含第二触发操作的位置信息并且外包矩形面积最小的窗口元素作为目标窗口元素。在实际操作中,第二触发操作例如是鼠标点p移动到窗口元素。在这种情况下,使用深度优先的方法遍历树形结构,从根节点开始,判断每一层的节点的修正后的外包矩形rectadjust是否包含p点,如果包含则继续判断其下一层的子节点的rectadjust是否包含p点,不包含p点则停止,记录所有rectadjust包含p点,但其子节点不存在或不包含p的节点元素。遍历记录的所有元素,找出外包rect包含p点且rect面积最小的节点元素为该目标窗口元素。并且突出显示该目标窗
口元素,例如:修目标窗口元素的背景颜色进行突出显示,表示此元素是当前的可抓取的元素。从而通过这种方式,可以准确的定位到需要抓取的目标窗口元素。
[0080]
可选地,根据树形结构确定与目标窗口元素相关的窗口元素信息,包括:根据树形结构确定目标窗口元素的元素信息和/或确定目标窗口元素在树形结构的位置信息,其中位置信息为目标窗口元素在树形结构的路径。
[0081]
具体地,在根据树形结构确定与目标窗口元素相关的窗口元素信息的操作中,可以确定确定目标窗口元素的元素信息,例如窗口元素类型、文本信息等。并且还可以确定目标窗口元素在树形结构的位置信息(在树形结构中的路径信息)。在确定位置信息的操作中,首先确定待抓取的目标窗口元素,然后程序创建栈stack变量将当前节点(目标窗口程序对应的节点)压入栈中,节点元素使用pparent获取父节点将父节点压入栈中,再继续往上获取获取父节点的父节点压入栈中直到根节点也压入栈中,这样栈stack就表示了抓取元素在树形结构的位置信息,最终输出的即为该目标窗口元素在树形结构的路径。从而,最终抓取的窗口元素信息可以是窗口元素在树形结构中的路径,因此可以清楚地表示抓取的窗口元素在窗口应用程序的位置。
[0082]
参考图4和图5所示,以一个完整的实施例描述本方案的具体流程如下:
[0083]
对一个窗口程序而言,存在一个最顶层的窗口称为主窗口,主窗口内部包含大大小小的子窗口元素,子窗口元素又包含自己的子窗口元素。如果把主窗口看成根节点,子窗口元素看成子节点,那么一个窗口程序的所有窗口元素构成了一颗树形结构。每个节点内包含元素的信息,同时指向其父节点和其子节点。每个节点为以下结构体treenode
[0084]
struct treenode
[0085]
{
[0086]
info;
[0087]
rid;
[0088]
rect;
[0089]
rectadjust;
[0090]
pparent;
[0091]
pchildrenlist;
[0092]
};
[0093]
info包含窗口元素的元素类型,元素名称,文本信息等
[0094]
rid表示窗口元素的运行时id,窗口元素从创建到销毁过程中的唯一编号
[0095]
rect表示窗口元素的外包矩形,即窗口的左上角点的坐标(left,top)和右下角点的坐标(right,bottom)
[0096]
rectadjust表示修正后的窗口元素外包矩形
[0097]
pparent指向窗口元素的父节点
[0098]
pchildrenlist包含窗口元素所有的子节点指针。
[0099]
屏幕抓取主要抓取屏幕窗口元素的两个信息,一是定位被抓取窗口元素在树形结构中的位置,(这个里的定位包含两个过程中的定位,a.在屏幕抓取的阶段,鼠标在窗口元素上移动时,抓屏程序要通过计算得到并指示对应的窗口元素是候选的被抓取元素,b.当用户或程序确认当前的窗口是被抓取的窗口元素时,抓屏程序要计算一条从根节点到被抓
取窗口元素节点的通路,用作下一步rpa对窗口进行自动化操作时定位窗口元素的路径);二是获取被抓取元素的信息,如元素的类型,文本内容(treenode::info包含的信息)等。
[0100]
1)鼠标移动时获取其所在位置的主窗口句柄。开启线程,当鼠标移动时,向上逐级获取鼠标所在位置的窗口句柄直到获取到程序的最上层主窗口句柄hwnd_top。
[0101]
2)当鼠标进入新窗口时,对此窗口进行至顶向下的并行建树。主要包括以下步骤:
[0102]
a.在抓屏程序的内存中分配队列queue用于存放总的候选窗口元素的可访问对象和树形节点;分配maxthreadnum数量的线程;为每个线程分配队列queue_in用于存放当前线程候选窗口元素的可访问对象和树形节点,为每个线程分配queue_out由于存放当前线程生成的可访问对象和树形节点。在内存中分配一个map,使每个树形节点可以通过rid直接映射到。
[0103]
b.构建窗口元素树形结构的第1层,调用系统api使用主窗口句柄hwnd_top作为参数获取主窗口的可访问对象acc_obj_top,在内存中创建树形结构的根节点tree_node_top,通过acc_obj_top获取主窗口的元素信息存入根节点tree_node_top的info之中,获取主窗口的运行时ir存入rid中,获取窗口的外包矩形存入rect和rectadjust中,将pparent设为空。使rid映射到节点map[rid]=tree_node_top。将{acc_obj_top,tree_node_top}放入队列queue中。此时队列queue中只有一个元素,为其分配一个线程,直接将queue的元素放入线程的queue_in中,在线程中使用acc_obj_top获取主窗口的子窗口元素的可访问对象acc_obj_child,为所有子窗口对象创建树形节点tree_node_child,获取子窗口的info,rid,rect,rectadjust,将其pparent指向tree_node_top。将所有tree_node_child依次放入tree_node_top的pchildrenlist中。使rid映射到节点map[rid]=tree_node_child。同时将所有的{acc_obj_child,tree_node_child}放入queue中。线程执行完毕后,清空之前的队列queue in,将queue out的元素放入queue中。
[0104]
c.构建窗口元素树形结构的第2层,获取队列queue的元素个数num,那么avg=maxthreadnum/num(这里是整除),rem=maxthreadnum-avg*num,如果rem》0,那么1到rem的线程分配avg 1个queue元素,rem 1到maxthreadnum的线程分配avg个queue元素,如果rem==0,所有线程都分配avg个queue元素,每个线程分配到的queue元素放入自己的队列queue_in中。maxthreadnum个线程并发执行,在每个线程中依次取出queue_in中的元素,使用acc_obj_child获取其下一级子窗口元素的可访问对象acc_obj_grandchild,为所有子窗口对象创建树形节点tree_node_grandchild,获取下一级子窗口元素的info,rid,rect,rectadjust,将其pparent指向tree_node_child。将所有tree_node_grandchild依次放入tree_node_child的pchildrenlist中。使rid映射到节点map[rid]=tree_node_grandchild。同时将线程中所有的{acc_obj_grandchild,tree_node_grandchild}放入queue_out中。所有线程执行完毕后,清空之前的线程队列queue,将每个线程的queue_out中的元素依次放入queue中。
[0105]
d.循环构建窗口元素树形结构的第3层,第4层

一直执行到新生成的queue的个数为0。
[0106]
e.对树形结构每个节点的外包信息进行修正(使父节点修正后的外包刚好包含所有子节点的外包)。从根节点开始,父节点tree_node_parent对每个子节点tree_node_child递归的调用修正方法进行修正,每个子节点修正完之后,使用父节点的外包和子节点
修正后的外包进行比较,如果子节点修正后的外包没有被父节点的外包包含,那么父节点修正后的外包取子节点修正后的外包。
[0107]
tree_node_parent.rectadjust left=min(tree_node_parent.rectadjust.left,tree_node_child.rectadjust.left);
[0108]
tree_node_parent.rectadjust.top=min(tree_node_parent.rectadjust.top,tree_node_child.rectadjust.top);
[0109]
tree_node_parent.rectadjust.right=max(tree_node_parent.rectadjust.right,tree_node_child.rectadjust.right);
[0110]
tree_node_parent.rectadjust.bottom=max(tree_node_parent.rectadjust.bottom,tree_node_child.rectadjust.bottom);
[0111]
3)监听窗口元素的变化,进行局部的建树。开启线程监听窗口元素变化,此线程和建树的线程做线程互斥的操作。如果窗口元素发生变化,通过变化窗口的可访问对象acc_obj的rid,直接找到对应的树形结构节点tree_node=map[rid],使用tree_node的pparent找到其父节点tree_node_parent,清除父节点tree_node_parent及其子孙几点的数据,使用acc_obj对父节点对应的窗口元素及其所有子孙窗口元素,使用第2)部的方法重新建树(这是一个局部树),局部建树完毕后,用新生成的局部树替换之前父节点tree_node_parent处的树。
[0112]
4)显示鼠标所在位置的窗口元素。当鼠标点p移动到窗口元素时,使用深度优先的方法遍历树,从根节点开始,判断节点的rectadjust是否包含p点,如果包含则继续判断其子节点的rectadjust是否包含p点,不包含p点则停止,记录所有rectadjust包含p点,但其子节点不存在或不包含p的节点元素。遍历记录的所有元素,找出外包rect包含p点且rect面积最小的节点元素为待显示的节点,修改此元素的背景颜色,表示此元素是当前的可抓取的元素。
[0113]
5)鼠标移动到想要获取的元素上进行抓取。当用户或抓屏程序决定对当前可抓取元素进行抓取时,程序创建栈stack变量将当前节点压入栈中,节点元素使用pparent获取父节点将父节点压入栈中,再继续往上获取获取父节点的父节点压入栈中直到根节点也压入栈中,这样栈stack就表示了抓取元素在树形结构的位置信息,输出栈和抓取节点的相关信息。
[0114]
6)继续步骤1的操作直到屏幕抓取程序退出。
[0115]
windows系统的uia提供了api级别的窗口元素的获取,所有窗口元素的遍历等功能。但是uia技术将元素窗口的粒度划分的很细,大到程序的主窗口被视为uia的窗口元素,小到一个按钮也被视为一个uia元素,这样一个程序就包含非常多的窗口元素,特别对于ui比较复杂的程序或较复杂的网页。定位窗口元素往往会用到整个窗口元素树形结构的信息,而抓屏元素获取窗口元素的信息是通过进程间通信获取的,时间消耗较多,窗口元素一多,会导致抓屏程序运行十分缓慢,使抓屏程序不可用。此外,目前对于窗口元素数目适中的情况,直接使用uia的api,抓屏程序在和用户进行有交互的情况下,由于有一定的人机交互时间和人的心理承受的等待时间,抓屏程序勉强能满足用户需求。但随着抓屏程序越来越朝着与用户无交互、用户无感知的智能抓屏程序发展,对抓屏程序的时效性要求越来越强,因为抓屏的延时可能造成抓取用户操作的丢失。并且某些程序为了阻止使用uia的方式
抓屏会在程序的窗口元素上加上一层透明的窗口元素使uia的api无法真正定位到被捕获的元素。通过该方案可以解决复杂窗口程序的抓屏问题,并且能够提高抓屏程序的时效性,同时解决客户程序阻止抓屏的问题。
[0116]
参考图6a和图6b所示,以下结合代码的方式描述本方案的实现过程:
[0117]
1)启动抓屏程序,初始化uia。进行程序的初始化,hresult hr=coinitializeex(nullptr,coinit_multithreaded);hr=cocreateinstance(clsid_cuiautomation,nullptr,clsctx_inproc_server,iid_iuiautomation,reinterpret_cast《void**》(&m_pclientuia));启动线程,m_hthread=createthread(nullptr,0,&rpa_base_spy::_runspythread,this,create_suspended,nullptr);检测鼠标位置的变化point pt;getcursorpos(&pt);。
[0118]
2)鼠标移动到窗口元素上获取主窗口的句柄。获取窗口元素句柄hwnd hwnd=windowfrompoint(pt);获取主窗口句柄hwnd mainhwnd=getancestor(hwnd,ga_root);
[0119]
3)当鼠标移动到新的主窗口,对主窗口并行建树。对主窗口及其子孙元素进行至顶向下的并行建树。主要包括以下步骤:
[0120]
a.在抓屏程序的内存中分别分配用于存放总的候选窗口元素uia对象和树形节点的两个列表std::list《iuiautomationelement*》m_peles;std::list《uianode*》m_pnodes,分配maxthreadnum数量的线程m_hthreads[i]=createthread(nullptr,0,&ccustomuiatree::runthread,this,create_suspended,m_nthreadids i),为每个线程分配用于存放当前线程候选窗口元素uia对象和树形节点的两个列表std::list《iuiautomationelement*》
[0121]
m_pelesthread_in[maxthreadnum];std::list《uianode*》
[0122]
m_pnodesthread_in[maxthreadnum],为每个线程分配用于存放当前线程生成的uia对象和树形节点的两个列表std::list《iuiautomationelement*》
[0123]
m_pelesthread_out[maxthreadnum];std::list《uianode*》
[0124]
m_pnodesthread_out[maxthreadnum]。在内存中分配一个map,使每个树形节点可以通过rid直接映射到,std::map《cstring,uianode*》m_maptree。
[0125]
b.构建窗口元素树形结构的第1层,获取主窗口的uia对象hresult hr=m_pclientuia
[0126]-》elementfromhandlebuildcache(hwnd,pcacherequest,&m_ptopelement),在内存中创建树形结构的根节点,获取窗口元素信息、ridrect、rectadjust,pparent设为空:getuianodevaluefromcache(m_ptopnode,m_ptopelement),映射rid到节点m_maptree[m_ptopnode-》str_rid]=m_ptopnode。将m_peles、m_pnodes的元素分配放入m_pelesthread_in[0]、m_pnodesthread_in[0]中。开启一个线程,在线程中获取主窗口的子窗口元素的uia对象iuiautomationelementarray*pfound=nullptr;hresult hr=m_ptopelement-》findallbuildcache(treescope_children,lpthis-》m_pcondition,lpthis-》m_pcacherequest,&pfound),为所有子窗口对象创建树形节点,获取子窗口的信息、rid、rect、rectadjust,将其pparent指向m_ptopnode,将所有tree_node_child依次放入m_ptopnode的pchildrenlist中:getuianodevaluefromcache(tree_node_child,acc_obj_child)。使rid映射到节点m_maptree[tree_node_child-》str_rid]=tree_node_child。同
时将所有的acc_obj_child、tree_node_child放入中m_pelesthread_out[0]和m_pnodesthread_out[0]中。线程执行完毕后,清空m_peles、m_pnodes,将m_pelesthread_out[0]和m_pnodesthread_out[0]的元素放入m_peles和m_pnodes中。
[0127]
c.构建窗口元素树形结构的第2层,获取m_peles和m_pnodes元素个数num,那么avg=maxthreadnum/num(这里是整除),rem=maxthreadnum-avg*num,如果rem》0,那么1到rem的线程分别分配avg 1个m_peles和m_pnodes元素,rem 1到maxthreadnum的线程分别分配avg个m_peles和m_pnodes元素,如果rem==0,所有线程都分别分配avg个m_peles和m_pnodes元素,每个线程分配到的m_peles和m_pnodes元素放入对应第i个线程的m_pelesthread_in[i]、m_pnodesthread_in[i]中。maxthreadnum个线程并发执行,在每个线程中依次取出m_pelesthread_in[i]、m_pnodesthread_in[i]中的元素,对每个子窗口元素的uia对象m_pelesthread_in[i]获取其下一级子窗口元素的uia对象iuiautomationelementarray*pfound=nullptr;hresult hr=m_pnodesthread_in[i][k]-》findallbuildcache(treescope_children,lpthis-》m_pcondition,lpthis-》m_pcacherequest,&pfound),为所有子窗口对象创建树形节点,获取子窗口的信息、rid、rect、rectadjust,将其pparent指向m_pnodesthread_in[i][k],将所有新生成的节点依次放入m_pnodesthread_in[i][k]的pchildrenlist:getuianodevaluefromcache(tree_node_child,acc_obj_child)。使rid映射到节点m_maptree[tree_node_child-》str_rid]=tree_node_child。同时将所有的acc_obj_child、tree_node_child放入中m_pelesthread_out[i]和m_pnodesthread_out[i]中。线程执行完毕后,清空m_peles、m_pnodes,将对每个线程i将m_pelesthread_out[i]和m_pnodesthread_out[i]的元素放入m_peles和m_pnodes中。
[0128]
d.循环构建窗口元素树形结构的第3层,第4层

一直到线程执行完毕后新生成的m_peles和m_pnodes中元素个数为0。
[0129]
e.对树形结构每个节点的外包矩形信息进行修正(使父节点修正后的外包刚好包含所有子节点的外包)。从根节点m_ptopnode开始,父节点tree_node_parent对每个子节点tree_node_child递归的调用修正方法进行修正,每个子节点修正完之后,使用父节点的外包和子节点修正后的外包进行比较,如果子节点修正后的外包没有被父节点的外包包含,那么父节点修正后的外包取子节点修正后的外包。
[0130]
tree_node_parent.rectadjust left=min(tree_node_parent.rectadjust.left,tree_node_child.rectadjust.left);
[0131]
tree_node_parent.rectadjust.top=min(tree_node_parent.rectadjust.top,tree_node_child.rectadjust.top);
[0132]
tree_node_parent.rectadjust.right=max(tree_node_parent.rectadjust.right,tree_node_child.rectadjust.right);
[0133]
tree_node_parent.rectadjust.bottom=max(tree_node_parent.rectadjust.bottom,tree_node_child.rectadjust.bottom);
[0134]
4)设置主窗口变化的监听过程。开启线程一个新线程,对主窗口及其子孙窗口元素,监听其变化m_pclientuia-》addpropertychangedeventhandlernativearray(m_ptopelement,treescope_subtree,null,(iuiautomationpropertychangedeventhandl
er*)pehtemp,ppidproperties,sizeof(ppidproperties)/sizeof(ppidproperties[0]))。
[0135]
5)如果窗口元素发生变化,函数hresult stdmethodcalltype handlepropertychangedevent(iuiautomationelement*psender,propertyid propertyid,variant newvalue)将被回调。通过变化窗口的uia对象psender的rid对应的字符串strrid,直接找到对应的树形结构节点tree_node=m_maptree[strrid],使用tree_node的pparent找到其父节点tree_node_parent,清除父节点tree_node_parent及其子孙节点的数据,对父节点对应的窗口元素及其所有子孙窗口元素使用第2)步的方法重新建树(这是一个局部树),局部建树完毕后,用新生成的局部树替换之前父节点tree_node_parent处的树。
[0136]
6)计算鼠标位置的窗口元素,显示可抓取的窗口元素。当鼠标点p移动到窗口元素时,使用深度优先的方法遍历树,从根节点开始,判断节点的rectadjust是否包含p点,如果包含则继续判断其子节点的rectadjust是否包含p点,不包含p点则停止,记录所有rectadjust包含p点,但其子节点不存在或不包含p的节点元素:std::list《uianode*》pnodearr;bool br=_findchildnodeincludepoint(m_ptopnode,x,y,pnodearr)。遍历记录的所有元素,找出外包rect包含p点且rect面积最小的节点元素为待显示的节点:int mid_x=(rect.left rect.right)/2,mid_y=(rect.top rect.bottom)/2;int dis=(x-mid_x)*(x-mid_x) (y-mid_y)*(y-mid_y);if(min_area》area){pnode_sel=*it;min_area=area;dis_sel=dis;}修改此元素的背景颜色,表示此元素是当前的可抓取的元素。
[0137]
7)鼠标移动到想要获取的元素上进行抓取。监听鼠标左键,当鼠标左键单击时,程序创建栈stack变量将当前节点压入栈中,节点元素使用pparent获取父节点将父节点压入栈中,再继续往上获取获取父节点的父节点压入栈中直到根节点也压入栈中,这样栈stack就表示了抓取元素在树形结构的位置信息,输出栈和抓取节点的相关信息。
[0138]
8)继续步骤1的操作直到屏幕抓取程序退出。
[0139]
此外,参考图1所示,根据本实施例的第二个方面,提供了一种存储介质。所述存储介质包括存储的程序,其中,在所述程序运行时由处理器执行以上任意一项所述的方法。
[0140]
从而根据本实施例,在进行窗口元素的抓取的过程中,首先获取待抓取的目标窗口应用程序中的窗口元素,并在内存中根据窗口元素构建树形结构。在用户选择待抓取的窗口元素时,可以从该树形结构中获取抓取的窗口元素的窗口元素信息。因此,在用户操作选择窗口元素的同时可以同时抓取窗口元素信息,相当于用户操作窗口应用程序和抓取的过程在同一个进程中进行。与现有技术中抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信相比,本方案只需要在内存中的树形结构获取窗口信息,不需要进行跨进程操作。因此可以达到提升窗口元素抓取效率的技术效果。此外,树形结构是根据窗口元素而创建的,因此即使面对复杂的窗口元素,本方案也可以快速地进行窗口元素抓取。进而解决了现有技术中存在的抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信,尤其是面对复杂的程序窗口,会消耗大量时间,影响窗口元素抓取效率的技术问题。
[0141]
需要说明的是,对于前述的各方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本发明并不受所描述的动作顺序的限制,因为依据本发明,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作和模块并不一定是本发明
所必须的。
[0142]
通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到根据上述实施例的方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如rom/ram、磁碟、光盘)中,包括若干指令用以使得一台终端设备(可以是手机,计算机,服务器,或者网络设备等)执行本发明各个实施例所述的方法。
[0143]
实施例2
[0144]
图7示出了根据本实施例所述的窗口元素抓取装置700,该装置700与根据实施例1的第一个方面所述的方法相对应。参考图7所示,该装置700包括:窗口程序确定模块710,用于响应于用户选择程序的第一触发操作,确定目标窗口应用程序;树形结构构建模块720,用于获取目标窗口应用程序包含的窗口元素,并根据窗口元素在内存中构建树形结构,其中树形结构中的节点与窗口元素在目标窗口应用程序中的排列相关并且包含窗口元素的结构信息;以及窗口信息抓取模块730,用于响应于用户选择抓取的目标窗口元素的第二触发操作,根据树形结构确定与目标窗口元素相关的窗口元素信息。
[0145]
可选地,窗口元素包括主窗口元素和至少一级子窗口元素,并且树形结构构建模块720,包括:根节点构建子模块,用于根据主窗口元素在内存中构建树形结构的根节点;子节点构建子模块,用于根据至少一级子窗口元素在内存中构建树形结构的子节点;以及结构构建子模块,用于根据根节点和子节点以及主窗口元素和至少一级子窗口元素在目标窗口应用程序中的排列构建树形结构。
[0146]
可选地,窗口元素的结构信息包括以下至少一项:窗口元素的元素信息、运行id、外包矩形、父节点指针、子节点指针。
[0147]
可选地,根节点构建子模块,包括:根节点构建单元,用于在内存中构建树形结构的根节点;元素信息获取单元,用于获取与主窗口元素对应的句柄并根据句柄获取主窗口元素的可访问对象,根据可访问对象获取与主窗口元素对应的元素信息;第一确定单元,用于确定主窗口元素的运行id和外包矩形,并设置主窗口元素的父节点指针为空,设置主窗口元素的子节点指针为第一级子窗口元素;根节点结构信息确定单元,用于将与主窗口对应的元素信息、运行id、外包矩形、父节点指针为空、子节点指针为第一级子窗口元素作为根节点的结构信息。
[0148]
可选地,还包括:线程分配模块,用于为根节点分配一个线程并确定与线程对应的第一队列,并且子节点构建子模块,包括:一级子节点构建单元,用于通过线程,根据第一队列中的根节点的结构信息获取第一级子窗口元素的可访问对象,并根据第一级子窗口元素的可访问对象构建与第一级子窗口元素对应的子节点;一级子节点信息确定单元,用于确定第一级子窗口元素对应的元素信息、运行id、外包矩形,并设置第一级子窗口元素的父节点指针为根节点,设置第一级子窗口元素的的子节点指针为第二级子窗口元素,作为第一级子窗口元素的结构信息;一级子节点存储单元,用于将第一级子窗口元素的子节点的结构信息存储至内存中预先设置的第二队列,并计算第二队列中节点的数量;线程分配单元,用于根据预先设置的线程数量和第二队列中节点的数量,将第一级子窗口元素的子节点存储至每个线程对应的第一队列;二级子节点构建单元,用于通过每个线程,根据每个线程对
应的第一队列中的第一级子窗口元素的子节点的结构信息获取第二级子窗口元素的可访问对象,并根据第二级子窗口元素的可访问对象构建与第二级子窗口元素对应的子节点;二级子节点信息确定单元,用于确定第二级子窗口元素对应的元素信息、运行id、外包矩形,并设置第二级子窗口元素的父节点指针为第一级子窗口元素的子节点,设置第二级子窗口元素的的子节点指针为第三级子窗口元素,作为第二级子窗口元素的结构信息;以及二级子节点存储单元,用于将每个线程的第一队列中的第二级子窗口元素的子节点的结构信息存储至第二队列。
[0149]
可选地,装置700还包括:修正单元,用于根据主窗口元素和至少一级子窗口元素的外包矩形对树形结构进行修正操作。
[0150]
可选地,装置700还包括:监听模块,用于设置监听线程对窗口元素进行监听;以及局部构建模块,用于在窗口元素发生变化的情况下,根据发生变化的窗口元素对树形结构进行局部调整。
[0151]
可选地,窗口信息抓取模块730,包括:窗口确定子模块,用于对树形结构的节点进行遍历,确定不包含第二触发操作的位置信息并且外包矩形面积最小的窗口元素作为目标窗口元素;以及窗口显示子模块,用于突出显示目标窗口元素。
[0152]
可选地,窗口信息抓取模块730,包括:路径确定子模块,用于根据树形结构确定目标窗口元素的元素信息和/或确定目标窗口元素在树形结构的位置信息,其中位置信息为目标窗口元素在树形结构的路径。
[0153]
从而根据本实施例,在进行窗口元素的抓取的过程中,首先获取待抓取的目标窗口应用程序中的窗口元素,并在内存中根据窗口元素构建树形结构。在用户选择待抓取的窗口元素时,可以从该树形结构中获取抓取的窗口元素的窗口元素信息。因此,在用户操作选择窗口元素的同时可以同时抓取窗口元素信息,相当于用户操作窗口应用程序和抓取的过程在同一个进程中进行。与现有技术中抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信相比,本方案只需要在内存中的树形结构获取窗口信息,不需要进行跨进程操作。因此可以达到提升窗口元素抓取效率的技术效果。此外,树形结构是根据窗口元素而创建的,因此即使面对复杂的窗口元素,本方案也可以快速地进行窗口元素抓取。进而解决了现有技术中存在的抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信,尤其是面对复杂的程序窗口,会消耗大量时间,影响窗口元素抓取效率的技术问题。
[0154]
实施例3
[0155]
图8示出了根据本实施例所述的窗口元素抓取装置800,该装置800与根据实施例1的第一个方面所述的方法相对应。参考图8所示,该装置800包括:处理器810;以及存储器820,与处理器810连接,用于为处理器810提供处理以下处理步骤的指令:响应于用户选择程序的第一触发操作,确定目标窗口应用程序;获取目标窗口应用程序包含的窗口元素,并根据窗口元素在内存中构建树形结构,其中树形结构中的节点与窗口元素在目标窗口应用程序中的排列相关并且包含窗口元素的结构信息;以及响应于用户选择抓取的目标窗口元素的第二触发操作,根据树形结构确定与目标窗口元素相关的窗口元素信息。
[0156]
可选地,窗口元素包括主窗口元素和至少一级子窗口元素,并且根据窗口元素在内存中构建树形结构,包括:根据主窗口元素在内存中构建树形结构的根节点;根据至少一级子窗口元素在内存中构建树形结构的子节点;以及根据根节点和子节点以及主窗口元素
和至少一级子窗口元素在目标窗口应用程序中的排列构建树形结构。
[0157]
可选地,窗口元素的结构信息包括以下至少一项:窗口元素的元素信息、运行id、外包矩形、父节点指针、子节点指针。
[0158]
可选地,根据主窗口元素在内存中构建树形结构的根节点,包括:在内存中构建树形结构的根节点;获取与主窗口元素对应的句柄并根据句柄获取主窗口元素的可访问对象,根据可访问对象获取与主窗口元素对应的元素信息;确定主窗口元素的运行id和外包矩形,并设置主窗口元素的父节点指针为空,设置主窗口元素的子节点指针为第一级子窗口元素;将与主窗口对应的元素信息、运行id、外包矩形、父节点指针为空、子节点指针为第一级子窗口元素作为根节点的结构信息。
[0159]
可选地,存储器820还用于为处理器810提供处理以下处理步骤的指令:为根节点分配一个线程并确定与线程对应的第一队列,并且根据至少一级子窗口元素在内存中构建树形结构的子节点,包括:通过线程,根据第一队列中的根节点的结构信息获取第一级子窗口元素的可访问对象,并根据第一级子窗口元素的可访问对象构建与第一级子窗口元素对应的子节点;确定第一级子窗口元素对应的元素信息、运行id、外包矩形,并设置第一级子窗口元素的父节点指针为根节点,设置第一级子窗口元素的的子节点指针为第二级子窗口元素,作为第一级子窗口元素的结构信息;将第一级子窗口元素的子节点的结构信息存储至内存中预先设置的第二队列,并计算第二队列中节点的数量;根据预先设置的线程数量和第二队列中节点的数量,将第一级子窗口元素的子节点存储至每个线程对应的第一队列;通过每个线程,根据每个线程对应的第一队列中的第一级子窗口元素的子节点的结构信息获取第二级子窗口元素的可访问对象,并根据第二级子窗口元素的可访问对象构建与第二级子窗口元素对应的子节点;确定第二级子窗口元素对应的元素信息、运行id、外包矩形,并设置第二级子窗口元素的父节点指针为第一级子窗口元素的子节点,设置第二级子窗口元素的的子节点指针为第三级子窗口元素,作为第二级子窗口元素的结构信息;以及将每个线程的第一队列中的第二级子窗口元素的子节点的结构信息存储至第二队列。
[0160]
可选地,存储器820还用于为处理器810提供处理以下处理步骤的指令:根据主窗口元素和至少一级子窗口元素的外包矩形对树形结构进行修正操作。
[0161]
可选地,存储器820还用于为处理器810提供处理以下处理步骤的指令:设置监听线程对窗口元素进行监听;以及在窗口元素发生变化的情况下,根据发生变化的窗口元素对树形结构进行局部调整。
[0162]
可选地,响应于用户选择抓取的目标窗口元素的第二触发操作,还包括:对树形结构的节点进行遍历,确定不包含第二触发操作的位置信息并且外包矩形面积最小的窗口元素作为目标窗口元素;以及突出显示目标窗口元素。
[0163]
可选地,根据树形结构确定与目标窗口元素相关的窗口元素信息,包括:根据树形结构确定目标窗口元素的元素信息和/或确定目标窗口元素在树形结构的位置信息,其中位置信息为目标窗口元素在树形结构的路径。
[0164]
从而根据本实施例,在进行窗口元素的抓取的过程中,首先获取待抓取的目标窗口应用程序中的窗口元素,并在内存中根据窗口元素构建树形结构。在用户选择待抓取的窗口元素时,可以从该树形结构中获取抓取的窗口元素的窗口元素信息。因此,在用户操作选择窗口元素的同时可以同时抓取窗口元素信息,相当于用户操作窗口应用程序和抓取的
过程在同一个进程中进行。与现有技术中抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信相比,本方案只需要在内存中的树形结构获取窗口信息,不需要进行跨进程操作。因此可以达到提升窗口元素抓取效率的技术效果。此外,树形结构是根据窗口元素而创建的,因此即使面对复杂的窗口元素,本方案也可以快速地进行窗口元素抓取。进而解决了现有技术中存在的抓屏程序要获取其他程序窗口的信息需要进行跨进程的通信,尤其是面对复杂的程序窗口,会消耗大量时间,影响窗口元素抓取效率的技术问题。
[0165]
上述本发明实施例序号仅仅为了描述,不代表实施例的优劣。
[0166]
在本发明的上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述的部分,可以参见其他实施例的相关描述。
[0167]
在本技术所提供的几个实施例中,应该理解到,所揭露的技术内容,可通过其它的方式实现。其中,以上所描述的装置实施例仅仅是示意性的,例如所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,单元或模块的间接耦合或通信连接,可以是电性或其它的形式。
[0168]
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
[0169]
另外,在本发明各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。
[0170]
所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可为个人计算机、服务器或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:u盘、只读存储器(rom,read-only memory)、随机存取存储器(ram,random access memory)、移动硬盘、磁碟或者光盘等各种可以存储程序代码的介质。
[0171]
以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献