• Day17:C++ WITH Easyx


    头文件:#include<graphic.h>

    一、鼠标的相关操作

    1.创建窗口和关闭窗口

    1. /*创建窗口和关闭窗口*/
    2. initgraph(400,400);
    3. closegraph();

    2.创建消息对象

                 (注:不是专门的鼠标消息对象,而是一个消息对象,可以通过peekmessage专门捕捉鼠标的消息) 

    1. /*创建对象*/
    2. ExMessage m;

     3.获取鼠标当前的坐标

    1. /*获取鼠标的当前坐标*/
    2. int m_x; int m_y;
    3. m_x=m.x; m_y=m.y;

     4.几种常见的消息类型

    WM_LBUTTONDDOWN、WM_LBUTTONUP、WM_RBUTTONDOWN、WM_RBUTTONUP  ->实际上都对应着某一个十六进制的整数

    5.操作鼠标消息三步走:

            step1:创建消息对象

            step2:通过peekmessage来捕捉相关的鼠标消息        

    peekmessage(&m,EM_MOUSE) 第二个参数表示是消息类型是鼠标操作

                    当然,也可以是按键操作 EM_KEY

            step3:根据捕捉到的消息,进行相应的操作 

    6.实例:

                    实现左键点击画空心圆,右键点击画一个实心圆的操作。

    1. #include<iostream>
    2. #include<graphics.h>
    3. using namespace std;
    4. int main()
    5. {
    6. initgraph(400, 400);
    7. //step one:
    8. ExMessage m;
    9. while (1)
    10. {
    11. //step two:
    12. /*获取当前窗口的鼠标消息*/
    13. peekmessage(&m, EM_MOUSE); /*获取当前窗口的信息*/
    14. //step three:
    15. if (m.message == WM_LBUTTONDOWN)
    16. {
    17. circle(m.x, m.y, 20);
    18. }
    19. if (m.message == WM_RBUTTONDOWN)
    20. {
    21. fillcircle(m.x, m.y, 10);
    22. }
    23. }
    24. closegraph();
    25. return 0;
    26. }

    效果展示: 

    二、按钮封装

    1.目的:

            自己构建几个筛选器,将基本的绘图的控件构建完毕,以后直接将这些头文件拿来用即可。

    2.小技巧:

            若想在另一个项目中复用这些tool&ui的.h和.cpp的文件,可以先将这些文件复制到对应项目的文件夹中,然后右键,添加“现有项”即可。

    3.在写图形化easyx界面的时候,一定要将其改为多字节

     4.相关代码:

    公共头文件:  common.h

    1. #pragma once
    2. #include <iostream>
    3. #include <string>
    4. #include <graphics.h>
    5. #include <conio.h>
    6. #include <mmsystem.h>
    7. #pragma comment(lib,"WINMM.LIB")
    8. using namespace std;

    UI筛选器下的widget.h

            ①构造函数(宽度、高度、读取图片的路径、flag(是否显示小黑窗))

            ②show()->绘制相应的窗口

            ③Refresh()更新窗口

            ④搞一个防闪退exec,按回车退出

    1. #pragma once
    2. #include"common.h"
    3. class Widget
    4. {
    5. public:
    6. enum SHOW_STYLE/*flag对应的模式*/
    7. {
    8. NO_CON, /*不显示控制台*/
    9. YEW_CON /*显示控制台*/
    10. };
    11. public:
    12. Widget(int width, int height, string url = "", int flag = 0);/*flag=0默认是没有控制台的*/
    13. void show(int flag = 0);/*flag对应显示模式*/
    14. void Refresh();
    15. ~Widget(); /*由于做了动态内存申请*/
    16. bool exec()
    17. {
    18. while (_getch() != '\r');/*按回车,退出->防止闪屏*/
    19. return 0;
    20. }
    21. protected:
    22. int width;
    23. int height;
    24. IMAGE* img;
    25. string imgURL; /*图片的路径*/
    26. };

    UI筛选器下的 widget.cpp

    1. #include "widget.h"
    2. Widget::Widget(int width, int height, string url, int flag)
    3. {
    4. this->width = width;
    5. this->height = height;
    6. this->imgURL = url; /*窗口背景的图片路径*/
    7. if (url.size() != 0)
    8. {
    9. this->img = new IMAGE; /*所以要析构*/
    10. loadimage(this->img, url.c_str(), this->width, this->height);
    11. }
    12. }
    13. void Widget::show(int flag)
    14. {
    15. initgraph(this->width, this->height, flag);/*flag传入0表示不显示窗口,flag传入1表示显示窗口*/
    16. if (this->imgURL.size() != 0)
    17. {
    18. putimage(0, 0, this->img); /*注意:图片的路径名长度不为0才会去寻找并贴图*/
    19. }
    20. }
    21. void Widget::Refresh()
    22. {
    23. if (imgURL.size() != 0)
    24. {
    25. putimage(0, 0, img);
    26. }
    27. else
    28. {
    29. cleardevice();
    30. }
    31. }
    32. Widget::~Widget()
    33. {
    34. if (imgURL.size() != 0) /*细节:要不为空才能析构*/
    35. {
    36. delete img;
    37. }
    38. }

    UI下的button.h

            ①已继承下来了width和height,一个按钮还需要x、y坐标以及上面可以显示的文字

            ②增加设置相关数据成员COLORREF和文字颜色的接口

            ③show()->绘制按钮(主要就是保证文字的居中!)

            ④MouseInButton()判断鼠标是否放在了按钮上

            ⑤clickButton()   点击鼠标后进行的反应

            ⑥新增数据成员,鼠标放置在按钮上颜色,和不在按钮上的颜色及当前色 COLOREF

    1. #pragma once
    2. #include"common.h"
    3. #include"widget.h"
    4. class Button:public Widget
    5. {
    6. public:
    7. Button(string text="", int x = 0, int y = 0, int width = 100, int height = 25);
    8. void SetBkColor(COLORREF);
    9. void setTextColor(COLORREF color);
    10. void show();
    11. bool MouseInButton(ExMessage msg); /*鼠标是否放在了按钮上*/
    12. bool clickButton(ExMessage msg);
    13. protected:
    14. //按钮的坐标
    15. int x;
    16. int y;
    17. //按钮文字
    18. string text;
    19. //按钮颜色
    20. COLORREF curColor; /*当前按钮颜色*/
    21. COLORREF inColor; /*鼠标在按钮中*/
    22. COLORREF outColor; /*鼠标不在按钮中的颜色*/
    23. COLORREF textColor;
    24. /*继承下来的成员
    25. int width;
    26. int height;
    27. IMAGE* img;
    28. string imgURL
    29. */
    30. };

     UI下的button.cpp

    1. #include "button.h"
    2. Button::Button(string text, int x, int y, int width, int height):Widget(width,height)
    3. {
    4. this->curColor =LIGHTGREEN;
    5. this->outColor = LIGHTGREEN;
    6. this->inColor = LIGHTBLUE;
    7. this->text = text;
    8. this->x = x;
    9. this->y = y;
    10. }
    11. void Button::SetBkColor(COLORREF color)
    12. {
    13. this->curColor = color;
    14. this->outColor = color;
    15. this->inColor = LIGHTBLUE;//鼠标在按钮中显示淡蓝色
    16. this->textColor = BLACK;
    17. }
    18. void Button::setTextColor(COLORREF color)
    19. {
    20. this->textColor = textColor;
    21. }
    22. void Button::show()
    23. {
    24. //按钮绘制出来(①按钮边框线的颜色②按钮的填充颜色)
    25. setlinecolor(this->curColor);
    26. setfillcolor(this->curColor);
    27. fillrectangle(x, y, x + width, y + height);
    28. //文字显示:文字居中及文字样式
    29. setbkmode(TRANSPARENT); /*去掉文字的背景色*/
    30. settextstyle(2*this->height/3, 0, "楷体"); /*第一个参数是粗细,第二参数是是否斜体*/
    31. int x = this->x+(this->width - textwidth(text.c_str()))/2;
    32. int y = this->y + (this->height - textheight(text.c_str())) / 2;
    33. outtextxy(x, y, text.c_str());
    34. }
    35. bool Button::MouseInButton(ExMessage msg)
    36. {
    37. if (msg.x >= this->x && msg.y >= this->y &&
    38. msg.x <= this->x + this->width &&
    39. msg.y <= this->y + this->height)
    40. {
    41. this->curColor = this->inColor; /*鼠标在button上颜色改变*/
    42. return true;
    43. }
    44. this->curColor = this->outColor;
    45. return false;
    46. }
    47. bool Button::clickButton(ExMessage msg)
    48. {
    49. if (MouseInButton(msg)&&msg.message == WM_LBUTTONDOWN)
    50. {
    51. return true;
    52. }
    53. return false;
    54. }

    三、实例之画线小工具

    1.直接复用刚才写的common.h    button类和widget类

    2.新增:

    Tool中的basic_shape.h

            写一个抽象类

    1. #pragma once
    2. #include"common.h"
    3. class Basic_shape
    4. {
    5. public:
    6. virtual void drawShape(ExMessage msg) = 0;
    7. protected:
    8. vector<Basic_shape*> shape;/*所有的形状都存在这里面*/
    9. };

     Tool中的bightLine.h      /*画一个曲线*/

            注意要重写抽象父类的方法

    1. #pragma once
    2. /*画曲线*/
    3. #include"common.h"
    4. #include"basic_shape.h"
    5. class BightLine :public Basic_shape
    6. {
    7. public:
    8. BightLine(int size = 5, COLORREF color = WHITE);
    9. void drawLine(ExMessage msg);
    10. void drawShape(ExMessage msg);
    11. protected:
    12. int size; /*曲线的粗细*/
    13. COLORREF color; /*颜色*/
    14. tuple<int, int>begin; /*画线的起点坐标*/
    15. tuple<int, int> end; /*画线的终点坐标*/
    16. bool isDown; /*用于处理两个消息*/
    17. };

     Tool中的bightLine.cpp     /*画一个曲线*/

            关键:如何实现画出曲线的效果!isDown作为检测变量,过渡两个消息之间的差异,注意:时刻更新begin的坐标,这样while(1)的循环下,使setlinestyle(PS_ENDCAP_ROUND, this->size);/*结束处为圆形*/  形成曲线的效果

    1. #include "bightLine.h"
    2. BightLine::BightLine(int size, COLORREF color)
    3. {
    4. this->size = size;
    5. this->color = color;
    6. this->isDown = false;
    7. }
    8. void BightLine::drawLine(ExMessage msg)
    9. {
    10. if (msg.message == WM_LBUTTONDOWN)
    11. {
    12. this->isDown = true;
    13. begin = tuple<int, int>(msg.x, msg.y); /*记录起点位置*/
    14. }
    15. if (msg.message == WM_LBUTTONUP)
    16. {
    17. this->isDown = false;
    18. }
    19. if (this->isDown == true && msg.message == WM_MOUSEMOVE)
    20. {
    21. setlinestyle(PS_ENDCAP_ROUND, this->size);/*结束处为圆形*/
    22. line(get<0>(begin), get<1>(begin), msg.x, msg.y);
    23. }
    24. /*每次画完后,要修改起点为上一次结束的位置*/
    25. begin = tuple<int, int>(msg.x, msg.y);
    26. }
    27. void BightLine::drawShape(ExMessage msg)
    28. {
    29. drawLine(msg);
    30. }

    待完成模块:新增一个颜色板(从button派生类,新写方法,实现点击返回相应颜色的功能)

    1. #pragma once
    2. #include"button.h"
    3. /*增加颜色板,点击相应的按钮颜色,返回颜色*/
    4. class ColorTool :public Button
    5. {
    6. public:
    7. COLORREF getColor();
    8. };
    1. #include "colorTool.h"
    2. COLORREF ColorTool::getColor()
    3. {
    4. return COLORREF();
    5. }

    画曲线测试:

  • 相关阅读:
    【计算机网络笔记】IPv6简介
    gdb 常用命令
    Postman知识汇总
    关于表单校验,:rules=“loginRules“
    【刷题系列】顺序表OJ题
    泛型通配符,上下限 ,生活案例介绍
    最全面的蓝桥杯常考知识点总结(Python)|冲国赛
    使用编码工具
    P8976 「DTOI-4」排列,贪心
    SpringMVC基础:@RequestMapping详解
  • 原文地址:https://blog.csdn.net/zjjaibc/article/details/125457372