2.03 消息基础
消息组成(windows平台下)
6大部分(固定),linux则可以由程序员规定
- 窗口句柄
- 消息ID
- 消息的两个参数(两个附带信息)
- 消息产生的时间
- 消息产生时的鼠标位置
/*
* Message structure
*/
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
消息的作用
当系统通知窗口工作时,(DispatchMessage)就采用消息的方式派发给窗口(的窗口处理函数 (自己定义的那个))。
// 伪代码
DispatchMessage(&nMsg){
1.nMsg.hwnd-->保存窗口数据的内存-->WndProc(自定义窗口函数名称)
2.WndProc( // 派发前4个函数给窗口处理函数, 派发 = 调用这个函数
nMsg.hwnd, // 窗口句柄
nMsg.message, // 消息ID(数字 微软提供约1000种)
nMsg.wParam, // 第一个附带信息
nMsg.lParam // 第二个附带信息
)
3.返回自己的函数
}
窗口处理函数
每个窗口必须有窗口处理函数
LRESULT CALLBACK WindowProc(
HWND hwnd // 窗口句柄
UINT uMsg // 消息ID
WPARAM wParam // 消息参数1
LPARAM lParam // 消息参数2
)
当系统通知窗口时, 会调用窗口处理函数, 同时将消息ID和消息参数传递给该函数.
在处理函数中, 不处理的消息, 使用缺省窗口处理函数. 例如DefWindowProc
// 示例
LRESULT CALLBACK WndProd(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
switch (msgID) {
case WM_DESTROY: // 窗口退出时,退出该程序
PostQuitMessage(0);
break;
}
if (GetAsyncKeyState(VK_ESCAPE)) { // ESC键 退出该程序
PostQuitMessage(0);
}
return DefWindowProc(hWnd, msgID, wParam, lParam); // 默认处理函数 Windows处理剩下的情况
}
浅谈消息相关函数
GetMessage
获取本进程的消息
BOOL GetMessage(
LPMSG lpMsg, // 存放获取到消息BUFF. 获取消息后,将消息参数存入MSG结构中
HWND hWnd, // 窗口句柄. 获取到hWnd指定窗口的消息(NULL代表该进程所有消息)
UINT wMsgFilterMin,// 获取消息最小ID. 消息范围, 都是0代表都抓
UINT wMsgFilterMax,// 获取消息最大ID
)
while (GetMessage(&nMsg, NULL, 0, 0)) {
TranslateMessage(&nMsg); // 翻译消息
DispatchMessage(&nMsg); // 派发消息(谁处理消息 就派发给谁 -> 窗口处理函数)
}
话外:PostQuitMessage(0) 向”消息队列”中发送了 WN_QUIT
, 被GetMessage抓取到, 从而程序退出
TranslateMessage
翻译消息。将键盘按键消息(可见字符),翻译成字符消息。
可见字符: A-Z这种, 比如按不按Caps, 结果不一样, 所以要翻译
不可见:上下左右 F1F2
先检查是不是按键消息,如果不是,直接跳过
BOOL TranslateMessage(
CONST MSG*lpMsg//要翻译的消息地址
);
检查消息是否是按键的消息,如果不是按键消息,不做任何处理,继续执行。
DispatchMessage
派发消息
LRESULT DispatchMessage(
CONST MSG *lpmsg//要派发的消息
);
将消息派发到该消息所属窗口的窗口处理函数上。