【WPF】学习笔记(二)——依旧是一个电子签名板
这篇博客呢,主要谈谈在实现电子签名功能中踩过的几个坑:1.System.BadImageFormatException异常;2.无法加载DLL“###.dll”,: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E);3.wpf获取控件句柄。
如果你想了解如何在wpf中使用InkCanvas实现一个类似于签名板(涂鸦板系列)的功能,请参考我的上一篇博客。
再扯点题外话,写这篇博客的很大一部分原因是InkCanvas版本的签名板被否决了。究其原因呢,是这个签名板将用于触摸屏上的用户签名,而InkCanvas版本在触摸屏上手写签名的体验可以用糟糕来形容。所以呢,最终采用了另一个解决方案:调用一个C++的dll(这个dll是公司提供的,而且有WinForm版的Demo,我只需要正确的“搬砖”就好了),通过电子签名笔来完成签名。
闲话扯完了,现在我们来聊聊那几个问题:
1.System.BadImageFormatException异常

这个异常是我在尝试编译WinForm版Demo的时候触发的,网上搜索了一下,在一篇博客中找到了原因——目标程序的目标平台与某一依赖项的目标编译平台不一致。于是我将相关工程的目标平台都更改为x86,问题就解决了。下方提供一个修改目标平台的示例:


大致修改过程:在工程上右键 => 属性 => 编译 => 目标平台
2.无法加载DLL“###.dll”,: 找不到指定的模块
隐约记得很久以前遇上过这个问题,但忘了具体怎么处理的了。所以上网搜索了一下,关于这个问题的帖子不少,但都大同小异……大体上都说将dll手动拷贝到项目文件夹中bin目录下;将dll拷贝到system32目录下;还有一个感觉看起来十分高大上的解决方法,个人就没什么兴趣看了。拜托!在我的记忆中,这不应该是件很麻烦的事情啊,而且现在的VS这么强大,还需要手动去搞这种事情??最终决定自己摸索,也终于找到了解决方法。


相信到这里各位都看出问题了吧——dll的Copy to Output Directory(复制到输出目录)这一项默认选的是永不复制!!搞骚,吓得我赶紧修改成Copy if newer(如果更新就会重新复制一份到输出目录,如果你想选始终复制Copy always我也不拦着),然后这个问题就没有然后了。当然,有可能我遇上的问题比较简单,这个解决方案可能对某些情况不适用,各位可以在博客下方留言,我们一起讨论。
3. wpf获取控件句柄
由于在调用C++的dll完成签名板功能时,需要把签名板的句柄作为参数传递过去,所以我在此把这个地方拿出来谈一谈。
网上关于wpf获取控件句柄的帖子也不少,但恕我直言,大都是在扯淡~
比如说下方截图:

容我先按照这个方法测试一票:

我们发现,这两个方法拿到的句柄一毛一样……
听老司机说,wpf的控件是画出来的,不会为每个控件分配句柄,所以通过这个方法拿到的所谓的控件的句柄,实际上是整个窗体的句柄。而我们的需求是要切切实实的拿到对应控件的句柄,所以,就只能想办法借助winform了。
接下来,我们来看看具体步骤:
1)添加两个引用(System.Windows.Forms 和 WindowsFormsIntegration)


为了相对快速找到这两个库,我搜索了关键字“windows”
2)XAML
A.引入命名空间
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
B.控件调用
<wfi:WindowsFormsHost Width="500" Height="240" Background="White">
<wf:Panel x:Name="panelSignature"/>
</wfi:WindowsFormsHost>
C.说明
a.有细心的童鞋会发现,WindowsFormHost的前方不必使用WindowsFormsIntegration对应的名称(我给的名称是wfi,各位请随意)进行限制,XAML中只导入System.Windows.Forms的命名空间也是可以的,但为了更清楚WindowsFormHost的来历(在哪个程序集的哪个命名空间下),我比较推荐将命名空间导入的写法。
b.可能有童鞋在添加引用之后就着手于Xaml的编码工作,然后发现VS不能正确的进行智能提示。我建议添加引用后Build(编译)一下,以便让编译器知道已经导入了新的dll,而后智能提示就可以正常运作了。
3)逻辑代码
var hwnd = panelSignature.Handle;
WinForm这边获取控件的句柄是很简单的,就这么一行代码就可以了。看看效果:

嗯~不一样,不一样就对了O(∩_∩)O
4.扯淡时间
完成签名板这个任务花了两天时间,第一天写出了InkCanvas版本,第二天完成了目前公司采用的这个版本。先来张测试截图:

有童鞋可能会问:怎么不写“测试”二字,亦或是“Hello World”……我表示当时完成这个功能的时候相当激动,颤抖的手握着电子签字笔就写下这么一行,然后截图发给心目中的女神了……那天晚上离开公司的时候大雨瓢泼,我的心头却晴空万里(●'◡'●)
最后祝各位劳动节快乐,相信每一份努力都不会被辜负!!
【WPF】学习笔记(二)——依旧是一个电子签名板的更多相关文章
- WPF学习笔记二 依赖属性实现原理及性能分析
在这里讨论依赖属性实现原理,目的只是学习WPF是怎么设计依赖属性的,同时更好的使用依赖属性. 首先我们来思考一个简单的问题:我们希望能验证属性的值是否有效,属性变更时进行自己的处理.回顾一下.net的 ...
- Struts2学习笔记(二):第一个Struts2应用
一.创建Action类. 创建工程Struts2Demo struts 2中的Action类并不需要继承struts 2中的某个父类,普遍的java类就可以. 在org.sunny.user.acti ...
- WPF学习笔记二之依赖属性
1.快捷生成依赖属性:propdp然后按两次tab键 2.应用场景:自定义控件 什么是依赖属性:依赖属性自己没有值,通过依赖别人(如Binding)来获得值. 依赖属性为什么会出现:控件常用字段有限, ...
- WPF的Binding学习笔记(二)
原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...
- AJax 学习笔记二(onreadystatechange的作用)
AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...
- [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计
源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...
- JMX学习笔记(二)-Notification
Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- Java IO学习笔记二
Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...
随机推荐
- hog特征及其提取方法图示
1 什么是hog特征 hog特征是histogram of gradient的缩写.我们观察图像时,信息更多来自目标边沿的突变.我们计算一块区域内的所有像素处的梯度信息,即突变的方向和大小,然后对36 ...
- JavaWeb之Listener监听器
监听在Java体系中运用的很广泛,在安卓开发.JavaWeb开发中到处存在,在其他语言也有类似的,如果有了解过设计模式那很容易理解实现的原理.不过对于开发者来说,使用观察者模式只需实现相应的接口就好, ...
- ubuntu查看安装的cuda toolkit自带的工具及其他安装文件
原创作品,转载请注明来源:http://www.cnblogs.com/shrimp-can/p/5253672.html 1.查看工具 默认目录为:local,进入local:cd /usr/loc ...
- zabbix_agent-linux下的安装
scp 10.25.133.184:/usr/local/zabbix-2.4.1.tar.gz /usr/local 1.为了安全考虑zabbix只使用普通用户运行,假如你当前用户叫ttlsa,那么 ...
- 《C++之那些年踩过的坑(三)》
C++之那些年踩过的坑(三) 作者:刘俊延(Alinshans) 本系列文章针对我在写C++代码的过程中,尤其是做自己的项目时,踩过的各种坑.以此作为给自己的警惕. [版权声明]转载请注明原文来自:h ...
- ConversionService接口
spring已经为我们提供了一个既可以使用GenericConversionService,又可以注入Converter的类,那就是ConversionServiceFactoryBean.该类为我们 ...
- vue监听滚动事件,实现滚动监听
在vue中实现滚动监听和原生js无太大差异,下面是一个简单的demo,可在控制台查看结果 <!DOCTYPE html> <html lang="en"> ...
- Windows运行命令大全
inetmgr 启动IIS控制台winver 检查Windows版本 wmimgmt.msc 打开Windows管理体系结构(wmi) wupdmgr Windows更新程序 wscript Wi ...
- 使用JDB调试Java程序
Java程序中有逻辑错误,就需要使用JDB来进行调试了.调试程序在IDE中很方便了,比如这篇博客介绍了在Intellj IDEA中调试Java程序的方法. 我们课程内容推荐在Linux环境下学习,有同 ...
- 手机自动化测试:Appium源码分析之跟踪代码分析六
手机自动化测试:Appium源码分析之跟踪代码分析六 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest推出手机自 ...