这里是limou3434的一篇个人博文,感兴趣可以看看我的其他内容。本次我给您带来的是easyX有关消息的函数与结构体解读。
0.消息处理相关函数和结构体概览
函数或数据类型 | 描述 |
---|---|
ExMessage | 消息结构体。 |
getmessage | 获取一个消息。如果当前消息缓冲区中没有,就一直等待。 |
peekmessage | 获取一个消息,并立即返回。 |
flushmessage | 清空消息缓冲区。 |
这里先提前说明一下消息的作用,平日我们使用电脑的时候,经常会使用鼠标,键盘等向电脑输入信息,而本节处理的消息就包含这些鼠标消息和键盘消息,通过消息,我们可以更好做出能与用户交互的程序。
1.ExMessage:消息结构体
该结构体可以保存一些信息。
struct ExMessage
{
USHORT message; //消息标识,有值表,后面会提到
union
{
//鼠标消息的数据
struct
{
bool ctrl :1; //Ctrl键是否按下
bool shift :1; //Shift 键是否按下
bool lbutton :1; //鼠标左键是否按下
bool mbutton :1; //鼠标中键是否按下
bool rbutton :1; //鼠标右键
short x; //鼠标的x坐标
short y; //鼠标的y坐标
short wheel; //鼠标滚轮滚动值,为120的倍数
};
//按键消息的数据
struct
{
BYTE vkcode; // 按键的虚拟键码
BYTE scancode; // 按键的扫描码(依赖于OEM)
bool extended :1; // 按键是否是扩展键
bool prevdown :1; // 按键的前一个状态是否按下
};
//字符消息的数据
TCHAR ch;
//窗口消息的数据
struct
{
WPARAM wParam;
LPARAM lParam;
};
};
};
//参数解读1
//message:消息标识,后面有专门的表格解读
//ctrl:Ctrl键是否按下。仅当消息所属类别为EX_MOUSE时有效。
//shift:Shift键是否按下。仅当消息所属类别为EX_MOUSE时有效。
//lbutton:鼠标左键是否按下。仅当消息所属类别为EX_MOUSE时有效。
//mbutton鼠标中键是否按下。仅当消息所属类别为EX_MOUSE时有效。
//rbutton:鼠标右键是否按下。仅当消息所属类别为EX_MOUSE时有效。
//x:当前鼠标x坐标(物理坐标)。仅当消息所属类别为EX_MOUSE时有效。
//y:当前鼠标y坐标(物理坐标)。仅当消息所属类别为EX_MOUSE时有效。
//wheel:鼠标滚轮滚动值,为120的倍数。仅当消息所属类别为EX_MOUSE时有效。
//参数解读2
//vkcode:按键的虚拟键码。仅当消息所属类别为EX_KEY时有效。
//在微软网站上列出有所有的虚拟键码:https://docs.microsoft.com/windows/win32/inputdev/virtual-key-codes
//scancode:按键的扫描码(依赖于OEM)。仅当消息所属类别为EX_KEY时有效。
//extended:按键是否为扩展按键,例如功能键和数字键盘。仅当消息所属类别为 EX_KEY 时有效。
//prevdown:按键的前一个状态是否为按下。仅当消息所属类别为EX_KEY时有效。
//参数解读3
//ch:收到的字符。仅当消息所属类别为EX_CHAR时有效。
//参数解读4
//wParam:消息对应的wParam参数。仅当消息所属类别为EX_WINDOW时有效。
//lParam:消息对应的lParam参数。仅当消息所属类别为EX_WINDOW时有效。
对于message成员为消息标识,有以下取值:
消息标识 | 消息类别 | 描述 |
---|---|---|
WM_MOUSEMOVE | EX_MOUSE | 鼠标移动消息。 |
WM_MOUSEWHEEL | 鼠标滚轮拨动消息。 | |
WM_LBUTTONDOWN | 左键按下消息。 | |
WM_LBUTTONUP | 左键弹起消息。 | |
WM_LBUTTONDBLCLK | 左键双击消息。 | |
WM_MBUTTONDOWN | 中键按下消息。 | |
WM_MBUTTONUP | 中键弹起消息。 | |
WM_MBUTTONDBLCLK | 中键双击消息。 | |
WM_RBUTTONDOWN | 右键按下消息。 | |
WM_RBUTTONUP | 右键弹起消息。 | |
WM_RBUTTONDBLCLK | 右键双击消息。 | |
WM_KEYDOWN | EX_KEY | 按键按下消息 |
WM_KEYUP | 按键弹起消息。 | |
WM_CHAR | EX_CHAR | 字符消息。 |
WM_ACTIVATE | EX_WINDOW | 窗口激活状态改变消息。 |
WM_MOVE | 窗口移动消息。 | |
WM_SIZE | 窗口大小改变消息。 |
2.getmessage:一直等到获取消息
如果当前消息缓冲区中没有,就一直等待。
ExMessage getmessage(BYTE filter = -1);
void getmessage(ExMessage *msg, BYTE filter = -1);
//参数
//msg:指向消息结构体 ExMessage 的指针,用来保存获取到的消息。
//filter:指定要获取的消息范围,默认 -1 获取所有类别的消息。可以用以下值或值的组合获取指定类别的消息:
//标志 描述
//EX_MOUSE 鼠标消息。
//EX_KEY 按键消息。
//EX_CHAR 字符消息。
//EX_WINDOW 窗口消息。
//返回值
//重载1返回保存有消息ExMessage的结构体。
//重载2没有返回值。
下面是easyX库文档里留有的演示例子,主要演示了getmessage()以及结构体ExMessage的使用:
#include <graphics.h>
int main()
{
//1.初始化图形窗口
initgraph(640, 480, EX_SHOWCONSOLE);
//2.定义消息变量
ExMessage m;
while (true)
{
//3.获取一条鼠标或按键消息
m = getmessage(EX_MOUSE | EX_KEY);
switch (m.message)
{
case WM_MOUSEMOVE:
//3.1.鼠标移动的时候画红色的小点
putpixel(m.x, m.y, WHITE);
break;
case WM_LBUTTONDOWN:
//3.2.如果点左键的同时按下了Ctrl键
if (m.ctrl)
//3.2.1画一个大方块
rectangle(m.x - 10, m.y - 10, m.x + 10, m.y + 10);
else
//3.2.2.画一个小方块
rectangle(m.x - 5, m.y - 5, m.x + 5, m.y + 5);
break;
case WM_KEYDOWN:
//4.按下ESC键退出程序
if (m.vkcode == VK_ESCAPE)
return 0;
}
}
//5.关闭图形窗口
closegraph();
return 0;
}
3.peekmessage:立刻返回获取的消息
这个函数用于获取一个消息,并立即返回(没有获取到消息也会立刻返回,只不过返回false罢了)。
bool peekmessage(ExMessage *msg, BYTE filter = -1, bool removemsg = true);
//参数
//msg:指向消息结构体ExMessage的指针,用来保存获取到的消息。
//filter:指定要获取的消息范围,默认-1获取所有类别的消息。其他取值见上方表格。
//removemsg:在 peekmessage 处理完消息后,是否将其从消息队列中移除
//返回值
//如果获取到了消息,返回true。
//如果当前没有消息,返回false。
peekmessage()和getmessage()最大的差别就在于:有些场景下,如果使用getmessage()会使得程序处于“停滞状态”,例如:在某些游戏里,我们可能需要释放技能,但是程序不可能使用getmessage()后一直等着用户选择技能(这个时候游戏的逻辑被终止了),而应该是在用户思考选择某些技能的同时,游戏依旧在运。因此使用peekmessage()要更为合理一些。
4.flushmessage:清空消息缓冲区
这个函数可以清空目前的消息缓冲区。
void flushmessage(BYTE filter = -1);
//参数
//filter:指定要清空的消息范围,默认-1清空所有类别的消息,其他取值见上方表格。
//返回值
//无