win32学习07.Windows消息机制

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

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

先看包裹
包裹需要包含的信息:

//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_CLOSESC_MOVESC_MINIMIZE等等,类似于一个集合。
- WM_CLOSE,窗口关闭。
- WM_LBUTTONDOWN,鼠标左键按下。
- WM_CHAR,字符消息,TranslateMessage可还记得?
- WM_CREATE,窗口创建,还没显示。CreateWindowShowWindow中间,可以用来创建子窗口(按钮也算哦),初始化窗口等等。
- WM_SIZE,大小变化,创建的时候也会调用。
- WM_QUIT,结束消息循环处理。
- WM_PAINT,绘制,需要绘制的区域称为窗口无效区域

//WM_PAINT专属方法:BeginPaint,EndPaint
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps); 
//怎么画加在这里
EndPaint(hwnd,&ps);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的提千万

江山父老能容我,不使人间造孽钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值