本图其实很糟糕了,无法展示动态效果。
下面这段代码的作用仅仅是自动点击WPS工具栏的打印按钮。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Windows.Automation;
using System.Diagnostics;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport("user32.dll", EntryPoint = "mouse_event")]
private static extern void mouse_enent(int a, int b, int c, int d, int e);
[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
private static extern void SetCurSorPos(int a, int b);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
AutomationElement r = AutomationElement.RootElement;
AutomationElement w = eGet1(r, "KPromeMainWindow");
AutomationElement qweight = eGet1(w, "QWidget");
AutomationElement kPromeCentralArea = eGet0(qweight, "KPromeCentralArea");
AutomationElement kPromeWpsPage = eGet0(kPromeCentralArea, "KPromeWpsPage");
AutomationElement kPromeWindowContainerWidget = eGet1(kPromeWpsPage, "KPromeWindowContainerWidget");
AutomationElement kxWpsMainWindow = eGet1(kPromeWindowContainerWidget, "KxWpsMainWindow");
AutomationElement kxWpsRbTabWidget = eGet1(kxWpsMainWindow, "KxWpsRbTabWidget");
AutomationElement kRbQuickAccessContainer = eGet1(kxWpsRbTabWidget, "KRbQuickAccessContainer");
AutomationElement kRbQuickAccessToolbar = eGet1(kRbQuickAccessContainer, "KRbQuickAccessToolbar");
AutomationElement kRbQatCommandWidget = eGet1(kRbQuickAccessToolbar, "KRbQatCommandWidget");
// AutomationElement my = eGet1(kRbQatCommandWidget, "KToolButton");
Condition c = new PropertyCondition(AutomationElement.ClassNameProperty, "KToolButton");
AutomationElement my = kRbQatCommandWidget.FindAll(TreeScope.Descendants, c)[2];
System.Windows.Rect rect = (System.Windows.Rect)my.Current.BoundingRectangle;
int x = (int)rect.Location.X;
int y = (int)rect.Location.Y;
SetCurSorPos(x + 5, y + 5);
mouse_enent(0x2 + 0x4, 0, 0, 0, 0);
Thread.Sleep(1000);
}
private AutomationElement eGet0(AutomationElement e, string s) {
Condition c0 = new PropertyCondition(AutomationElement.NameProperty, s);
Condition c1 = new PropertyCondition(AutomationElement.AutomationIdProperty, s);
Condition c2 = new PropertyCondition(AutomationElement.ClassNameProperty, s);
Condition c3 = new PropertyCondition(AutomationElement.AutomationIdProperty, s);
Condition c4 = new PropertyCondition(AutomationElement.AccessKeyProperty, s);
Condition c5 = new PropertyCondition(AutomationElement.AcceleratorKeyProperty, s);
Condition c = new OrCondition (c0, c1, c2, c3, c4, c5);
return e.FindAll(TreeScope.Descendants, c)[0];
}
private AutomationElement eGet1(AutomationElement e, string s)
{
Condition c0 = new PropertyCondition(AutomationElement.NameProperty, s);
Condition c1 = new PropertyCondition(AutomationElement.AutomationIdProperty, s);
Condition c2 = new PropertyCondition(AutomationElement.ClassNameProperty, s);
Condition c3 = new PropertyCondition(AutomationElement.AutomationIdProperty, s);
Condition c4 = new PropertyCondition(AutomationElement.AccessKeyProperty, s);
Condition c5 = new PropertyCondition(AutomationElement.AcceleratorKeyProperty, s);
Condition c = new OrCondition(c0, c1, c2, c3, c4, c5);
return e.FindFirst(TreeScope.Children, c);
}
}
}
相信通过代码大家可以知道,automation类有很多局限性。比如很多控件本身明显可以接收鼠标点击的动作,但是对其调用invoke()方法后,都是没有反应的。于是笔者在无奈之下,只好先通过控件坐标的属性值,来定位控件的位置,然后再通过Windows api或者发送消息的方式,模拟鼠标单击动作。
需要注意的是,System.Windows.Rect类封装在WindowsBase.dll动态链接库中,因此需要手动加载该文件。而该文件在Microsoft发布的sdk中。请看下图:
再看下图: