1.消息处理---鼠标消息:

1.ExMessage结构体:

ExMessage---这个结构体用于保存鼠标消息。

//定义消息结构体变量
ExMessage msg = { 0 };

2.获取消息:

(1)peekmessage函数:

用于获取一个消息,并立即返回。

bool peekmessage(ExMessage *msg, BYTE filter = -1, bool removemsg = true);

参数:

msg:指向消息结构体 ExMessage 的指针,用来保存获取到的消息。

filter:默认 -1 获取所有类别的消息。可以用以下值或值的组合获取指定类别的消息:

removemsg:在 peekmessage 处理完消息后,是否将其从消息队列中移除。

返回值:

如果获取到了消息,返回 true,如果当前没有消息,返回 false。

(2)获取鼠标按键情况:

peekmessage函数会将消息保存到 ExMessage 结构体中,只需查看 msg.message (一个成员变量)的内容即可知道按了什么键。

msg.message 可以成为以下值:

	//获取消息
	while (1)
	{
		if (peekmessage(&msg, EX_MOUSE))
		{
			switch (msg.message)
			{
			case WM_LBUTTONDOWN	:			
					cout << "鼠标左键按下\n" << endl;
					break;			
			case WM_RBUTTONDOWN	:			
					cout << "鼠标右键按下\n" << endl;
					break;			
			case WM_MBUTTONDOWN	:			
					cout << "鼠标中键按下\n" << endl;
					break;			
			case WM_MOUSEWHEEL:	:			
					cout << "鼠标滚轮滚动\n" << endl;
					break;	
            case WM_LBUTTONDBLCLK :
					cout << "鼠标左键双击" << endl;
					break;	    		
			}
		}
	}

注:检测鼠标双击必须在 initgraph 函数参数中传入 EX_DBLCLKS(详见上篇)。

(3)获取按键时鼠标位置:

msg.x ; msg.y 中保存了按键时鼠标的位置坐标。

例:将上面代码改为:

case WM_LBUTTONDOWN	:			
		cout << "鼠标左键按下 pos("<<msg.x<<","<<msg.y<<")" << endl;

(4)获取滚轮时滚动方向:

msg.wheel 中保存了滚轮时滚动方向:

向屏幕滚动为120 ,向自己为 -120。

2.消息处理---按钮:

1.封装按钮函数:

//鼠标处于按钮区域
bool inArea(int mx, int my, int x, int y, int w, int h)
{
	if (msg.x > x && msg.x < x + w && msg.y > y && msg.y < y + h)
	{
		return true;
	}
	return false;
	
}
//按钮绘制且判断是否点击
bool button(int x, int y, int w, int h, const char* text)
{
	//绘制按钮
	setfillcolor(RGB(230, 231, 232));
	fillroundrect(x, y, x + w, y + h, 5, 5);

	//绘制文本
	int hSpace = (w - textwidth(text)) / 2;
	int vSpace = (h - textheight(text)) / 2;
	outtextxy(x + hSpace, y + vSpace, text);

	//判断按钮是否被点击
	if (msg.message == WM_LBUTTONDOWN&&inArea(msg.x,msg.y,x,y,w,h))
	{
		return true;
	}
	return false;
}

2.双缓冲绘图:

所有的绘图代码必须放在BeginBatchDraw和EndBatchDraw之间,否则会发生闪烁现象。

两个函数用途:BeginBatchDraw函数将绘图操作保存不输出,直至遇到EndBatchDraw才输出。

BeginBatchDraw();
if (button(20, 20, 150, 35, "Start Game"))
{
	printf("Start Game!");
}
EndBatchDraw();

3.按钮可点击时变色:

只需当鼠标在按钮区域时更换填充颜色即可:

//绘制按钮
if (inArea(msg.x, msg.y, x, y, w, h))
{		
    setfillcolor(RGB(93, 107, 153));
}
else  setfillcolor(RGB(230, 231, 232));
fillroundrect(x, y, x + w, y + h, 5, 5);

4.每次循环重置msg的消息:

在循环结尾加

msg.message = 0;

作用:保证每次点击只执行一次内容。

原因:将msg设置为全局变量后,除非鼠标再发生变化(移动,松开),否则msg中message始终为左键点击状态,导致不断执行点击后的内容。

3.消息处理---按键消息:

1.msg.message的可为值:

(也可见上面的图)

2.具体判断是哪个键按下:

msg中有一个变量为 vkcode 保存具体按键的虚拟键值:

常用键值:

(1)上下左右键:

(2)空格键:

(3)字母键:

大写的相应字母加单引号:如键A 即为 ‘A’

在微软网站上列出有所有的虚拟键码:Virtual-Key Codes (Winuser.h) - Win32 apps | Microsoft Learn

例:

if (msg.message == WM_KEYDOWN)
{
	printf("keydown");
	//具体判断是哪个键按下
	switch (msg.vkcode)
	{
	case VK_UP:
		printf("上箭头");			
	case VK_DOWN:
		printf("下箭头");			
	case VK_LEFT:
		printf("左箭头");			
	case VK_RIGHT:
		printf("右箭头");
	case 'A':
		printf("A键");
	default:
		break;
	}
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐