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.筆者只急着畫圖了,忘了當圖都畫滿了要擦除

初次寫程序,可能存在很多不足,希望讀者們多給我一些建議啊!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM