博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
win32学习07.Windows消息机制
阅读量:6266 次
发布时间:2019-06-22

本文共 2985 字,大约阅读时间需要 9 分钟。

hot3.png

程序运行有两种,一种是流程式的,一种是回调式的。流程式的会按照设定好的路线,走完就可以了;回调式的会根据用户的输入进行判断,做出不同的处理。一个仿佛看电影,一个仿佛打游戏。

如果需要实现回调式的,就需要消息。操作系统就是典型。不管是信号池还是消息队列,都是将消息统一管理。打个比方:消息就像包裹,每个进程就仿佛一个家,我可以给另一个人家里发包裹,但是都要快递,如果所有人都去快递公司拿,快递公司直接炸了,如果快递到家门口,再去拿,效率就快多了。这个快递的过程,就是消息队列。

先看包裹

包裹需要包含的信息:

//MSG结构体:typedef struct tagMSG {               HWND   hwnd;      //句柄,属于哪个窗口的        UINT   message;   //消息ID,不同数值表示不同消息        WPARAM wParam;    //附加信息1        LPARAM lParam;    //附加信息2        DWORD  time;      //时间        POINT  pt;        //鼠标位置} MSG;

大约就是哪一户的包裹,什么类型的,里面有什么。

包裹处理方式

每个消息都会对应一个处理函数,不然你拿了包裹干啥,即消息处理函数。

LRESULT CALLBACK WindowProc(      HWND hwnd,      // handle to window,句柄    UINT uMsg,      // message identifier,消息ID    WPARAM wParam,  // first message parameter,参数1    LPARAM lParam   // second message parameter,参数2);{    //里面写处理方式}

拿快递、送快递和寄快递

方式1:

BOOL PostMessage(      HWND hWnd,      // handle to destination window,句柄    UINT Msg,       // message,消息    WPARAM wParam,  // first message parameter,参数1    LPARAM lParam   // second message parameter,参数2);//基本和消息相关的函数都有这几个参数//PostMessage类似非挂号信,和所有的快递一起进去快递公司(系统消息队列),然后配发(发给对应窗口即进程的消息队列),然后用户来取。至于用户取了没,不管,送了就走了。//对应的取快递的函数:BOOL GetMessage(  LPMSG lpMsg,         // message information,消息存放缓冲区  HWND hWnd,           // handle to window,窗口句柄  UINT wMsgFilterMin,  // first message,最大ID  UINT wMsgFilterMax   // last message,最小ID,如果都为0表示没有范围限制);//消息ID分类:系统的(0-0x03ff),自己定义的(0x400-ox7FF),应用程序之间通信用(0x800-0xBFF),系统注册消息(0xc000-oxffff)//这个取的方式很蠢,一直在楼下等,阻塞了进程,浪费CPU//前台,只看着,来快递了就喊你去拿,非阻塞,进程该干啥干啥BOOL PeekMessage(  LPMSG lpMsg,         // message information  HWND hWnd,           // handle to window  UINT wMsgFilterMin,  // first message  UINT wMsgFilterMax,  // last message  UINT wRemoveMsg      // removal options,是否移除);//是否移除标志:PM_NOREMOVE和PM_REMOVE,前者是不从消息队列中移除,后者是移除,和getmessage一样。/********************** 两个函数共同的处理流程: *在进程找符合要求的(窗口句柄和ID范围),有就取包裹。 *找不到就找系统消息队列要一下。 *系统消息队列也没有,就看看是不是要重绘,需要就WM_PAINT。 *没有要重绘的就看看定时器,有的WM_TIMER。 *也没有定时器就整理下程序资源。 ***********************///取了包裹之后:BOOL TranslateMessage(      CONST MSG *lpMsg   // message information,消息的地址);//判断是不是按键消息,是的话就WM_CHAR,不是就过。LRESULT DispatchMessage(      CONST MSG *lpmsg   // message information);//得到消息,找窗口处理函数,找到就执行,返回结果。

方式2:

//自己送LRESULT SendMessage(  HWND hWnd,      // handle to destination window  UINT Msg,       // message   WPARAM wParam,  // first message parameter  LPARAM lParam   // second message parameter );//这个就简单多了,自己跑一趟,找到对应的处理函数,执行,返回结果。//但是自己跑很累,虽然更快,所以重要的消息可以用下。

常用的消息

- WM_DESTORY,销毁的时候触发,善后处理。 - WM_SYSCOMMAND,系统命令消息,比如最大最小化,关闭等等。传入命令和鼠标位置。SC_CLOSE,SC_MOVE,SC_MINIMIZE等等,类似于一个集合。 - WM_CLOSE,窗口关闭。 - WM_LBUTTONDOWN,鼠标左键按下。 - WM_CHAR,字符消息,TranslateMessage可还记得? - WM_CREATE,窗口创建,还没显示。CreateWindow和ShowWindow中间,可以用来创建子窗口(按钮也算哦),初始化窗口等等。 - WM_SIZE,大小变化,创建的时候也会调用。 - WM_QUIT,结束消息循环处理。 - WM_PAINT,绘制,需要绘制的区域称为窗口无效区域  //WM_PAINT专属方法:BeginPaint,EndPaintHDC hDC;PAINTSTRUCT ps;hDC=BeginPaint(hwnd,&ps); //怎么画加在这里EndPaint(hwnd,&ps);

转载于:https://my.oschina.net/HappyTeemo/blog/1558473

你可能感兴趣的文章
jdk目录详解及其使用方法
查看>>
说说自己对RESTful API的理解s
查看>>
通过layout实现可拖拽自动排序的UICollectionView
查看>>
服务器错误码
查看>>
javascript中的面向对象
查看>>
Splunk作为日志分析平台与Ossec进行联动
查看>>
yaffs文件系统
查看>>
Mysql存储过程
查看>>
NC营改增
查看>>
Lua
查看>>
Mysql备份系列(3)--innobackupex备份mysql大数据(全量+增量)操作记录
查看>>
postgresql 获取刚刚插入的数据主键id
查看>>
C# Activex开发、打包、签名、发布 C# Activex开发、打包、签名、发布 [转]
查看>>
05-Vue入门系列之Vue实例详解与生命周期
查看>>
验证码展示
查看>>
浅谈大型web系统架构
查看>>
淘宝大秒系统设计详解
查看>>
linux如何修改登录用户密码
查看>>
Kali Linux 2017中Scapy运行bug解决
查看>>
Python监控进程性能数据并画图保存为PDF文档
查看>>