DIY一个超简单的画图程序

编译环境: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 的倍数。

 

我写的代码如下:

  1 #include "stdafx.h"
  2 #include <graphics.h>
  3 
  4 void  twopiont();    
  5 void pen();
  6 void chalk();
  7 
  8 void main()
  9 {        
 10     initgraph(640, 480);    //初始化图形界面,窗口分辨率设置为640*480
 11     MOUSEMSG p;                //定义一个鼠标的结构体    
 12     RECT r1 = { 512, 0, 640, 40 };// 在屏幕右侧输出字符串
 13     drawtext(_T("----------"), &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 14     RECT r2 = { 512, 40, 640, 80 };
 15     drawtext(_T("1.钢笔"), &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 16     RECT r3 = { 512, 80, 640, 120 };
 17     drawtext(_T("2.粉笔"), &r3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 18     RECT r4 = { 512, 120, 640, 160 };
 19     drawtext(_T("3.两点画线"), &r4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 20     RECT r5 = { 512, 160, 640, 200 };
 21     drawtext(_T("---------"), &r5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 22     RECT r6 = { 512, 200, 640, 240 };
 23     drawtext(_T("单击鼠标右键"), &r6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 24     RECT r7 = { 512, 240, 640, 280 };
 25     drawtext(_T("切换选项"), &r7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 26     
 27     while (true)
 28     {
 29         p = GetMouseMsg();    
 30         if (p.uMsg == WM_LBUTTONDOWN) pen();
 31         if (p.uMsg == WM_LBUTTONDOWN) chalk();
 32         if (p.uMsg == WM_LBUTTONDOWN) twopiont();
 33     }
 34 
 35 }
 36 
 37 /**************实现在两点之间画一条直线**************/
 38  void  twopiont()        
 39 {
 40     int x0, y0, x1, y1;
 41     MOUSEMSG m;        // 定义鼠标消息
 42     while (true)
 43     {
 44     flag:                //重置开始
 45         m = GetMouseMsg();// 获取一次鼠标消息
 46         switch (m.uMsg)
 47         {
 48         case WM_LBUTTONDOWN:x0 = m.x; y0 = m.y;    //鼠标第一次按下时,得到坐标(x0,y0)
 49             while (true)
 50             {
 51                 m = GetMouseMsg();// 获取一条鼠标消息
 52                 switch (m.uMsg)
 53                 {
 54                 case WM_LBUTTONDOWN:x1 = m.x; y1 = m.y;//鼠标第二次按下时,得到坐标(x1,y1)
 55                     line(x0, y0, x1, y1);
 56                     goto flag;   //跳回到flag处进行重置
 57                     break;
 58                 case WM_RBUTTONUP:
 59                     return;    // 按鼠标右键退出函数
 60                 }
 61             }
 62             break;
 63         case WM_RBUTTONUP:
 64             return;    // 按鼠标右键退出函数
 65         }
 66     }
 67 
 68 }
 69 
 70  /****************实现钢笔功能****************/
 71  void pen()
 72  {
 73      int x0, y0;  
 74      MOUSEMSG m;        // 定义鼠标消息
 75      while (true)
 76      {
 77      flag:                //重置开始
 78          m = GetMouseMsg();// 获取一次鼠标消息
 79          switch (m.uMsg)
 80          {
 81          case WM_LBUTTONDOWN:x0 = m.x; y0 = m.y;    //鼠标第一次按下时,得到坐标(x0,y0)
 82              while (true)
 83              {
 84                  m = GetMouseMsg();// 获取一条鼠标消息
 85                  line(x0, y0, m.x, m.y);
 86                  x0 = m.x; y0 = m.y;
 87                  switch (m.uMsg)
 88                  {
 89                  case WM_LBUTTONUP:
 90                      goto flag;   //跳回到flag处进行重置
 91                      break;
 92                  case WM_RBUTTONUP:
 93                      return;// 按鼠标右键退出函数        
 94                  }
 95              }
 96              break;
 97          case WM_RBUTTONUP:
 98              return;
 99                       // 按鼠标右键退出函数
100          }
101      }
102  }
103 
104  /****************实现粉笔功能****************/
105  void chalk()
106  {
107      int x0, y0;  // 绘图环境初始化
108      MOUSEMSG m;        // 定义鼠标消息
109      while (true)
110      {
111      flag:                //重置开始
112          m = GetMouseMsg();// 获取一次鼠标消息
113          switch (m.uMsg)
114          {
115          case WM_LBUTTONDOWN:x0 = m.x; y0 = m.y;    //鼠标第一次按下时,得到坐标(x0,y0)
116              while (true)
117              {
118                  m = GetMouseMsg();// 获取一条鼠标消息
119                  switch (m.uMsg)
120                  {
121                  case WM_MOUSEMOVE:
122                      fillcircle(m.x, m.y, 10);// 画一个填充圆
123                      break;
124 
125                  case WM_LBUTTONUP:
126                      goto flag;   //跳回到flag处进行重置
127                      break;
128                  case WM_RBUTTONUP:
129                      return;   // 按鼠标右键退出函数
130                  }
131              }
132              break;
133          case WM_RBUTTONUP:
134              return;    // 按鼠标右键退出函数
135          }
136      }
137  }

其主要功能为:实现钢笔,粉笔,和两点画线的功能,鼠标右键单击可以实现功能的依此切换,初始为钢笔功能

 

效果如下:钢笔功能:

 

看到粗粗的粉笔了没

 两点之间画直线:

 

存在缺陷:1.使用较多的goto语句,破坏了循环语句的结构性,(笔者个人觉得goto语句在这里挺好的)

     2.程序没有结束的语句(只有点一下右上角的小叉叉了)。

     3.笔者只急着画图了,忘了当图都画满了要擦除

初次写程序,可能存在很多不足,希望读者们多给我一些建议啊!!

原文地址:https://www.cnblogs.com/junjunjun123/p/8635568.html