1.前言
这个键盘记录器同样是我以前的兴趣之作,研究了良久才完成的,现在拿来作为大家的一个学习Qt的项目。
同时该项目里面不仅仅含有Qt知识,还含有很多其它WIndows开发的神奇知识点,也当是给大家开开眼界了。
它的作用就是,可以记录你每天电脑敲击键盘的数量,并显示出你敲击数量最多的前十个键,成品如下:
是不是感觉还不错呢?
所以接下来,我就带大家一步一步将这个软件给做出来,当然建议你跟我一样,使用VS开发,因为这个解决方案里面将至少包含两个项目,用Qtcreator
的话,确实不方便。
之所以说是至少,因为我本来还想给它写个服务器,弄个多人排行榜之类的东西。
也就是说,这个软件只是一个单机版的,单纯就是用来记录我们每天敲击键盘数量的软件,每天晚上看一看自己一天的成果,是不是也很有成就感呢!
2.理论知识
首先我们看这个项目的核心功能,是统计用户敲击键盘按键的次数。
为了实现这一功能,我们就需要用到Windows编程中的钩子概念。
在WIndows窗口编程,乃至MFC编程中,相信大家最记忆犹新的就是消息循环
,我们的窗口应用程序启动后,是如何接收到用户的鼠标、键盘消息的呢?
这就是通过我们的Windows系统,将我们移动鼠标,点击键盘的消息收集起来,然后发送给你应用程序的。
最常见的就是,我们窗口上开了很多个应用程序,比如微信、QQ,那么我们的按键消息应该发送给哪个应用程序呢?
经验来看,一般是最前面的那一个窗口,我们称当前接收系统发送消息的窗口,为焦点窗口。
一般来说,即使你开了很多程序,系统也只会将我们的按键消息发送给其中一个焦点窗口。
而所谓钩子,就是在系统发送给窗口的中途,设下了一个关卡,即系统无论发送给哪个窗口,都必须经过这个关卡。
现在你听着可能没啥感觉,举个例子,当你输入QQ账号密码时,你按下的每一个按键都将作为消息,发送给QQ,这是正常情况下。
然后当我们设下了一个钩子时,系统发送的消息就必须先经过我们这里,然后我们可以任意处理该消息,早期盗号的木马病毒,很多就是用的这个技术,你的QQ密码还没到QQ程序,在半路就被拦截下来了。
而想要做一个这样的钩子,就必须使用动态库,为什么呢?
这就涉及到了进程相关的知识,不懂的可以先看看本站的另一篇文章:进程与线程。
我们平时说的内存8G,16G,32G,一般指电脑的运行内存,即电脑同时可以容纳多大的程序运行,比如我目前的电脑就是16G的:
而我们平时在编写程序中,所说的申请内存,其实就是申请的这个内存,无论临时变量(栈中)还是全局变量,new变量(堆中),都是它,这些名称只是我们在特定情况下,给某些内存人为的赋予了不同的涵义而已。
一般32位应用程序最大为4G内存(2的32次方),而64位应用程序最大是很多T的内存(2的64次方)。
那为什么我们电脑运行这么多程序,电脑占用内存还是这么低呢?
这就涉及到了一个叫做虚拟内存的概念,可以查看本站的另一篇文章:逆向基础。
为什么需要了解这些看起来枯燥且乏味的理论知识呢?就是因为我们这里要用到这个。
动态库的作用就是,当它被加载到内存中时,可以被多个exe程序,即进程,加载到自己的地址空间中,虽然一般它在内存中只有一份(只要你不改变动态库中的变量值),但它却可以同时被所有进程使用。
这就是使用动态库的优点:节约空间。
由于进程之间的互不关联性,所以我们不能在我们的程序中,去统计系统发给别的应用程序的消息。
而这里通过动态库的这一特性:可以加载到所有exe程序(进程)中,我们就可以完成这样的任务!
我们将钩子写在动态库中,只要我们的exe程序启用并加载这个动态库,那么系统中其它所有的程序接收的系统信息,就都必须经由这个动态库。
因为一旦启用钩子,这个动态库就会被系统强制加载到所有接收消息的进程中。
这样我们就可以统计按键消息了!
说了这么多,可能你依旧还是云里雾里的,但没关系,我们边写代码边理解!
3.建立项目
还是创建Qt组件应用程序:
这里解决方案与项目直接同名即可,注意不要勾选将这两者放在同一个目录:
前面的选项都为默认即可,到下图的步骤时,选择QMainWindow比较方便,因为我们需要菜单等正常窗口所需要的东西,它里面就有现成的:
然后我还勾选了预编译头文件,因为如果你Qt用的比较多的话,就会发现它编译特别慢,每次编译运行都要等好久,而MFC就会比它快很多。
难道是MFC设计的比Qt好吗?那可不一定,最主要的原因就是MFC是自动开启了预编译的,而Qt我们一直没有使用过预编译,所以编译速度会相差很大。
所以这里我就带大家使用一下预编译,然后上图点击Finish
即可。
这样我们的基本项目就建立好了,剩下的就不用管它了,后面我们再对它进行写代码之内的操作
然后我们还需要给这个解决方案再添加动态库项目,至于如何使用,我们后面会谈到: