00:00
呃,咱们这一节课开始呢,我们就开始一个这个新的专辑了,就是黑客下家编程这块啊,然后呢,主要呢,会实现一些这个,呃,安全编程的一些基础知识啊,和这个相关的一些小工具的开发,那我们这是第一节课啊,我们来先来讲一个基础,就是我们Windows的一个消息机制啊,我们Windows上的这个程序呢,都是基于这个我们Windows系统而这个运行的,那么我Windows系统呢,它就是干嘛呢,基于消息机制来进行一个运行的操作系统,那么我们在这一方面呢,可以直接参考它的这个WIN32和这个MFC的一个类库的一个程序啊,来观察一下它里边的消息机制是怎么样来运行的,那首先我们可以直接使用一个微缩C加加啊,来给你建一个啊,这个SDK的一个原生程序啊,就是这个啊C加加桌面应用程序啊,如果说你是老版本或者更新版本的,它名字可能不一样啊,然后点击确定就可以了啊,点击确定之后呢,它会给你构建出一个基本的SDK程序的。
01:00
这个模板啊,就是这个样子的啊,在这个上面呢,你要如果正常运行的情况下,你需要它的这个属性里边啊,给它设置一下。MTD啊把缓解库关掉啊,这样之后呢,它就可以正常运行了啊,直接点运行。好,运行起来之后呢,它就是这样的一个这个窗口啊,那么然后呢,我们现在呢,就来了解一下啊,它是一个怎么样的一个基本流程啊,首先我们SDK呢,它是给你自动给你创建了一个模板啊,然后呢,我们来看一下它里边呢,有一个消息循环,在消息循环之前呢,它首先呢有这么一个这个主函数啊,它就类似于我们这个普通C和C加程序的一个main函数,然后它有四个参数啊,主要是一个实例句柄啊,然后两个实例句柄和一个这个字符串,以及一个显示方式一个型的,那这个实例句柄呢,实际上就相当于我们整个EE程序的一个加载机啊,然后呢,这个第二个呢,它是一个一个已经废弃的东西啊,你就不用管了,第三个呢是如果你是以命令函形式启动的,那那么这个参数里存的就是命令行,最后一个就是你个窗口啊,它是以什么形式啊进行显示的,在这个位置呢,这有个函数啊,是注册了一个窗口类啊,这个窗口类里里边有一些这个窗口的一些基本信息,比如说啊窗口的一些这个风格啊,然后这个呢,是窗口的一个。
02:20
的一个,呃,回调函数,这个函数呢,主要是用来处理什么处理的消息的,那么我们现在呢,先不看这个啊,先回来,回来之后呢往下看啊,这里边呢,还有一些比如说图标,光标实力柄,然后呢还有这个。背景色啊,这是背景色啊,默认情况下应该是灰的或者白的,然后呢,这个是你默认情况下菜单是哪一个,它这块呢,有一个ID啊,那你在资源里头可以看到啊,这有一个RCRC里头有一个菜单,菜单里头默认的这个菜单啊,就是我们在那显示的这个啊,我们在运行的时候,它作为一个顶层菜单的存在啊好,那这个呢,是这个默认菜单啊,默认菜单底下呢,还有这个类名啊,这个类名呢,在上边呢,进行一个默认初始化,它是一个呃,资源的形式存在的啊,它这里有一个名字叫IDC啊,Window project6啊,那它是在这个string table里边啊,有一个这个字符串啊,你看在这。
03:14
叫什么叫做这个IDC project啊,然后上呢,有一个ID title啊,那个是标题名啊,啊底下这个呢,是它的一个类名啊在底下呢,这呢就是什么呢,这呢就是啊不是不是这啊这底下呢啊在底下呢就是一些这个注册相关的东西了啊他们呢是在一个结构里的,叫wn class SW啊这里边呢,就是我们刚才看到那些成员,然后当这些成员被填充之后呢,他就会在这里啊使用一个API啊注册注册他这个窗口类,注册完窗口类的目的呢,主要是为了干嘛呢?主要是为了在这里啊初始化的时候把它创建出来,我们使用一个create window啊来进行一个窗口的这么一个创建,然后第一个呢,就是窗口类的一个类名啊,第二个呢是它的呃title口啊标题啊,第三个呢,就是一些它的风格啊,然后呢之后呢,就是它的这个X坐标和Y坐标啊,然后宽度和高度,然后这两个呢,一个是这个我看一下啊,它应该是什么来着。
04:12
啊,这一个是副窗口的一个句柄,一个是菜单,然后实例句柄啊,最后一个这个没有用,是个参数啊嗯,等等,最后一个可能也有用啊,但是我们现在用不到啊,然后现在呢,就是这么多啊,然后最后接下来判断一下它有没有这个创建成功,如果创建成功了呢,进行秀温度啊,把它显示出来,按照这个副窗口窗口句柄,然后是它的显示模式,然后给它秀出来,秀出来之后呢,进行更新,更新窗口啊,然后用这个句柄把它更新窗口更新出来,然后接下来呢,就进入到我们的这个消息循环了啊在这个位置啊,有一个这个消息循环,主消息消息循环,我们这个主消息消息循环呢,就是我们的这个程序啊,整个的消息的一个派发的一个过程啊,我们这个消息大致上呢,是从这个操作系统啊,然后进行分发,分发到窗口,窗口有一个消息列表,然后呢,我们的get message从消息列表里进行这个消息的获取,存储到我们的消息结构里,然后呢在这个位置上啊对它呢,进行一个这个码,然后呢进行分发啊,分发到我们的这个。
05:13
窗口上,那么这里边呢,他们操作的一个东西呢,就是什么呢?就是消息啊,也就是M啊,这是一个死循环啊,进行一个消息的一个操作,那么我们在上边这呢,就有什么呢?就有消息它的一个结构啊,我们可以直接F12进去看一下它的结构,它的结构呢,比较单纯啊,一共就七项啊哎不对,六项啊六项啊啊不对,应该是七项啊这还有一个大家不用啊啊这六项啊,那六项是什么东西呢?首先第一项它是窗口句柄,第二项是消息类型,第三项第四项是两个参数,分别占32位,然后这个东西呢,是你消息触发时候的时间的时间,戳这个呢是什么呢?这个PT是一个坐标啊坐标啊,它这个这个它也是一个啊,我们之后你会发现它是一个S啊,那这个东西为什么要存在呢?比如说你接的是一个这个件,比如说是这个,呃,鼠标或者键盘传过来的,那如果它是鼠标传过来的,你鼠标点在哪了,是不是是一个很重要的消息啊,那这个point呢,就把它在触发。
06:13
的时候,这个鼠标在哪点击的这个消息啊,给你记录下来啊,让你知道它是在哪里触发的这个消息。那这个呢,就是什么呢?这个就是我们的一个主消息循环啊,那我们这个主消息循环把它派发到我们窗口之后,由谁进行处理呢?就是由我们刚才说的,在我们注册窗口类的时候,这有一个什么,有一个主窗口的一个这个处理程序,回调call back啊,那我们跟进去这块啊,就是用来干嘛,用来处理我们的消息的啊,那么这个你看它是处理什么,处理主窗口的消息,如果说你需要处理其他的对话框的消息呢,你还需要给他单独的创建一个消息循环啊,如果是这个模态的啊,就是自建消息循环,如果是非模态呢,就与串口共用循环啊,然后你可以看到这个函数呢,它是什么呢?它是一个这个call啊,那这个call实际上就是一个调用约定,应该就正常情况下呢,就是一个std call,好,那回来之后呢,你可以看到它有四个参数,这个四个参数呢,和我们刚才看到的MSG呢,就是非常接近啊,我们的MS一共六个,但是有两个呢,它没有显示出来,一个是时间戳,一个是位置啊,它显示了四个通用的,分别是窗口句柄,消息啊,然后两个参。
07:22
参数啊,一个W参数,一个L参数啊,然后底下呢,在这儿呢,使用一个Switch对这个message进行一个分发,分发出来的是顶级消息啊,就是类似于wm command啊,然后这个拍印的啊,还有这个什么这个呃,就这就不知道怎么读了,反正就这个啊,这个是销毁啊,那这几个消息呢,你可以看到是什么东西啊,首先呢,这个卡曼的是处理应用程序的一个这个相关的一些这个操作啊叭如说菜单消息啊,按钮消息啊,都在这儿处理这个这个拍呢,这个东西呢,是这个处理绘制的啊,你比如说你要在窗口上画点什么东西啊,就在这儿,然后这个呢,是这个退出的啊,那如果你是对话框程序的情况下呢,你这要额外的处理两个,一个是这个case啊,这个in it dialog啊,这是对话框程序需要处理的,然后呢,如果你要关掉的,你要处理WM啊,Close。
08:15
这是两个啊,那如果说你不是对话框上句现现在是主窗口,那这两个就不用了,但是如果你需要绘制绘制窗口,在上面写空件,那你就不能放在这里边,你要放在什么,你不能放在拍那里,你要放在case create里,WM啊create啊,这个是用来初始化控件的一个这个消息,好,那以上呢,就是我们的正常的一些这个常规的一些消息,以及消息的一个处理过程啊,那我们现在呢,就来看一下啊,我们正常情况下消息呢,我们都要了解什么,我们大致上需要了解的主要是这个几项啊几项我在这儿给写文本。首先我们第一点啊,我们已经知道了这个消息结构里边存的都是什么东西,然后呢,我们知道了什么是这个消息循环,那剩下的呢,就是消这个消息类型了啊,消息类型我们大致上需要了解的消息类型呢,是分这么几种,第一种啊是这个,呃,键盘消息,第二种呢,是这个鼠标消息,第三种呢是控件消息,第四种呢是这个,呃,我想想应该还有这个自定义消息啊,然后呢,我们还需要了解的呢,就是两种发送这个发送消息函数的区别啊,分别是什么呢?分别是我们的这个send send message。
09:51
和什么和我们的push的他们之间的一个区别。啊,是这两个这些东西啊,那我们现在刚才呢,我们已经认识了它的这个消息结构和消息循环啊,那我们现在呢,给他来写在上边。
10:16
我们首先把这个消息结构啊,我们给他拿过来,然后简单给大家打个注释啊。这就是消息结构,消息结构呢,这一项啊,窗口句柄消息。或者说要消息编号啊都行啊,反正就是一个消息啊,它是一个整形,然后呢,接下来是参数啊,这是参数,这个呢也是参数,这两个参数呢,各占32位,这个呢是时间。时间戳啊,这个呢是坐标体系啊,坐标消息触发时的坐标,好,但是就这么东西啊,这个没有用啊,那删掉。
11:12
好,首先我们消息结构就知道了,消息结构之后啊,主消息循环。这就是主消息循环啊,我们把消息循环拿过来,消息循环里的这个函数的内容呢,你可以通过这个一啊来查看它的SSDNMSN啊,比如这个啊,这是这个获取消息啊中消息对接里获取消息啊,然后它的参数是什么呢?分别是这个消息类型,附状口句柄啊和这个最小最大值啊,就这类东西啊,你可以直接通过我们的这个这个MSDN进行查看啊,这就是派发的一个过程啊,它是不断的在消息队列里进行获取,获取之后进行一码,一码之后进行派发,好然后呢,这是消息循环我们也知道了,接下来呢,我们就看它的消息类型啊,分为三类啊,一类是键盘消息,一类是鼠标消息,一类是控件消息,那正常情况下呢,我们的这个键盘消息呢,大致常分为两类啊,一类叫做这个3.1啊,3.1.1叫做这个非系统啊,非系统按消息,还有呢,就是3.1.2的这个系统按键消息。
12:21
信安件消息呢,大致上呢,分为两种,第一种呢,叫做我们的这个,呃,分别是两种,两种状态啊,一种叫做见。按下啊,一种叫键啊,这是系统的啊,非系统的呢,分别叫做什么WM啊,然是两,那还有呢,还有这个我们系统是这个是这个键按下和键起,但是它有一定的区别,它的区别是什么呢?它的区别就在于我们系统按键呢,叫做WM啊,这个啊,System p up啊,那么它们之间的区别是什么呢?就是我们正常情况下啊,我们的按下和抬起,一般情况下主队出现的,就比如说你按了一个按键之后,你一般情况下呢,会再跟着抬起啊,你很少有说你按下去之后就一直不抬的这种情况啊,这种情况较少的,那么我们如果一直按着一个键不放呢,就会出一个连续的按键行为啊,就是我们Windows会发送给窗口一大堆的这个,然后呢,你在起的一瞬间呢,出现一个这个up啊,这是一。
13:32
它简单的一个区别,然后呢,我们这个东西呢,我们这个系统按键和非系统按键呢,有一点点小区别,就在于什么呢?在于我们的消息啊,如果说啊,我们加了system,就说明这个消息对于操作系统比较重要,而对于我们应用程序来说呢,虽然重要,但没有那么重要,简简单来说就是这个消息对于系统而言比对于应用程序而言更重要,比如说啊,你在这个和alt键组合的时候,它很很多情况下就是什么,就是system啊,一般情况下都是system啊,怎么说呢?比如说你alt加typeb进行页面切换,或者alt加F4进行关闭窗口,这些东西呢,都是在操作系统上啊,有一定功能性的,所以说呢,它通常触发的是什么呢?书通常触发的就是system消息,而不会是普通的应用消息,那如果说你刚刚好你也使用了这些消息,那么这种情况下呢,你最好在使用完你的消息之后,把这个消息在转发给操作系统啊,就是在调用一下这个window p。
14:32
行默认的处理啊,不然的话,有可能会因为你啊来拦截出的这些消息而又没有交还给操作系统,那么这种情况下呢,可能触发一定的这个错误啊,所以说呢啊,你应该再给他啊,那么我们这四类消息呢,它里边呢,都是使用了一套这个体系啊,就是说我们这不是有四个这个成员嘛,我们在这个接收消息的情况下,这这儿有一个四个成员嘛,就分别是这四个,那么这里边呢,我们在这个W啊W开头这个参参数里边,它保存的是虚拟键安代码。
15:06
呃,我们这这给他写一下啊保存。虚拟现码。那虚拟件码是什么东西呢?这个东西也不用备啊,这个东西呢,我们可以上网搜啊,然后呢,我们直接啊在百度上啊搜一下虚拟件码,它就直接就有了啊,比如说我们直接打开,打开之后呢,你可以看到啊,这就是一个所谓的这个虚拟键码啊,但是呢,你可以看到它按顺序来的,实际上是1234,然后什么八九十十一十二十二三,但是这里边呢,有三个虚拟键码是和键盘无关的,分别是124啊,你可以看到一是什么,一是鼠标左键,二是鼠标右键,四是鼠标中键啊这三个键呢,是和我们的键盘没有关系的,所以说呢,你这三个东西你在键盘的处理程序里是不会遇到的,而是会干什嘛呢?在鼠标的处理程序里边会遇到这三个东西啊,那么这种情况下呢,你就不要在这个键盘里去拦它了,拦了也白拦啊,所以说没有用啊,那我们已经知道了,W参数里边存储的是我们的虚拟键码啊,决定了你到底是按了哪个键,那么我们的L参数里呢,保存的是一些其他的消息,但这些其他消息一般情况下你是很少用到的啊,所以说呢,你不需要太在意,那么。
16:18
在呢,就来实际上的编写一下程序,来看一下我们的这个呃,按键消息是如何进行发送以及处理的啊好,那没有点关注的同学们,我们点点关注啊,每周六周日晚上都有直播啊,我们这个黑客瞎加系列编程呢,也会有很多节啊,然后呢,不要错过,需要工具的呢,也可以找老满来进行领取,老满的联系方式呢,就在公屏上,大家可以直接找他要啊。好,那我们这个消息呢,它这个因为是一个这个按键消息,它是和我们这个WM啊顶顶层消息啊,是处于处于同一层的,所以你可以在这啊直接使使用一个case啊,用一个WM啊,比如说我现在拦截一个key大啊,这里呢是顺便提一句啊,因为我们的按键消息通常情况下是床对出现的,就是有按一下比较抬起啊,所以说呢,你就没有必要两个都来啊,你来一个就行了啊,因为你按下抬不起的几率呢,比较低啊,我们break啊,然后呢,在这儿啊处理一下WMK档,也就是按下这个键盘这么一个消息,然后呢,我们使用一个Switch啊对我们的消息码进行判断,那我们刚才也说过了啊,我们W参数里保存的是虚拟件码,所以说呢,我们在这儿呢,直接啊对其进行什么啊,进行分发,分发之后呢,在底下呢,就可以处理这些虚拟键码,比如说我们直接case一个F1 f1是什么样的虚拟件码呢?我们来看一下啊,这么多虚拟件码它里边啊就有就有这个F1啊,我这。
17:44
呃,这呢你看啊, VKf1到F10啊,然后F11到F22 Ff24啊都有,那我们现在呢,就干嘛呢,我们使用一个VK啊,然后F1啊代表什么?代表着我们要处理的是F1按键,好,那这种情况下呢,首先我们对基金一个break,然后呢,我们在调用一个ma box。
18:12
好,我们运行。在这个窗口上,我们点击一,你可以看到啊,我们就弹出什么,就弹出了这个VK1这个按键啊,就弹出来了,然后呢,我们这个就是说明什么,说明我们拦截到了这个消息啊,并且进行了什么,进行个处理啊,那么好,那这是一个什么,这是一个单纯案件啊,那如果说你现在呢,要判断一个复杂案件,比如说你要判断是不是跟shift同时按下了,那么这个时候你怎么办啊,你就来获取一下按键的一个状态啊,那我们这用一个short。短整形啊,来进行一个flag的获取。等于啊,然后这里边儿是get获取啊,获取按键的状态,那这个按键状态呢,支持几个啊,我们这是使用一个这个v k shift。
19:19
啊,然后呢,最好呢,你是给它与上一个0S8000的这么一个常数啊,为什么要与上0S8000这么常数呢?因为你在获取到键的时候,它有可能会产生一些其他的状态对你造成干扰,那么我们对这个mi对比这个MSDN的这个说法而言啊,那么你雨上0S8000这种情况下呢,就没有什么问题,另外呢,你这个返回这个flag啊,它不是说是这个true false这种形式,而是说如果说你返回的这个false是小于等于零的啊,那么这种情况下啊,它就是什么啊,它就是说是平时按下了这个按键啊,然后呢,我们现在呢,就可以直接啊给它来进行一个弹出,弹出是什么呢?弹出的是shift加F1。
20:06
而如果没有这个,如果它是一个正数的情况下,那它就是什么,它就是一个啊普通的按键一说明我们的shift没有被按下,那么我们运行一下。首先我们按一下F1啊,诶。不对啊,我看一下啊,可能是这这的原因,它应该是一个负数啊,我来再运行一下。你看这是F1,然后shift加F1,诶你看对不对啊,它不包括零啊,它是一个负数啊,这是普通F1,这是shift加F1,诶看它就是不同的啊,这个呢方法呢,就可以判断什么,判断组合键的存在啊,判断组合键的存在好,然后呢,我们还可以干嘛呢?我们还可以通过一个按键啊给另一个按键发送消息,比如说我直接一个case啊K什么 KVKf2好,那么这种情况下呢,我就可以干嘛呢?我就可以直接啊给他发送啊,调用一个send message进行发送消息,发送消息首先呢,我们要发送这个消息发送到我当前窗口,然后呢,我采用的呢是副窗,我自己窗口的一个窗口句柄传进来,因为我发送消息的时候,我在顶层处理,这里呢,是带了一个窗口句柄过来的,所以说呢,我直接接收到,接收到之后呢,接下来呢,我们一个WM啊,Key档的一个消息啊,就是发送,发送key档的消息就模拟按键,模拟完事之后呢,我们再调用啊这个v k fe啊,因为我们。
21:34
这里的默认情况下呢,是W参数里存的是他的件码,那我们也把件码放进去,然后最后一个呢,是其他消息,我们可以直接传一个闹进去。好,我们传了一个闹进去啊,那么这种情况下呢,我们就按照F2的时候会直接发消息啊,给我们窗口,然后进到K档,再进到F1啊,然后执行F1的消息啊,那我们现在break好运行。
22:02
现在我摁F1啊,你看正常的,然后呢,我摁一下F2啊,你看它也是正常的对不对,那为了分别我到底摁的是F1还是F2,我们可以对它呢,进行一个简单的一个区别,什么区别呢?就是如果说我是通过F2给他发过去的啊,我可以把我这边给他留点数字啊,比如说我给他放个123啊。好,那么在这边呢,我们可以在在在进来之前啊,我先判断一手,判断一手我的这个L参数。如果我的L参数啊,等于等于123,那么这种情况下呢,我就直接啊给他谈一个什么呢?谈一个123。然后直接啊,直接break,它是在F1里处理了F2的消息,这就属于啊,那我们运行啊,那我们首先F1没问题,F2你看123对不对啊,所以说呢,这个呢,就是一种发送消息的方式啊,发送消息的方式啊,这是属于什么?这属于键盘消息啊键盘消息,那么首先我们键盘消息就在这儿了,那么我们如果说是鼠标消息呢,鼠标消息呢,那就是另一个按键了啊,鼠标消息首先我们要了解啊,它有两个三,什么三呢?就是首先啊3.1.1啊,它是有三种三种状态啊,然后呢,3.1.2,它是有不对三点。
23:41
3.23.2.13.2.2啊,然后这是有三个按键啊三个按键,然后呢,三种状态分别是什么呢。分别是单机。
24:00
双击和拖动,而我们的三个按钮是什么呢?分别是左键L啊八右键。阿尔,呃不呃,对,阿尔。和中间。M button,好,这个呢是常规的鼠标啊,因为我们常规的鼠标一般情况下,最基本的它会有左键右键和中间的滚轮啊,但是呢,有一些比较说,比如比如说电竞的那种啊,那那种呢是什么呢?是我们的这个它有一些辅助键啊,比如说它有一些这个快快速切换啊,边键啊,这种东西呢,它是基于你的这个驱动而实现的,因为你鼠标上会带驱动,然后来响应这些消息啊,告诉你的操系统应该如何处理,但是最基本的三种消息呢,就是左键消息,右键消息和中键消息啊,那这三种消息呢,我们都有这三种状态,比如说左键单击左键双击左键拖动啊,右键单击右键双击右键拖动啊,中键呢,很少有说单击双击的,但是它确实有这个功能啊,好,这个,哎,我去。
25:41
啊,这这个搞错了,我把它这个。关了。好,这个呢是三种消息和三种按键,那我们现在呢,拿其中一个啊,左键端单击给大家演示一下啊,剩下的大家自己尝试,我们首先呢,左键单击这个东西呢,它依然是一个顶层消息,比如说我现在呢,直接一个w ML button。
26:06
Button down啊,左键点击啊,你可以再来一个左键抬起啊,都无所谓。好,那我们现在呢,来看一下啊,这个东西啊,我们已经啊给大家有了这个消息啊,那么接下来就是处理这个消息了啊,那比如说我现在就只想单纯的判断一下是不是左键点击啊,那现在呢,你就可以干嘛呢,可以在这儿给他响应一下,比如说现在呢,我就是一个左键单击消息,左键单击啊,左键单击我们直接运行。点左键单击对不对,再点左键单击,再点左键单击对吧,这就有左键单击消息了,那么如果说你需要判断一下啊,你不想所有左键单击都被触发,那这个时候你其实你是可以判断一些组合消息的,比如说啊,你进行判断if啊,If什么呢?If你的W参数里。
27:13
W参数里与上一下MK shift,注意不是VK啊,是MK啊,这里边呢,只支持几种啊,包括我们什么,包括我们的shift CTR啊这几种啊才能判断啊,然后呢,我现在这个这种形式呢,就是判断什么,判断我是不是左键和shift一起按了,如果一起摁的情况下才会产生这个消息。才会啊,我们比如说啊,这个shift加左键单击啊,那现在呢,我直接运行。你看啊,他什么什么点了之后什么反应都没有,我摁一下shift,再摁一下左键,你看shift左键单击啊,这就是组合消息,另外呢,你这也不单单可以是一层组合啊,那你可以二层组合,比如说我现在呢,再给它干嘛呢,再给他判断一下有没有摁CTRL啊,如果摁了CTRL呢,我在这儿呢,就弹一个什么呢,就弹一个这个我们的这个CTRL加shift加左键单击,如果没有的情况下呢,我们就给它弹出一个什么,弹出一个啊shift加左键单击。
28:26
好,现在呢,我们运行运行之后啊,我们点你看这就是CTRL加shift加左键啊,那我们shift加左键,你看这就是shift加左键啊,我们就可以判断什么呢?判断同时它按了几个按钮,这就是属于什么组合键啊组合键好,那这个呢,就是我们的这个这个键盘不是鼠标相关的一个消息啊,说鼠标消息之后呢,我们再说下一个,下一个呢,就是我们有这个控件相关的一个消息啊,那控件消息。那控件消息这个东西呢,我们正常情况下呢,有非常非常多的件啊,那我们这个在我们SDK里啊,我们提供了很多很多件给你使用啊,我们可以直接在这个TR这个crl window上面进行一个F1啊F1上面呢,它会有写你在这个所有东西啊,什么参数返回啊,返回值之后啊,它这有一个什么东西啊,你看它会啊,给你这个预设一些这个东西啊一预设一些这个类啊,你比如说你可这window的时候,你创建它需要一个自己啊填写一个叫做什么这个WND,那么这个指定如果啊,就是这个钮,你把这些东西预设好,然后你直接给它填上样式就可以了,或者说有这个编辑框啊,这个下拉框啊,列表框啊,这类东西都是可以直接使用预设的,那比如说我们以一个简单的按钮为例啊,你来演示一下按钮消息,我们点开这个按钮样式啊,那首先呢,它这里边呢,有很多很多的东西,那么按照我们正常情况下而言呢,我们才需要找一下他这个。
29:55
按钮样式啊,正常呢,我们会用到的样式呢,也就十来种啊,那这里边这些样式呢,实际上我们都会,呃,也不是都用到,因为有些东西呢,是这个单选框和多选框啊,相对于N1而言呢,我们通常情况下加上这个BS这个push button就可以了啊那我们在这儿呢,我们选择啊在哪呢?在我们刚才写的这个create啊,Create这个消息里边啊,进行一个呃,初始化的一个绘制啊就在这儿啊,我们直接啊写一下这个create。
30:25
啊,对了,我们不用这么写啊,我们这边是有示例的啊,我们在这个概数里边啊,然后使用按钮,这有一个如何创建按钮,我们直接点开,点开之后呢,它会在这儿呢,给你显示一个示例,那我们直接把这个示例啊给它复制过来啊,然后呢来使用它就行了,但是呢,它有一定的错误啊,因为这里边有些东西没有我们需要,比如说这个副窗口句柄啊,我们要改成我们自己需要的一个名字啊,然后这获取的是实例句柄啊,然后接下来我们进行一个运行。可以看到啊,它一个按钮就创建出来了啊,那么这个时候呢,如果我们要应这个钮啊,它的一个消息,那么首先呢,你要有一个ID,那这个ID你要写在哪呢?正常情况下要填在这个位置上,但是现在呢,我们没有写,那所以说呢,我们在顶层呢,要给啊设置一个这个全变啊,或者说啊,那都可以啊,那我们直接用一个吧,就是它是一个IDC啊,然后啊button。
31:23
嗯,Button啥干啥用的呢?就是push用的啊PUSH1,然后呢,给他选择一个这个消息编号,比如说这个呃19199,呃就就9999吧,0X9999,但是注意啊,注意我们这种东西啊,如果你要使用编号的情况下,尽量不要大于什么呢?尽量不要大于这个0X12344个F啊为什么呢?因为如果你大于四个F的情况下啊,那你这个东西在用的时候可能会产生一定的问题,为什么会产生问题呢?因为我们的控件消息呢,它是这样保存的啊,它这个W参数里边呢,它保存了两样东西啊,W参数里边的这个第16位啊,第16位保存的是你的这个通这个子窗口的ID啊,也就是我们现在定义这个东西,但是呢,它的高16位是有另外的作用的啊,它的高16位是保存的通知。
32:24
把。也就是消息类型啊,通知码也不算是消息类型吧,反正就是它是一个通知码,然后它的L参数整个保存的呢,是一个句柄。所以说呢,如果你他这个东西大于四个F的情况下呢,他就把这个子开这个子窗口的ID捅穿了啊,就捅到什么呢,捅到充值码那边去了,所以说呢,尽量不要这么用,而是什么呢?而是说啊,你保持在这个呃,你的16位以内啊16位以内好,那现在有这个东西之后呢,我现在呢,直接来到这个可这边啊改它干嘛呢,给他填上啊,在这填上,但是注意啊,你要给他强制类型转换一下,因为它这个东西默认情况下是填菜单的啊,你给他填一下HW呃,HMU呃M这个EMU啊好,现在呢就完事了啊,我们运行。
33:17
正常情况下这个按钮就可以可以来这个给他做消息处理了,那这个消息处理是在哪呢?正常情况下我们要按照这个消息来选择,比如说它是什么状态下的什么按钮,比如说我现在是左键,我要给他来一个左键单击啊,那这种左键单击的消息呢,你要在这个command里啊进行一个处理。在这啊wm command啊,然后呢,你现在在这儿呢,给他做一个处理,比如说我现在直接啊来这个进行Switch啊,进行一个分发啊,那我们刚才说了啊,我们这里边呢,W参数的高位啊,是这个控件点击类型的一个通知码,那我们使用一个这个啊就可以把它这个东西给取出来,取出来之后呢,直接用它做一个分发。
34:04
分发之后呢,我们直接case啊,比如说我现在case什么的case,我现在是一个按钮消息,那这些按钮消息呢,你可以在刚才这边啊给他找到,比如说我这个控件参考里边有这个按钮消息啊,比如这些东西都是干什么的,那我们现在呢,在左键啊,给他来这个产生的这个消息啊,我们啊不对,这控制消息啊,这是通知啊,我们要找通知通知啊,左键点击啊,你看啊,单击按钮是发送啊BN check的啊,然后如果是右键呢,它会加个R,那我们现在呢来这个。这是L的啊,然后右键是R的啊,然后现在呢,我们来拦截啊,它单击的消息,那么单击消息呢,我们直接就一个BN啊,然后的好,这就是左键单击的一个消息,然后左键单击消息呢,你愿意干点什么呢,你就干点什么啊,干什么都行,比如说我现在呢,直接在这弹个窗。
35:02
证明我现在呢,是点击了那个按压的一个这个八啊18。然后直接运行。点击诶,你看是不是push button就点击上了,对不对啊,这个就是我们的这控件消息的一个处理,然后呢,我们各种各样不同的消这个控件呢,它有不同的这个消息处理,那这些东西呢,都是在我们的MSN上描述的啊,首先这个是一个控件库,你可以看到啊,有什么控件啊,这个button啊,有这个下拉框啊,然后主合框啊,日期时间选择器,编辑框啊,什么乱七八糟数啊,什么列列表啊,Table啊这些东西啊,你可以看到在这都有啊,然后呢,你可以点开之后啊,而且它每一个东西里边都会有这个概述里都有一个如何去创建的这个东西,以及如何啊,比如这个是创建啊,然后呢,还有什么,还有它的一些这个使用的一些宏啊,以及消息,以及触发消息啊,是如何使用它的啊,这些东西呢,它里边都是有的好,然后呢,我们这个呢,就是我们的这个控件消息啊,那我们这个控件消息啊,简单的说了一个这个button的一个消息啊,然后呢,我们接下来啊,就看什么呢,看我们的这个自定义消息,自定义消息呢,其实顾名思义啊,我们就可以发送一个自己想要的消息出去啊,比如说我现在。
36:15
我在顶上啊,我定义一个红啊,定一个红啊,这个红呢,我们可以直接一个DeFine啊,然后呢,我们这是一个这个user message啊。Use message啊,然后随便起个名啊,正常情况下你应该是用这个user message啊,从0S8000开始,然后往上加啊,我这就不管了啊,我这就是一个测试用的消息啊,然后呢,比如说我给了一个0X啊,然后这个466啊,接下来呢,我就我就用这个东西啊,它是一个什么顶层消息,那你还可以给他定义什么子消息啊,比如说点这个DeFine啊,然后这个user啊,然后sub message啊,Sub message one啊,然后呢,这个是零一啊,这个0S1啊,这个这个只要不是顶级消息啊,你设置成什么鬼东西,其实都无所谓啊,那我们现在呢,把他们俩拿下来啊,进行什么进行消息处理,好在这儿啊,我们进行一个这个消息处理,我们首先呢,在这个顶层里边啊,来给他这个使用一下啊,Case一下这个消息。
37:14
比如说我kiss一下它,Kiss他之后呢,然后呢,我们来判断子消息啊,比如说我现在case在里边啊,进行一个Switch,我们case这个W参数啊,我们给他存W参数里,然后直接K它的一个子消息。啊,如果说触发了这个子消息的情况下啊,我们就直接,诶这什么情况。应输入K01扩展到X,嗯,啊,我这好像写写写分号了,把这个分号去掉。好,没点关注点点关注啊,每周六周日都有,同时都有直播,有需要这个课程的课件啊,然后还有这个录播视频的,可以联系咱们老板进行获取啊好,然后呢,我们继续啊,在这个位置上啊,我们给他这个处理一下啊break,然后弹出message box啊这呢,我们就直接给它弹出一个L啊自定义自定义消息啊然后。
38:18
LMGL啊,不对。我看一下啊,他现在是。好,然后我们现在呢,怎么去触发这个消息呢?我们去用这个我们的按钮啊,这个按钮我现在呢,直接干嘛把这给它注释掉,然后呢,使用我们的send message啊给它发送出去,发送到我们主窗口上是WND,然后主消息啊,Message上面的消息啊,用我们的这个user message test啊,然后子消息我们使用这个user,然后呢,这个L参数呢,我们随便带个字符串吧,测试。
39:08
换算了,我我直接把这个算了,我直接在这写一个测试啊,然后给它进行一个类型的强制转换,然后LPRAM,好,那这边呢,我这个自定义消息呢,我就不使用这个了啊,我直接使用一个这个L参数啊,进行一个打印得了啊。因为我这边发了个字符串过去啊,我可以直接这边进行打印啊,但是呢,你用的时候呢,要给它转换一下啊,使用这个W叉形成型类型转换啊,然后呢,我们运行。运行之后呢,现在我点击这个button啊,你看它发送消息发出去了,然后呢,它里边的内容呢,就是通过我们的L参数啊进行放过去的。好,然后点击确定,诶,他一直在发。哎,为什么会一直在发呢?啊,他break之后啊,就进入到菜单里头去了啊,然后又重新发,发完之后又下来了啊,那所以说呢,我们在这儿呢,我们不应该使用break,而是直接使用一个这个return啊,让他回去啊,如果如果进到这儿了,就是return一个处啊让他走就行了,不然的话呢,他就会继续把消息往下发,进入到这儿,然后又发消息又回来了,死循环了啊,然后呢,我们运行。
40:16
点击确定啊,点击确定你看这就没了啊,就是这个原因,好,那这个呢,就是我们的这个自定义消息,那么最后一个呢,就是我们的send message和post message的一个消息啊,那这个两个东西的消息呢,是这个区别是什么呢?就是它是阻塞和不阻塞的一个区别啊,这个是阻塞的啊,这个呢是不阻塞的啊,主要区别呢是这个是发送消息后会等待消息执行结束啊后返回啊,这个是什么?这个是发送消息后啊立即返回,还不等待啊,另外呢,如果说你这个东西不是一个SDK程序,而是一个MFC程序的情况下,他们俩发送到这个位置是不一样的啊,我们可以创建一个MFC程序来验证一下。
41:04
好,我们直接啊新建一个项目啊,然后呢,创建一个这个MFC的应用程序,点击确定,然后呢,使用静态库啊,点击完成,哎呀,选错了啊,重新建一下吧,我这选多文档了啊。不对啊,我们不能用多元档,我们用对话框啊。确定在静态公众使用,然后选择对话框啊,然后点击完成。好,然后现在呢,我们来直接啊,在它的这个资源里啊,资源文件里点开RC,然后点开dio啊,把它主O点出来,点出来是这个情况的,然后呢,我们把东西都删掉,删掉之后呢,右键属性啊,然后给它设置一下缓解库啊,把缓解库给它关了。在C加加代码商城里啊,这儿呢,把它关掉啊,点击应用点击确定,然后我们先运行一下,测试一下有没有问题。
42:06
好,你看没有问题,没有问题呢,我们现在呢,在上边拖两个空件下来啊,工具箱啊,我们搞两个八过来。一个BUTTON2个button啊,那我们这两个button呢,分别使用不同的方式啊进行发送啊,这个上边这个呢,我们使用的这个是的方式。下边这个呢,我们使用的是send的方式。好,那他们俩呢,我们都是需要在类向导里头给咱们创建一个虚函数啊,给它重构一个这个,给它创建一个虚函数,那我们如果说发出send,它会在这个P这个这个message里啊进行处理啊,我们直接添加函数。好,然后呢,如果说我们是这个用send方呢,它会直接发送到这个on wn message里啊,然后点击添加函数,好,那么这两个东西呢,我们可以看到啊,他们俩其实是一样的啊,只是它呢是分开四个东西了,这个东西呢是直接一个ma结构发过来了啊,然后呢,我们直接使用这个Switch啊,然后呢,Switch上边呢使用这个呢,是使用这个message啊进行一个分发,下边这个呢,我们就是使用呃直接这个message啊,我们使直接给它实现出来,然后再分啊,然后比如说我现在直接给一个这个1231个123啊,然后呢,然后case啊,14K125。
43:37
好,每一个呢,我都给他弹个窗啊麦bos。
44:08
啊对,直播回放可以联系咱们老满啊,这次屏幕上可以联系的来获取这个回放啊好,这是这个我们三个消息,123124125啊然后我把这个东西呢,同样的方式呢,放到我们的这个message这里啊,但是呢,这个分发呢,你要给它区别一下啊,这边呢是直接用message进行分发,然后呢,我们创建这个post的一个按键消息,然后直接啊使用这个post message啊进行一个发送,这这个因为是MFC啊,所以说呢,它第一个参数的这个副窗口句柄呢,它自动给你这个填上了啊,就不需要你自己填了啊然后呢,我现在呢,从第二个消息开始啊,我直接使用一个什么呢,使用一个这个123的这么一个消息啊发送过去,然后这个W参数呢,我们什么也不填,L参数呢,我也什么也不填,我就这么给他发过去了,好,然后呢,我连续发三条123啊124125。
45:03
好,然后呢,我现在运行。我直接点击post,你看123123啊,然后没了123啊,然后没了啊,我现在呢,来看一下它到底发生了什么,我在我的这个123上边啊,我给他我不是我在我的Switch上边啊,给他来点上一点,然后呢我直接运行。然后现在呢,哎呀不行啊,这样的话拦截的比较范围比较大啊,我重新写一下吧,我直接在这儿给他kiss一下什么呢?Kiss一下这个12138啊。这个消息,然后呢,我在消息内啊,再次进行二次分啊,这样呢,我们处理起来比较方便啊,我直接啊这个Switch啊,然后在这个W参数上再填一层啊。啊,这是使用的啊。
46:00
算了,我先把它放下来啊,然后这个message点。W,好,然后呢,底下那个呢也一样啊,然后一样复制一份过去啊。好,这样分发起来下顿点更方便啊,不会被一直拦运行啊,我们现在呢点击。下单点断下来了,这是是吗。啊,不对,我这消息发错了啊,我现在这个消息上面没有12138啊,要把主消息和子消息替一下啊,这现在呢,第一个是12138啊,这是主消息,然后呢,子消息是123啊,这是124,这是125啊,然后上面的主消息呢,是12138,好,现在呢,我运行运行之后呢,我点击我的铺子的,你看125124123,然后123啊,这是因为什么呢?这就是铺子的一个特性啊,然后我们来看一下。首先呢,我们这个东西呢,它首先呢,会发生到这个函数里来啊,它不会直接发生到下边那个函数去,然后我们现在呢,在这儿啊,拦截它W消息啊,因为我们是这个已经判断的主消息啊,进入了此消息之后判断,所以它不会一直被拦截,我们运行,运行之后你铺子铺子之后你看啊,它将会走到这,走到这之后没了。
47:13
诶。你看啊,他连续弹了三次看到了吧,为什么呢?因为这个东西呢,它这个东西发送出来之后,他就不管了啊put这个东西发送之后,它会立即返回,而你的消息它在什么地方,在消息列表里啊,那但这个东西发它不会发丢对不对啊,它会发到消息列表里,而消息列表里呢,会因为它这个会进行这个get,所以说呢,它不会丢东西,它会一直往外发,但是你可以看到它这个东西是三次访问完事之后,它一起一起进行这个message的,而不是说我过了一下回去一下,那我们再看一下这边啊,我们的send message它是怎么一个处理方式。我们在这下论点吧,然后这个也在这儿下个论点啊,然后我们啊给它加一个这个send的一个处理。
48:06
没点关注可以点点关注啊,每周六周日晚上都有直播啊,然后我们来运行。好,我点肾的,点完肾的我们运行,你看它会先到123这。弹弹完之后走回去,回去之后再继点继续,继续之后再下来到124这,然后弹弹完之后再回去,然后到消息处理完事,然后再继续,继续之后又发成这个消息到125这,到125这之后弹再回去,那你可以发现一个问题,他这个send每一次都是执行完自己整个消息之后,回来再发第二个消息,而不是三次消息一起发过去,发完之后他也不管有没有执行,然后就返回了,但是他的消息没有丢,都在消息列表里,所以说他等全都返回之后,三个message就一起执行了。这就是他们的一个区别啊。
49:02
而且他们的处理函数也不一样啊,这个这个post会先发到这儿啊,然后呢,如果是这个send,它会先发到这儿啊,这是他们的之间一个区别啊。好,有没有什么问题,如果没有问题,今天的技术部分啊,就到这儿了。有需要领东西的啊,可以直接找咱们的老满进行获取啊。
我来说两句