这篇博客呢,主要谈谈在实现电子签名功能中踩过的几个坑: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】学习笔记(二)——依旧是一个电子签名板的更多相关文章

  1. WPF学习笔记二 依赖属性实现原理及性能分析

    在这里讨论依赖属性实现原理,目的只是学习WPF是怎么设计依赖属性的,同时更好的使用依赖属性. 首先我们来思考一个简单的问题:我们希望能验证属性的值是否有效,属性变更时进行自己的处理.回顾一下.net的 ...

  2. Struts2学习笔记(二):第一个Struts2应用

    一.创建Action类. 创建工程Struts2Demo struts 2中的Action类并不需要继承struts 2中的某个父类,普遍的java类就可以. 在org.sunny.user.acti ...

  3. WPF学习笔记二之依赖属性

    1.快捷生成依赖属性:propdp然后按两次tab键 2.应用场景:自定义控件 什么是依赖属性:依赖属性自己没有值,通过依赖别人(如Binding)来获得值. 依赖属性为什么会出现:控件常用字段有限, ...

  4. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  5. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  6. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  7. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  8. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  9. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

随机推荐

  1. gzip 与 gunzip 语法与示例

    gzip 与 gunzip 语法与示例 语法: gunzip -c 被压缩的文件 > 已解压的文件示例: 将 catalina.out.gz 文件解压到 catalina.out 文件中: gu ...

  2. php文件管理与基础功能的实现

    文件的基本操作 先来看一下PHP文件基础操作,请看强大注释 <body> <?php var_dump(filetype("./img/11.png")); // ...

  3. cuda编程学习1——hello world!

    将c程序最简单的hello world用cuda编写在GPU上执行,以下为代码: #include<iostream>using namespace std;__global__ void ...

  4. 将node.js程序作为服务,并在windows下开机自动启动(使用forever)

    手上项目中有一块服务是用node.js实现的,运行环境是windows server 2008 R2,刚开始着手实现这块功能的时候时间很紧迫,随便写了个console程序就部署上去了--启动方式就是在 ...

  5. CDN,你了解多少?

    大家对CDN并不陌生,工作中或多或少都有所接触,最近也有人问到,在此对CDN相关概念和流程做下总结,希望还能对其他朋友也有所帮助. 一.什么是CDN 维基百科上是这样定义的: CDN:内容分发网络(C ...

  6. linux命令之查看字符集

    lucifer@abc:~$ locale -a 查看本地字符集lucifer@abc:~$ locale -m 查看所有支持的字符集将文件从gb2312转为utf8iconv -f gb2312 - ...

  7. mysql的导入和导出

    MYSQL数据库导出 以root登录vps,执行以下命令导出. 1./usr/local/mysql/bin/mysqldump -u root -p123456 zhumaohai > /ho ...

  8. JDK动态代理实现机制

    =========================================== 原文链接: JDK动态代理实现机制   转载请注明出处! =========================== ...

  9. Activiti的全局事件机制及其监听处理

    概述 Activiti在5.15以后的版本后,增加了统一的事件入口,不需要再像以前那样,监听流程的事件时,在流程定义的BPMN文件中为每个节点及流程增加以下的配置,以实现监听事件的做法,这种做法导致我 ...

  10. Linux文件管理下

    文件操作 对于文件,我们可以读取(read),写入(write)和运行(execute).读取是从已经存在的文件中获得数据.写入是向新的文件或者旧的文件写入数据.如果文件储存的是可执行的二进制码,那么 ...