原文:[WPF] PerformClick ?

[WPF] PerformClick ? 

周银辉

WPF没有提供这个方法,还真是让人觉得有些讨厌啊。而关于这个嘛,Google中搜一下,一大堆,但一般是利用XXXAutomationPeer。

这个原本用于支持自动化测试的,被拿来干了这事,代码如下:

        public static void PerformClick(this Button button)
        {
            var peer =new ButtonAutomationPeer(button);

var invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;

if (invokeProv != null)
            {
                invokeProv.Invoke();
            }
        }

但很快地,你会发现去其依赖于具体的类:ButtonAutomationPeer, 所以WPF实现了一堆XXXAutomationPeer, 这多少让人觉得有些.... 比如“我想在任意UI元素上模拟下鼠标点击”,这种方法便不可行了,虽然有一堆Peer,再多也不是“任意”,那么用SendMessage吧,这才是王道,代码如下:

        public static void PerformClick(this UIElement element, Point point)
        {
            var window = Window.GetWindow(element);

if (window != null)
            {
                var windowHwnd = GetHwnd(window);

var locOfElement = element.TranslatePoint(new Point(0, 0), window);
                var pointToWindow = new Point(point.X + locOfElement.X, point.Y + locOfElement.Y);

Int32 lparam = MakeLong((int)pointToWindow.X, (int)pointToWindow.Y);

// WM_LBUTTONDOWN = 0x0201
                SendMessage(windowHwnd, WM_LBUTTONDOWN, 0, lparam);
                // WM_LBUTTONUP = 0x0202;
                SendMessage(windowHwnd, WM_LBUTTONUP, 0, lparam);
            }
        }

internal static int MakeLong(int lowWord, int highWord)
        {
            return (highWord << 16) | (lowWord & 0xffff);
        }

internal static IntPtr GetHwnd(this Window window)
        {
            var winHelper = new WindowInteropHelper(window);
            return winHelper.Handle;
        }

这个方法可以拓展到任意UI元素上,但很奇怪的是:居然不会引发Button的Click事件!从效果上看,的确点击了,因为焦点都转移上去了。那好吧,再用用下面的方法吧:反射,我比较喜欢这个方式:

        public static void PerformClick(this ButtonBase button)
        {
            var method = button.GetType().GetMethod("OnClick", 
                BindingFlags.NonPublic | BindingFlags.Instance);

if (method != null)
            {
                method.Invoke(button, null);
            }

//button.Focus();
        }

OK,总结一下:
第一种方法,依赖于具体的XXXPeer, 能力有限,不够灵活

第二种方法,较灵活,但由于SendMessage第一个参数要求传入hwnd,而WPF普通控件没有句柄,所以其依赖于窗口句柄,也就是该方法依赖窗口

第三种方法,我喜欢。有什么缺点吗?如果没有,为啥Google上的朋友们都用第一种方法?如果有,是啥?

-----------------------

[update]

最近看到一个开源项目, 专门模拟键盘和鼠标,非常棒: http://inputsimulator.codeplex.com/

源代码打包下载 : http://files.cnblogs.com/zhouyinhui/WindowsInput.zip

使用方法嘛,比如:

 var sim = new InputSimulator();
 sim.Mouse.LeftButtonDown();

[WPF] PerformClick ?相关推荐

  1. 分享Silverlight/WPF/Windows Phone一周学习导读(8月28日-9月3日)

    分享Silverlight/WPF/Windows Phone一周学习导读(8月28日-9月3日) 本周Silverlight学习资源更新: Silverlight动画 cutylongshen Si ...

  2. 分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日)

    分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日) 本周Silverlight学习资源更新 Silverlight 定位 niejunhua [学习 ...

  3. 基于 WPF + Modern UI 的 公司OA小助手 开发总结

    前言: 距离上一篇博客,整整一个月的时间了.人不能懒下来,必须有个阶段性的总结,算是对我这个阶段的一个反思.人只有在总结的过程中才会发现自己的不足. 公司每天都要在OA系统上上班点击签到,下班点击签退 ...

  4. 学习Modern UI for WPF

    这两天断断续续的学了学Modern UI for WPF 没啥学习笔记呵呵,来自大牛王春明的博客园 http://www.cnblogs.com/wangchunming/category/34288 ...

  5. [转][小结][三种方法]实现WPF不规则窗体

    实现WPF不规则窗体的三种常用的方法如下: 1.使用Blend等工具绘制一个不规则xaml,然后作为窗体的背景.这个可以参考xiaowei0705的这篇博文:WPF制作不规则的窗体 . 2.给wind ...

  6. WPF:跨应用程序会话保持和还原应用程序范围的属性

    所谓的wpf夸应用程序员会话保持和还原.其实就是将多个应用程序都用的资源保存到一个独立的文件存储系统中.这个应用程序退出的时候将数据写入文件中,其他应用程序使用的时候可以去读取这个文件 这个地方用到了 ...

  7. 关于WPF的ComboBox中Items太多而导致加载过慢的问题

                                         [WFP疑难]关于WPF的ComboBox中Items太多而导致加载过慢的问题                         ...

  8. datagrid底部显示水平滚动_DevExpress WPF v19.1:Data Grid/Tree List等控件功能增强

    行业领先的.NET界面控件DevExpress 日前正式发布v19.1版本,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WPF v19.1中新增的一些控件及部 ...

  9. WPF入门(三)-几何图形之不规则图形(PathGeometry) (2)

    WPF入门(三)->几何图形之不规则图形(PathGeometry) (2) 原文:WPF入门(三)->几何图形之不规则图形(PathGeometry) (2) 上一节我们介绍了PathG ...

最新文章

  1. 【转】sed 简明教程
  2. 他是世界上最杰出的程序员,一个月写了个操作系统,退休后去做飞行员!
  3. linux下mkdir头文件_整理Linux下gcc编译中关于头文件与库文件搜索路径相关问题
  4. 使用Github Pages建独立博客
  5. 通过CertEnroll在CA上(1创建证书请求2得到证书3安装证书)
  6. 洛谷 - P4568 [JLOI2011]飞行路线(分层图最短路)
  7. [2017.11.11特辑]以一个光棍节表白案例浅谈ECMAScript6模块化的使用方法
  8. oracle 执行java_oracle调用JAVA类的方法
  9. linux sudo命令全称,linux sudo命令的概念与使用
  10. windows进程/线程创建过程 --- windows操作系统学习
  11. 各种github浏览器无法访问问题
  12. 重装电脑麻烦,但值得
  13. [转](1条消息) 前端必知:针对高分辨率屏幕的样式优化(转载请删除括号里的内容)
  14. Cassandra 1
  15. python 树莓派摄像头_Python实现树莓派摄像头持续录像并传送到主机的步骤
  16. 天钥涉密计算机2019采购计划,关于编制《2019年度教学科研仪器设备采购计划表》的通知...
  17. 深度学习提高泛化能力的技术
  18. Swing是一把刀(转载)
  19. jQuery对于FireBox中的keypress与event
  20. crc32校验的c语言实现

热门文章

  1. IDA* AcWing 181. 回转游戏
  2. SylixOS周期定时抖动分析
  3. Fidller 抓包工具-手机代理抓包
  4. 远远超过了醉酒的尺度
  5. flutter 屏幕尺寸适配 字体大小适配,android面试常用算法
  6. 编程零基础,如何成为未来的无人车工程师?
  7. 在iphone上安装linux的一种方法(无需越狱)
  8. thinkphp漏洞浅析随笔
  9. [USACO2.1] 三值的排序 乱搞
  10. 安装Git遇到错误Unable to locate packag