2015.4.25利用UIAutomation 替代API函数,解决了ListView无法读数据的难题,顺便实现了鼠标模拟滚轮
UIAutomation比API的优点是类似于消息处理机制,而不是主要靠模拟鼠标键盘发送消息
首先添加引用UIAutomationClient和UIAutomationTypes,在安装.net3.5的电脑上可用。低版本的VS可以直接引用dll。
using System.Windows.Automation;
//先用传统方法找到hwnd,用UI也能找到,新项目应统一到UI
IntPtr leftview = API.FindWindowEx(wd0, 0, "SysListView32", "CFQS");
IntPtr rightview = API.FindWindowEx(wd0, 0, "SysListView32", "List2");
if (leftview == IntPtr.Zero || rightview == IntPtr.Zero) return;
AutomationElement el = AutomationElement.FromHandle(leftview); //左侧view
AutomationElement er = AutomationElement.FromHandle(rightview); //右侧view
PropertyCondition condition_bk = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem); //查找子窗口的条件 同样是ListViewItem,对左边的只能用ControlType.DataItem,右边的用ControlType.ListItem
AutomationElementCollection bks = el.FindAll(TreeScope.Children, condition_bk); //获得所有满足条件子窗口的集合
//还有一种遍历子窗口的方法 用TreeWalker
//AutomationElement el = AutomationElement.FromHandle(leftview);
//TreeWalker walker = TreeWalker.ContentViewWalker;
//for (AutomationElement child = walker.GetFirstChild(el); child != null; child = walker.GetNextSibling(child)) //{
// string name=child.Current.Name
//}
API.mouse_event((int)(MouseEventFlags.Wheel | MouseEventFlags.Absolute), 0, 0, -380, IntPtr.Zero); //让滚动条下滚,仅为视觉效果,不要也行
SelectionItemPattern selPattern = (SelectionItemPattern)item.GetCurrentPattern(SelectionItemPattern.Pattern);
selPattern.Select(); //选择该板块 //实现ListView内部元素选择
// item.Current.Name 可取出Listview内部元素内容
//PropertyCondition condition = new PropertyCondition(AutomationElement.IsEnabledProperty, true); //可通用所有非禁用项作为类型
2016.9.2补充
往控件中输入内容
AutomationElement element = AutomationElement.FromHandle(edbox);
object valuePattern = null;
if (element.TryGetCurrentPattern(ValuePattern.Pattern, out valuePattern)) //是否支持直接写入
{
// Set focus for input functionality and begin.
element.SetFocus();
((ValuePattern)valuePattern).SetValue(fullpath);
}
else //否则模拟键入
{
// Set focus for input functionality and begin.
element.SetFocus();
// Pause before sending keyboard input.
Thread.Sleep(100);
// Delete existing content in the control and insert new content.
SendKeys.SendWait("^{HOME}"); // Move to start of control
SendKeys.SendWait("^+{END}"); // Select everything
SendKeys.SendWait("{DEL}"); // Delete selection
SendKeys.SendWait(fullpath);
}