windows编程基础篇 -- 消息

来源:互联网 发布:jira mysql驱动 win7 编辑:程序博客网 时间:2024/06/03 16:34

win32编程基本流程@ ->写回调/处理函数(由于是给系统调用处理消息的,所以参数只HWND,MSGID,WPARAM,LPARAM
->设计窗口类(写入操作系统内核,绑定的重要资源是进程实例号(hInstatnce)和类名(className)
->创建窗口(会去内核找到类名和实例号匹配的对应窗口类并返回,顺序是局部-全局-系统窗口类)
->显示窗口(ShowWindow的意义在于会发送消息WM_PAINT)
->处理消息循环(老规矩GetMessage{TranslateMessage;DispatchMessage;}
传统的程序采用过程驱动方式,而Windows则是事件驱动,也就是你不知道程序下一步会执行到哪,由随机触发事件决定,其实也就
是一种基于消息的机制,所以理解windows基本流程第一步还是要从消息队列出发
======================——正题开始—–========================
PA.
消息MSG这个结构体分6个参数 HWND MSGID WPARAM LPARAM TIME PT 前面4个是用户可以自己修改的,后面两个一个时
间一个光标位置则是投递消息时系统帮你写的,你无法修改,所以在SendMessage/PostMessage这
样的投递消息函数中只有4个参数HWND MSGID WPARAM LPARAM
理解和区别各种系统消息重要的3点是@ 消息产生时间(硬件驱动产生还是GetMessage函数发出或用户?)
消息产生时传递的参数(WPARAM LPARAM)
该类消息的一般应用
所以文章的最后给出就是典型消息传递的参数信息和附加说明

PB.
消息要走队列,Windows的消息队列分两种: 系统消息队列 -><派发> 应用程序消息队列(细分线程消息队列)
所有的消息都是先投递到系统消息队列(PostMessage),这里相当于邮局总部
然后系统每过一段时间将消息投递到对应的应用程序消息队列(各分部),而后对应程序
调用GetMessage/PeekMessage函数来取消息
所以windows程序在初始化窗口后就一直跑在了消息循环那里,也就是一直等消息调用函数去取消息,而系统则会一直
将对应消息派发到对应队列里,一旦有一个WM_QUIT消息给出,GetMessage函数就会返回
FALSE,程序退出,记住这才是退出,所有的窗口销毁和程序退出没半毛关系,窗口相当于资源,
和你程序里的int变量无太大区别,别被视觉欺骗。
取消息函数GetMessage/PeekMessage函数区别:
它们都能从程序消息队列里取消息,不同是a.GetMessage函数是阻塞函数,而PeekMessage
不是,如果没有消息它会返回,使用它程序不会因没消息而进入睡眠.
b.GetMessage在取完后一定从队列里移除消息,
PeekMessage可以选择不移除,即用它来检查有没有消息。
最后,二者具体取消息流程如下:
1)从进程消息队列里取消息,有则返回,无则下一步。
2)想系统消息队列询问有没有消息,系统会提前检查系统消息队列有没有对应该线程的消息,
有将对应消息取出派发到线程消息队列,没有下一步。
3)检查需不需要发出WM_PAINT消息,即哪些窗口需要重绘,没有下一步。
4)检查有没有定时器WM_TIMER消息产生(所以定时器消息经常有略微延迟,消息响应被推后了),
没有下一步。
5)整理资源、内存。
6)至此事情做完了,没有消息函数无法返回,GetMessage选择等待,PeekMessage则会退出。
发送消息函数SendMessage/PostMessage区别:
SendMessage不会将消息投递到队列当中,它会在函数内部自己调用消息处理函数来处理这个消息,
并且等待消息处理函数的返回 ,即需要等待。
PostMessage是真正的投递消息函数, 它会将消息投递到系统消息队列并立刻返回.
PC.
消息ID范围
0x0000 - 0x03FF 系统消息 共 1024条
0x0400 - 0x7FFF 用户自定义消息 基值WM_USER(0x0400)
0x8000 - 0xBFFF 应用程序消息,用于程序之间的通信
0xC000 - 0xFFFF 系统注册消息
对于软件开发的只需要记住前两条就可以
系统消息传参表
WPARAM LPARAM 附带说明
WM_DESTROY 无 无 窗口销毁产生的消息,常用于回收资源
WM_SYSCOMMAND 具体位置 水平+垂直位置 点击最大化最小化关闭按钮时产生
WM_CREATE 无 CREATESTRUCT 显示窗口前创建子窗口
WM_SIZE 原因 改变后的宽度+高度 窗口大小发生改变时
WM_QUIT PostMessage参数 无 使GetMessage函数FALSE
WM_PAINT 无 无 想手动产生,调用InValidateRect函数
WM_KEYDOWN virtual key 按键其它参数 KEYDOWN按下一直产生,KEYUP只一次
WM_CHAR char 相关参数 TranslateMessage发出的消息
WM_LBUTTONDOWN 其他按键(ctrl,alt,rbutton) x坐标+y坐标(滚轮偏移) 鼠标消息
WM_TIMER 定时器ID 定时器处理函数 LPARAM为NULL,调用消息处理函数
最后的WM_TIMER消息调用哪个函数是由DispatchMessage函数决定的,它会检查LPARAM是不是为NULL

PD.
不是所有消息都要走队列,像SendMessage函数就会直接把消息调用回调函数处理而不进队列等待。
队列消息:WM_PAINT,键盘,鼠标。
非队列消息:WM_CREATE WM_SIZE (因为这是创建窗口后和显示窗口时产生的,此时还没进入消息循环,只能走非
队列)

0 0
原创粉丝点击