项目搭建(三):自定义DLL
说明:程序中有些自定义的控件类型在TestStack.White框架中没有涉及,需要引入自定义的DLL,通过鼠标点击事件处理
使用:将自定义的ClassLibrary2.dll拷贝到项目/bin/debug目录下,项目添加引用选择dll。
--该dll定义了Control Patterns为空的点击事件类BaseClass;
--该dll定义了查找控件属性类PropertyConditions;
一、 C#生成DLL文件
1. 在VS2015,文件->新建项目->项目类型visual C#->类库(注意必须是类库)
--即新建一个由纯.cs 类库文件组成的程序集。
2. 编写代码 详细代码见附录:
-文件名:Class1.cs
-namespace:BaseTest
-类名:BaseClass
3. 生成->生成[解决方案名]
这样你的\Projects\ClassLibrary2\ClassLibrary2\bin\Debug文件夹或者\Projects\ClassLibrary2\ClassLibrary2\obj\Debug文件夹里便会自动生成 dll文件,该文件名称与项目名称一致,即为ClassLibrary2.dll。
二、引用DLL文件
a. 首先把dll文件放到应用程序...\bin\Debug\下;
b. 然后在解决方案中添加引用:右键鼠标-->添加引用-->浏览-->选择dll放置路径后点击“确定”。
c. 在应用文件头处使用using BaseTest;
调用 dll中方法时使用BaseClass.方法名
三、附录:自定义类库代码
using System;
using System.Text;
using System.Windows;
using System.Windows.Automation;
using System.Diagnostics;
using System.Runtime.InteropServices; namespace BaseTest
{
public class BaseClass
{
#region ClickMouse
#region Import DLL /// <summary>
/// Add mouse move event
/// </summary>
/// <param name="x">Move to specify x coordinate</param>
/// <param name="y">Move to specify y coordinate</param>
/// <returns></returns> [DllImport("user32.dll")] extern static bool SetCursorPos(int x, int y); /// <summary>
/// Mouse click event
/// </summary>
/// <param name="mouseEventFlag">MouseEventFlag </param>
/// <param name="incrementX">X coordinate</param>
/// <param name="incrementY">Y coordinate</param>
/// <param name="data"></param>
/// <param name="extraInfo"></param> [DllImport("user32.dll")] extern static void mouse_event(int mouseEventFlag, int incrementX, int incrementY, uint data, UIntPtr extraInfo);
const int MOUSEEVENTF_MOVE = 0x0001;
const int MOUSEEVENTF_LEFTDOWN = 0x0002;
const int MOUSEEVENTF_LEFTUP = 0x0004;
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
const int MOUSEEVENTF_RIGHTUP = 0x0010;
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
const int MOUSEEVENTF_MIDDLEUP = 0x0040;
const int MOUSEEVENTF_ABSOLUTE = 0x8000; #endregion public static void ClickLeftMouse(int processId, string automationId)
{
AutomationElement element = FindElementById(processId, automationId);
if (element == null)
{
throw new NullReferenceException(string.Format("Element with AutomationId '{0}' and Name '{1}' can not be find.",
element.Current.AutomationId, element.Current.Name));
}
Rect rect = element.Current.BoundingRectangle;
int IncrementX = (int)(rect.Left + rect.Width / );
int IncrementY = (int)(rect.Top + rect.Height / );
//Make the cursor position to the element.
SetCursorPos(IncrementX, IncrementY);
//Make the left mouse down and up.
mouse_event(MOUSEEVENTF_LEFTDOWN, IncrementX, IncrementY, , UIntPtr.Zero);
mouse_event(MOUSEEVENTF_LEFTUP, IncrementX, IncrementY, , UIntPtr.Zero);
}
#endregion public static void ClickLeftMouseByName(int processId, string name)
{
AutomationElement element = FindElementByName(processId, name);
if (element == null)
{
throw new NullReferenceException(string.Format("Element with Name '{0}' and Name '{1}' can not be find.",
element.Current.Name, element.Current.Name));
}
Rect rect = element.Current.BoundingRectangle;
int IncrementX = (int)(rect.Left + rect.Width / );
int IncrementY = (int)(rect.Top + rect.Height / );
//Make the cursor position to the element.
SetCursorPos(IncrementX, IncrementY);
//Make the left mouse down and up.
mouse_event(MOUSEEVENTF_LEFTDOWN, IncrementX, IncrementY, , UIntPtr.Zero);
mouse_event(MOUSEEVENTF_LEFTUP, IncrementX, IncrementY, , UIntPtr.Zero);
} /// <summary>
/// Get the automation elemention of current form.
/// </summary>
/// <param name="processId">Process Id</param>
/// <returns>Target element</returns>
public static AutomationElement FindWindowByProcessId(int processId)
{
AutomationElement targetWindow = null;
int count = ;
try
{
Process p = Process.GetProcessById(processId);
targetWindow = AutomationElement.FromHandle(p.MainWindowHandle);
return targetWindow;
}
catch (Exception ex)
{
count++;
StringBuilder sb = new StringBuilder();
string message = sb.AppendLine(string.Format("Target window is not existing.try #{0}", count)).ToString();
if (count > )
{
throw new InvalidProgramException(message, ex);
}
else
{
return FindWindowByProcessId(processId);
}
}
} // Get the automation element by automation Id.
public static AutomationElement FindElementById(int processId, string automationId) {
AutomationElement aeForm = FindWindowByProcessId(processId);
AutomationElement tarFindElement = aeForm.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.AutomationIdProperty, automationId));
return tarFindElement;
} // Get the automation element by Name.
public static AutomationElement FindElementByName(int processId, string name) {
AutomationElement aeForm = FindWindowByProcessId(processId);
AutomationElement tarFindElement = aeForm.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.NameProperty, name));
return tarFindElement;
} // get the button element and click
public static void ClickButtonById(int processId,string buttonId)
{
AutomationElement element = FindElementById(processId,buttonId);
if (element == null)
{
throw new NullReferenceException(string.Format("Element with AutomationId '{0}' can not be find.", element.Current.Name));
}
InvokePattern currentPattern = GetInvokePattern(element);
currentPattern.Invoke();
} #region InvokePattern helper
/// <summary>
/// Get InvokePattern
/// </summary>
/// <param name="element">AutomationElement instance</param>
/// <returns>InvokePattern instance</returns>
public static InvokePattern GetInvokePattern(AutomationElement element)
{
object currentPattern;
if (!element.TryGetCurrentPattern(InvokePattern.Pattern, out currentPattern))
{
throw new Exception(string.Format("Element with AutomationId '{0}' and Name '{1}' does not support the InvokePattern.",
element.Current.AutomationId, element.Current.Name));
}
return currentPattern as InvokePattern;
} #endregion
}
}
项目搭建(三):自定义DLL的更多相关文章
- vuejs学习——vue+vuex+vue-router项目搭建(三)
前言 vuejs学习——vue+vuex+vue-router项目搭建(一) vuejs学习——vue+vuex+vue-router项目搭建(二) 为什么用vuex:组件之间的作用域独立,而组件之间 ...
- 基于webpack的React项目搭建(三)
前言 搭建好前文的开发环境,已经可以进行开发.然而实际的项目中,不同环境有着不同的构建需求.这里就将开发环境和生产环境的配置单独提取出来,并做一些简单的优化. 分离不同环境公有配置 不同环境虽然有不同 ...
- springmvc项目搭建三-添加前端框架
这几年前端框架发展可以说非常迅猛了...实际项目中也用到了几个,easyui相对来讲,算是我第一个接触的前端框架了,用的时候感觉很方便,省了很多代码量,一个好的前端框架可以为你省去很多精力在前端布局上 ...
- IDEA项目搭建三——简单配置Maven使用国内及本地仓库
大家在前面创建时发现Maven下载jar包的时候会很慢,我们又引入了自己的Maven,所以可以配置一下不让其去国外下载jar包,而使用国内的镜像站来加快下载速度 1.找到Maven所在文件夹 2.在c ...
- 我的第一个netcore2.2 api项目搭建(三)续
上一章快速陈述了自定义验证功能添加的过程,我的第一个netcore2.2 api项目搭建(三) 但是并没有真正的去实现,这一章将要实现验证功能的添加. 这一章实现目标三:jwt认证授权添加 在netc ...
- 我的第一个netcore2.2 api项目搭建(三)
上一章快速添加了swagger文档管理功能,我的第一个netcore2.2 api项目搭建(二) 这一章实现目标三:api添加身份验证功能 在实现该目标之前,先得理解netcore运行机制. 这是微软 ...
- Spring MVC 项目搭建 -6- spring security 使用自定义Filter实现验证扩展资源验证,使用数据库进行配置
Spring MVC 项目搭建 -6- spring security使用自定义Filter实现验证扩展url验证,使用数据库进行配置 实现的主要流程 1.创建一个Filter 继承 Abstract ...
- Spring MVC 项目搭建 -4- spring security-添加自定义登录页面
Spring MVC 项目搭建 -4- spring security-添加自定义登录页面 修改配置文件 <!--spring-sample-security.xml--> <!-- ...
- Spring Boot 项目学习 (三) Spring Boot + Redis 搭建
0 引言 本文主要介绍 Spring Boot 中 Redis 的配置和基本使用. 1 配置 Redis 1. 修改pom.xml,添加Redis依赖 <!-- Spring Boot Redi ...
随机推荐
- C#=>递归反转栈
原理,递归反转栈 using System; using System.Collections.Generic; using System.Linq; using System.Threading.T ...
- HDFS-NameNode和SeconddaryNode
一.NN和2N的工作机制 一.概述 一.概述 一.概述 一.概述 一.概述 一.概述 一.概述
- [fw]拦截系统调用
今天在ubuntu中玩了下“拦截系统调用”,记录下自己对整个实现的理解. 原理 在linux kernel中,系统调用都放在一个叫做“sys_call_table”的分配表里面,在进入一个系统调用的最 ...
- php数组转换字符串及复选框如何勾选中
php数组转换字符串及复选框如何勾选中,应用到函数 implode explode 复选框被选中后如何保存数据,表单提交过来为数组,要转换字符串 用到函数implode if(!empty($_PO ...
- ASP.NET CORE 2.0 模板 (Admin LTE)
原文:https://www.jianshu.com/p/4916f380be66?utm_campaign=hugo&utm_medium=reader_share&utm_cont ...
- JS 逻辑非!简单总结
!"" true!"aaa" false""==false true ...
- github命令大全
github是一种开源的版本控制工具,现在已经得到很多人的应用.所以想介绍一下github的一些使用. github安装 github提供了桌面客户端,我们也可以通过命令行的方式来进行控制. wind ...
- js字符串相关方法
<script> // 使用索引位置来访问字符串中的每个字符: var carname = 'Volvo XC60'; var character = carname[7]; consol ...
- 一、AJAX
一. (function ($) { //1.得到$.ajax的对象 var _ajax = $.ajax; $.ajax = function (options) { //2.每次调用发送ajax请 ...
- 毕设问题(2) fastjson 的过滤器使用(SSH hibernate)以及转换对象出现 $ref
毕业设计,用SSH框架,但是想要做出异步请求数据的效果,使用了ajax方式,其中数据传递的类型为json.ajax使用用的jQuery的ajax.其实struts里也支持ajax功能,但是我觉得用太多 ...