说明:程序中有些自定义的控件类型在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的更多相关文章

  1. vuejs学习——vue+vuex+vue-router项目搭建(三)

    前言 vuejs学习——vue+vuex+vue-router项目搭建(一) vuejs学习——vue+vuex+vue-router项目搭建(二) 为什么用vuex:组件之间的作用域独立,而组件之间 ...

  2. 基于webpack的React项目搭建(三)

    前言 搭建好前文的开发环境,已经可以进行开发.然而实际的项目中,不同环境有着不同的构建需求.这里就将开发环境和生产环境的配置单独提取出来,并做一些简单的优化. 分离不同环境公有配置 不同环境虽然有不同 ...

  3. springmvc项目搭建三-添加前端框架

    这几年前端框架发展可以说非常迅猛了...实际项目中也用到了几个,easyui相对来讲,算是我第一个接触的前端框架了,用的时候感觉很方便,省了很多代码量,一个好的前端框架可以为你省去很多精力在前端布局上 ...

  4. IDEA项目搭建三——简单配置Maven使用国内及本地仓库

    大家在前面创建时发现Maven下载jar包的时候会很慢,我们又引入了自己的Maven,所以可以配置一下不让其去国外下载jar包,而使用国内的镜像站来加快下载速度 1.找到Maven所在文件夹 2.在c ...

  5. 我的第一个netcore2.2 api项目搭建(三)续

    上一章快速陈述了自定义验证功能添加的过程,我的第一个netcore2.2 api项目搭建(三) 但是并没有真正的去实现,这一章将要实现验证功能的添加. 这一章实现目标三:jwt认证授权添加 在netc ...

  6. 我的第一个netcore2.2 api项目搭建(三)

    上一章快速添加了swagger文档管理功能,我的第一个netcore2.2 api项目搭建(二) 这一章实现目标三:api添加身份验证功能 在实现该目标之前,先得理解netcore运行机制. 这是微软 ...

  7. Spring MVC 项目搭建 -6- spring security 使用自定义Filter实现验证扩展资源验证,使用数据库进行配置

    Spring MVC 项目搭建 -6- spring security使用自定义Filter实现验证扩展url验证,使用数据库进行配置 实现的主要流程 1.创建一个Filter 继承 Abstract ...

  8. Spring MVC 项目搭建 -4- spring security-添加自定义登录页面

    Spring MVC 项目搭建 -4- spring security-添加自定义登录页面 修改配置文件 <!--spring-sample-security.xml--> <!-- ...

  9. Spring Boot 项目学习 (三) Spring Boot + Redis 搭建

    0 引言 本文主要介绍 Spring Boot 中 Redis 的配置和基本使用. 1 配置 Redis 1. 修改pom.xml,添加Redis依赖 <!-- Spring Boot Redi ...

随机推荐

  1. stringstream流分割空格

    1205 单词翻转 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze       题目描述 Description 给出一个英语句子,希望你把句子里的单词顺序都翻转 ...

  2. 【题解】Intervals

    题目大意   有\(n\)个区间(\(1 \leq n \leq 200\)),第\(i\)个区间覆盖\((a_{i}, b_{i})\)且有权值\(w_{i}\)(\(1 \leq a_{i} &l ...

  3. 小Z的袜子(题解)(莫队)

    小Z的袜子(题解)(莫队) Junlier良心莫队 题目 luoguP1494 [国家集训队]小Z的袜子 code #include<bits/stdc++.h> #define lst ...

  4. break和continue能否跳出函数

    int func() { printf("In func, before continue.\n"); // continue; break; printf("In fu ...

  5. 68.Palindromic Substrings(回文字符串的个数)

    Level:   Medium 题目描述: Given a string, your task is to count how many palindromic substrings in this ...

  6. C#面试 笔试题 五

    1.什么是受管制的代码? 答:unsafe:非托管代码.不经过CLR运行. 2.net Remoting 的工作原理是什么? 答:服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置. ...

  7. IntelliJ IDEA 中 Ctrl+Alt+Left/Right 失效

    开发工具:Idea OS:Window 7 在idea中使用ctrl+b跟踪进入函数之后,每次返回都不知道用什么快捷键,在idea中使用ctrl+alt+方向键首先会出现与win7屏幕方向的快捷键冲突 ...

  8. 240-4C6678_K7_DDR3_VPX高速信号处理板

    4C6678_K7_DDR3_VPX高速信号处理板 4C6678_K7_DDR3_VPX板为基于TI   多核DSP TMS320C6678的通用处理板卡.板卡满足OpenVPX平台标准,可为雷达.电 ...

  9. 创建 OpenStack云主机

    创建过程 创建虚拟网络 创建m1.nano规格的主机(相等于定义虚拟机的硬件配置) 生成一个密钥对(openstack的原理是不使用密码连接,而是使用密钥对进行连接) 增加安全组规则(用iptable ...

  10. CSS实现三级菜单[转]

    头部导航条布局 html代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...