WPF中监听剪贴板存在的Bug:OpenClipboard HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))错误

1.WPF监听剪贴板的方法

WPF的方法和WinForm略有不同,具体步骤如下:

(1)首先定义消息钩子

        #region 消息钩子预定义参数private const int WM_DRAWCLIPBOARD = 0x308;private const int WM_CHANGECBCHAIN = 0x30D;private IntPtr mNextClipBoardViewerHWnd;[DllImport("user32.dll", CharSet = CharSet.Auto)]static public extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);[DllImport("user32.dll", CharSet = CharSet.Auto)]static public extern bool ChangeClipboardChain(IntPtr HWnd, IntPtr HWndNext);[DllImport("user32.dll", CharSet = CharSet.Auto)]static public extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);#endregion

(2)重写OnSourceInitialized

        protected override void OnSourceInitialized(EventArgs e){base.OnSourceInitialized(e);HwndSource source = PresentationSource.FromVisual(this) as HwndSource;//挂消息钩子mNextClipBoardViewerHWnd = SetClipboardViewer(source.Handle);source.AddHook(WndProc);}

(3)处理消息WM_DRAWCLIPBOARD 和WM_CHANGECBCHAIN

        /// <summary>///  参考:https://blog.csdn.net/xlm289348/article/details/8050957///  MSG=0x308无法收到消息,原因是0x308是在剪贴板发生变化时将消息发送到监听列表中的第一个窗口///  所有这里要收到0x308必须将窗口放到监听列表里///  即在OnSourceInitialized(EventArgs e) 中调用SetClipboardView/// </summary>/// <param name="hwnd"></param>/// <param name="msg"></param>/// <param name="wParam"></param>/// <param name="lParam"></param>/// <param name="handled"></param>/// <returns></returns>IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){switch (msg){case WM_DRAWCLIPBOARD:{SendMessage(mNextClipBoardViewerHWnd, msg, wParam.ToInt32(), lParam.ToInt32());//文本内容检测if (System.Windows.Clipboard.ContainsText()){//System.Windows.Clipboard.GetText()此处有Bug//String ct = System.Windows.Clipboard.GetText();String ct = getClipboardText();                   //做进一步操作}}break;case WM_CHANGECBCHAIN:{if (wParam == (IntPtr)mNextClipBoardViewerHWnd){mNextClipBoardViewerHWnd = lParam;}else{SendMessage(mNextClipBoardViewerHWnd, msg, wParam.ToInt32(), lParam.ToInt32());}}break;default:break;}return IntPtr.Zero;}

(4)退出程序时注意移除钓子

        private void ModernWindow_Closing(object sender, EventArgs e){HwndSource source = PresentationSource.FromVisual(this) as HwndSource;//移除消息钩子ChangeClipboardChain(source.Handle, mNextClipBoardViewerHWnd);source.RemoveHook(WndProc);}

2.WPF在读取剪贴板内容时报OpenClipboard HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))错误

如果直接通过Clipboard.GetText()获取剪贴板上的文本时,如果剪贴板被占用(每次只能一个程序读取),则会报OpenClipboard HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))错误,这是个随机错误,所以比较隐蔽,而且在WinForm中没有这个问题。

网上搜到有三种方法,这里我就只把我的解决方法贴在这里,因为剪贴板被其它程序占用是个小概率事件且占用时间通常很短,每次读取时多试几次就可以了。

        private String getClipboardText(){for (int i = 0; i < 200; i++){try{return System.Windows.Clipboard.GetText();}catch{System.Threading.Thread.Sleep(10);//这句加不加都没关系}}return String.Empty;}

WPF中监听剪贴板存在的Bug:OpenClipboard HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))错误相关推荐

  1. Android 监听 Android中监听系统网络连接打开或者关闭的实现代码

    本篇文章对Android中监听系统网络连接打开或者关闭的实现用实例进行了介绍.需要的朋友参考下 很简单,所以直接看代码 复制代码 代码如下: package xxx; import android.c ...

  2. java 多个监听_java中监听一个客户端怎么做?监听多个怎么做?

    随着时代的不断进步与发展,人们对于科学技术的使用也越来越普遍化.人们都开始自己学习编程语言以更好的适应时代的发展.今天就来为大家介绍一下,java中监听一个客户端怎么做?监听多个怎么做?一起来看看吧. ...

  3. vue输入框输入触发事件_.vue文件中监听input输入事件oninput详解

    .vue文件其实是一个组件,关于它的说明我之前也写过一篇文章,地址:.vue文件,今天这篇文章要讲的是.vue文件中监听input的输入值变化事件.需求是这页面中,改变input的值,就调用一个事件, ...

  4. android 控件监听方法是,Android | Android中监听Button的实现

    Android中监听Button的实现 单按钮监听 2018-04-27_061911.jpg 1.在按钮所属的父Activity里,创建按钮变量 private Button mBtnTextVie ...

  5. Android中监听电源键长按、Home键、Home键长按

    Android中监听"电源键长按"."Home键"."Home键长按" 这几个"按钮"的触发,都会产生一个Action ...

  6. Android中监听Home键的4种方法总结

    本文主要介绍了Android中监听Home键的4种方法总结,主要讲解了onSaveInstanceState方法.onUserLeaveHint方法.ACTION_CLOSE_SYSTEM_DIALO ...

  7. vue 中监听并设置scrollTop

    vue 中监听并设置scrollTop 问题描述: 目前在做一个项目,父子组件以及兄弟组件中数据调用比较频繁.但是鉴于项目没那么大,就没有使用vuex.直接使用了this.$emit来给父级组件传递参 ...

  8. Vue中监听页面刷新和关闭beforeunload事件

    代码 在methods中定义事件方法,在mounted 生命周期钩子中绑定事件, 在destoryed钩子中卸载事件 mounted () {window.addEventListener('befo ...

  9. iphone开发在应用中监听(判断)来电状态-接听-拒接

    phone开发在应用中监听(判断)来电状态-接听-拒接-CoreTelephony   zxwo0o IOS,iphone,互联网络 CoreTelephony, CTCallCenter   0   ...

  10. JavaScript 中监听 div 高度的变化

    实现功能描述: 基于 vue + elementUI,在 Dialog 中有一个 Select 选择器,当 Select 的下拉列表显示时,要求高度能够撑开 Dialog.实现效果如图: 实现 实际项 ...

最新文章

  1. C#命名规则、开发习惯和风格
  2. 小程序获取用户的操作轨迹日志
  3. maven 引入本地 jar
  4. C# 关闭正在执行的文件
  5. 转:WinForm程序中两份mdf文件问题的解决方法
  6. 一个老忘且非常有用的jquery动画方法 网页上卷
  7. 对XMLHttpRequest异步请求的面向对象封装
  8. Python 办公自动化:让你的工作效率翻番
  9. socket只能连接本地mysql_MySQL本地用IP登陆而非socket
  10. Django实现发邮件
  11. 最美旗舰机型又将易主?三星Galaxy S11高清渲染图曝光
  12. [笔记]TB-6S-LX150T-IMG2_HWUserManual_1.02e实例讲解
  13. java笔试题_公司真题 | 用友2018秋招Java笔试题(四)
  14. Sql Server CHAR类型
  15. dom4j的操作(增删改查)
  16. stm32码盘传感器_STM32电机测速(正交或者霍尔编码器)
  17. java hashset retain_Java HashSet retainAll()用法及代码示例
  18. ClickHouse函数介绍
  19. ESD元器件防护原理及选型
  20. 江苏大学毕业设计TEX排版(三)

热门文章

  1. (六)SSO之CAS框架扩展 改动CAS源代码实现与ESS动态password验证对接
  2. Java中处理tiff文件
  3. python 保存为tiff文件, 图像转tiff, tif文件添加投影
  4. 食品行业十大进销存软件功能大对比,我教你怎么选
  5. java初级程序员学习思路
  6. 台式计算机usb口不识别鼠标,答疑解惑:USB鼠标无法被电脑识别怎么办
  7. win10局域网加入工作组计算机,Win10专业版加入局域网工作组的技巧
  8. ecosys m5021cdn_京瓷ECOSYS M5021cdn驱动
  9. 一个3D引擎Demo 源码
  10. 两根硬铜线并线接插座_两根硬铜线正确接法