编译环境:VS2017+Easy_X
最近笔者一直在翻阅Easy_X的帮助手册,学习到了一些关于获取鼠标状态消息函数的知识,感觉收获颇大,于是想试验一番,将所学知识运用出来。先补充一下在Easy_X中的一些鼠标函数和结构体吧。在下面的程序中,只用到了GetMouseMsg函数和MOUSEMSG结构体。
FlushMouseMsgBuffer
这个函数用于清空鼠标消息缓冲区。
void FlushMouseMsgBuffer();
参数:
(无)
返回值:
(无)
GetMouseMsg
这个函数用于获取一个鼠标消息。如果当前鼠标消息队列中没有,就一直等待。
MOUSEMSG GetMouseMsg();
参数:
(无)
返回值:
返回保存有鼠标消息的结构体。
MouseHit
这个函数用于检测当前是否有鼠标消息。
bool MouseHit();
参数:
(无)
返回值:
如果存在鼠标消息,返回 true;否则返回 false。
MOUSEMSG
这个结构体用于保存鼠标消息,定义如下:
struct MOUSEMSG
{
UINT uMsg; // 当前鼠标消息
bool mkCtrl; // Ctrl 键是否按下
bool mkShift; // Shift 键是否按下
bool mkLButton; // 鼠标左键是否按下
bool mkMButton; // 鼠标中键是否按下
bool mkRButton; // 鼠标右键是否按下
int x; // 当前鼠标 x 坐标(物理坐标)
int y; // 当前鼠标 y 坐标(物理坐标)
int wheel; // 鼠标滚轮滚动值
};
成员:
uMsg:
指定鼠标消息类型,可为以下值:
值 | 含义 |
---|---|
WM_MOUSEMOVE | 鼠标移动消息。 |
WM_MOUSEWHEEL | 鼠标滚轮拨动消息。 |
WM_LBUTTONDOWN | 左键按下消息。 |
WM_LBUTTONUP | 左键弹起消息。 |
WM_LBUTTONDBLCLK | 左键双击消息。 |
WM_MBUTTONDOWN | 中键按下消息。 |
WM_MBUTTONUP | 中键弹起消息。 |
WM_MBUTTONDBLCLK | 中键双击消息。 |
WM_RBUTTONDOWN | 右键按下消息。 |
WM_RBUTTONUP | 右键弹起消息。 |
WM_RBUTTONDBLCLK | 右键双击消息。 |
mkCtrl
Ctrl 键是否按下
mkShift
Shift 键是否按下
mkLButton
鼠标左键是否按下
mkMButton
鼠标中键是否按下
mkRButton
鼠标右键是否按下
x
当前鼠标 x 坐标(物理坐标)
y
当前鼠标 y 坐标(物理坐标)
wheel
鼠标滚轮滚动值,为 120 的倍数。
我写的代码如下:
#include "stdafx.h"
#include <graphics.h> void twopiont();
void pen();
void chalk(); void main()
{
initgraph(, ); //初始化图形界面,窗口分辨率设置为640*480
MOUSEMSG p; //定义一个鼠标的结构体
RECT r1 = { , , , };// 在屏幕右侧输出字符串
drawtext(_T("----------"), &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
RECT r2 = { , , , };
drawtext(_T("1.钢笔"), &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
RECT r3 = { , , , };
drawtext(_T("2.粉笔"), &r3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
RECT r4 = { , , , };
drawtext(_T("3.两点画线"), &r4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
RECT r5 = { , , , };
drawtext(_T("---------"), &r5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
RECT r6 = { , , , };
drawtext(_T("单击鼠标右键"), &r6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
RECT r7 = { , , , };
drawtext(_T("切换选项"), &r7, DT_CENTER | DT_VCENTER | DT_SINGLELINE); while (true)
{
p = GetMouseMsg();
if (p.uMsg == WM_LBUTTONDOWN) pen();
if (p.uMsg == WM_LBUTTONDOWN) chalk();
if (p.uMsg == WM_LBUTTONDOWN) twopiont();
} } /**************实现在两点之间画一条直线**************/
void twopiont()
{
int x0, y0, x1, y1;
MOUSEMSG m; // 定义鼠标消息
while (true)
{
flag: //重置开始
m = GetMouseMsg();// 获取一次鼠标消息
switch (m.uMsg)
{
case WM_LBUTTONDOWN:x0 = m.x; y0 = m.y; //鼠标第一次按下时,得到坐标(x0,y0)
while (true)
{
m = GetMouseMsg();// 获取一条鼠标消息
switch (m.uMsg)
{
case WM_LBUTTONDOWN:x1 = m.x; y1 = m.y;//鼠标第二次按下时,得到坐标(x1,y1)
line(x0, y0, x1, y1);
goto flag; //跳回到flag处进行重置
break;
case WM_RBUTTONUP:
return; // 按鼠标右键退出函数
}
}
break;
case WM_RBUTTONUP:
return; // 按鼠标右键退出函数
}
} } /****************实现钢笔功能****************/
void pen()
{
int x0, y0;
MOUSEMSG m; // 定义鼠标消息
while (true)
{
flag: //重置开始
m = GetMouseMsg();// 获取一次鼠标消息
switch (m.uMsg)
{
case WM_LBUTTONDOWN:x0 = m.x; y0 = m.y; //鼠标第一次按下时,得到坐标(x0,y0)
while (true)
{
m = GetMouseMsg();// 获取一条鼠标消息
line(x0, y0, m.x, m.y);
x0 = m.x; y0 = m.y;
switch (m.uMsg)
{
case WM_LBUTTONUP:
goto flag; //跳回到flag处进行重置
break;
case WM_RBUTTONUP:
return;// 按鼠标右键退出函数
}
}
break;
case WM_RBUTTONUP:
return;
// 按鼠标右键退出函数
}
}
} /****************实现粉笔功能****************/
void chalk()
{
int x0, y0; // 绘图环境初始化
MOUSEMSG m; // 定义鼠标消息
while (true)
{
flag: //重置开始
m = GetMouseMsg();// 获取一次鼠标消息
switch (m.uMsg)
{
case WM_LBUTTONDOWN:x0 = m.x; y0 = m.y; //鼠标第一次按下时,得到坐标(x0,y0)
while (true)
{
m = GetMouseMsg();// 获取一条鼠标消息
switch (m.uMsg)
{
case WM_MOUSEMOVE:
fillcircle(m.x, m.y, );// 画一个填充圆
break; case WM_LBUTTONUP:
goto flag; //跳回到flag处进行重置
break;
case WM_RBUTTONUP:
return; // 按鼠标右键退出函数
}
}
break;
case WM_RBUTTONUP:
return; // 按鼠标右键退出函数
}
}
}
其主要功能为:实现钢笔,粉笔,和两点画线的功能,鼠标右键单击可以实现功能的依此切换,初始为钢笔功能
效果如下:钢笔功能:
看到粗粗的粉笔了没
两点之间画直线:
存在缺陷:1.使用较多的goto语句,破坏了循环语句的结构性,(笔者个人觉得goto语句在这里挺好的)
2.程序没有结束的语句(只有点一下右上角的小叉叉了)。
3.笔者只急着画图了,忘了当图都画满了要擦除
初次写程序,可能存在很多不足,希望读者们多给我一些建议啊!!