VC绘图/游戏简易教程--10:用鼠标控制绘图/游戏程序
作者:BestAns

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

学习本节课前,需要熟练掌握第 7 节。详见:http://www.easyx.cn/skills/View.aspx?id=21

==本节课开始==

捕获鼠标消息就像捕获按键消息一样简单。
对于按键,通常我们会先检查是否有按键,然后定义一个变量保存按键,再然后根据该按键的值,执行相应的程序。
对于鼠标,道理是一样的。

先写个代码对比一下:

获取按键:               获取鼠标:
  char c;                    MOUSEMSG m;
  if (kbhit())               if (MouseHit())
      c = getch();               m = GetMouseMsg();

很简单吧。由于鼠标消息的内容太多,不像按键那么简单,因此需要用一个结构体来保存。通过该结构体,我们可以获取鼠标的如下信息:

struct MOUSEMSG
{
	UINT uMsg;      // 当前鼠标消息
	bool mkCtrl;    // Ctrl 键是否按下
	bool mkShift;   // Shift 键是否按下
	bool mkLButton; // 鼠标左键是否按下
	bool mkMButton; // 鼠标中键是否按下
	bool mkRButton; // 鼠标右键是否按下
	int x;          // 当前鼠标 x 坐标
	int y;          // 当前鼠标 y 坐标
	int wheel;      // 鼠标滚轮滚动值
};

其中,“当前鼠标消息”可以是以下值:

  • WM_MOUSEMOVE     鼠标移动消息
  • WM_MOUSEWHEEL    鼠标滚轮拨动消息
  • WM_LBUTTONDOWN   左键按下消息
  • WM_LBUTTONUP     左键弹起消息
  • WM_LBUTTONDBLCLK 左键双击消息
  • WM_MBUTTONDOWN   中键按下消息
  • WM_MBUTTONUP     中键弹起消息
  • WM_MBUTTONDBLCLK 中键双击消息
  • WM_RBUTTONDOWN   右键按下消息
  • WM_RBUTTONUP     右键弹起消息
  • WM_RBUTTONDBLCLK 右键双击消息

例如,判断获取的消息是否是鼠标左键按下,可以用:

if (m.uMsg == WM_LBUTTONDOWN)
	...

下面举一个综合的例子(我偷点懒,直接粘贴的绘图库帮助里面的鼠标范例),该程序会用红色的点标出鼠标移动的轨迹,按左键画一个小方块,按Ctrl+左键画一个大方块,按右键退出:

#include <graphics.h>
#include <conio.h>

void main()
{
	// 初始化图形窗口
	initgraph(640, 480);
	
	MOUSEMSG m;						// 定义鼠标消息
	while(true)
	{
		// 获取一条鼠标消息
		m = GetMouseMsg();

		switch(m.uMsg)
		{
			case WM_MOUSEMOVE:		// 鼠标移动的时候画红色的小点
				putpixel(m.x, m.y, RED);
				break;

			case WM_LBUTTONDOWN:	// 如果点左键的同时按下了 Ctrl 键
				if (m.mkCtrl)		// 画一个大方块
					rectangle(m.x-10, m.y-10, m.x+10, m.y+10);
				else				// 画一个小方块
					rectangle(m.x-5, m.y-5, m.x+5, m.y+5);
				break;

			case WM_RBUTTONUP:
				return;				// 按鼠标右键退出程序
		}
	}

	// 关闭图形窗口
	closegraph();
}

[本节作业]

1. 画一个填充的三角形,要用鼠标点选三角形的三个顶点。提示:可以用 fillpoly 函数画多边形。

2. 写一个“格子涂色”的游戏,要求:屏幕上有16x8的格子,屏幕底部有类似画笔中的选色区(随便放上一些常用的颜色),鼠标点击选择区的颜色后,就作为当前颜色,然后再点屏幕上的格子,就可以用刚才的颜色填涂相应格子。

更新时间:2010/5/21