1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【MFC】实现简单画板功能 包含画点 画线 矩形 棋盘 指定棋盘大小等功能。

【MFC】实现简单画板功能 包含画点 画线 矩形 棋盘 指定棋盘大小等功能。

时间:2020-03-23 03:43:05

相关推荐

【MFC】实现简单画板功能 包含画点 画线 矩形 棋盘 指定棋盘大小等功能。

【MFC】实现简单画线、矩形、棋盘功能。

一.实现基础绘画功能(一)新建工程(二)实现画点功能(三)实现画直线功能(四)实现画矩形功能(五)实现画棋盘功能 二、基础交互式示例(一)、交互式指定绘画方式(二)、交互式指定棋盘大小

一.实现基础绘画功能

(一)新建工程

1.首先新建一个 MFC应用程序(这里我使用的是VS版本),我这里设置名称为Draw。

2.在以下页面选择单文档,点击完成,完成创建。

3.直接点击调试运行,就可以看到你的画板啦。

可惜的是现在即使你点击鼠标,它也无法显示出任何笔迹,所以接下来我们就先从画点开始吧!

(二)实现画点功能

1.在视图中找到 类视图,在 类视图 中找到 C(你的文件名)View 这个类,例如我的文件名为 Draw 故而我的是 CDrawView 是这个类(后面我们就叫做视图类)。接下来我们的操作就在这个类中啦~

2.在电脑上如何画画呢?肯定是要借助鼠标的,所以需要我们添加两个 消息事件,来在我们 按下鼠标 和 抬起鼠标 的时候进行绘图。

右键点击 视图类-属性,点击闪电之后的按钮,出现以 VM_ 开头的,就是消息事件啦。选择如下图所示的 L开头的 LBUTTONDOWN,点击后面的小箭头,添加即可。同样方法添加 LBUTTONUP 消息函数。

3.添加存储起点和终点的变量

为了存储鼠标点击下去和放开时的点,以便于我们进行后续的画点、画线行为,我们需要存储这两个点~~~接下来我们来设置存储点的变量吧。

1.在类视图窗口中选择视图类点击进入,找一个**public:**写入CPoint m_point1;CPoint m_point2;,CPoint 是可以存储点的类,m_point1和m_point2 是存储点的变量名,自己随意起名就可以。

public: CPoint m_point1;CPoint m_point2;

2.接着,我们通过视图-解决方案资源管理进入我们视图类的.cpp文件,找到OnLButtonDown()这个函数(也可以通过类视图下方的小框直接找到这个函数,点击进入),

写入代码:

m_point1=point; //*在这里 OnLButtonDown()这个函数中point表示鼠标按下时获取到的点。

3.同理在OnLButtonUp()这个函数中写入代码:

m_point2=point; //*在这里 OnLButtonUp()这个函数中point表示鼠标抬起时获取到的点。

4.好的,现在让我们来写入画点函数开始画点吧~

因为画点的话只需要给定一个点就可以,所以我们在OnButtonDown或者OnButtonUp()函数中任意选一个函数写入下方这段代码就可以啦~

CClientDC du(this); //获得一个指向当前画板的句柄(可以理解为笔杆子)du为自定义变量。du.SetPixel(point,RGB(255,0,0)); //画点函数,其中点的颜色通过RGB方式来指定。可以自行设定颜色。

因为点的像素很小,点击运行测试画板的时候一定记得注意仔细观察呀~~

(三)实现画直线功能

1.划线涉及两个点,起点和终点。而之前我们已经利用m_point1变量和m_point2变量存储了起点和终点。所以我们可以直接在OnButtonUp()函数中写入以下代码

注意:最好先注释掉画点函数,即上文中的du.SetPixel(point,RGB(255,0,0));。

m_point2=point;CClientDC du(this); //获得一个指向当前画板的句柄(可以理解为笔杆子)du为自定义变量。//du.SetPixel(point,RGB(255,0,0)); //这句已经被注释掉du.MoveTo(m_point1); //画笔先移动到了鼠标点击下去的点。这是线的起点。du.LineTo(m_point2); //以鼠标释放的点为终点,画出一条直线。

好的,现在点击调试运行,按住鼠标拖动一下再释放鼠标,就可以看到你画的直线啦~

(四)实现画矩形功能

1.画矩形呢,也是需要两个点的,即左上角的点和右下角的点就可以完整的画出一个矩形。

这里呢我们先注释掉刚写入的画直线的这两句,然后写入以下代码:

m_point2=point;CClientDC du(this); //获得一个指向当前画板的句柄(可以理解为笔杆子)du为自定义变量。//du.SetPixel(point,RGB(255,0,0)); //这句已经被注释掉//du.MoveTo(m_point1); //画笔先移动到了鼠标点击下去的点。这是线的起点。//du.LineTo(m_point2); //以鼠标释放的点为终点,画出一条直线。du.Rectangle(m_point1.x,m_point1.y,m_point2.x,m_point2.y);//这里变量后的.x表示点的x轴坐标, .y表示点的y轴坐标。

当然这里也可以直接调用一个函数,一次性传入这四个变量,代码如下:

m_point2=point;CClientDC du(this); //获得一个指向当前画板的句柄(可以理解为笔杆子)du为自定义变量。//du.SetPixel(point,RGB(255,0,0)); //这句已经被注释掉//du.MoveTo(m_point1); //画笔先移动到了鼠标点击下去的点。这是线的起点。//du.LineTo(m_point2); //以鼠标释放的点为终点,画出一条直线。du.Rectangle(CRect(m_point1,m_point2));//和上述代码效果是一样的。

运行并点击拖动鼠标,铛啦~效果就出现啦

2.接下来我们来画一个实心矩形。这里需要用到画刷工具来为矩形填充颜色。

在画矩形那一句代码之前添加如下代码:

Brush brush0(RGB(0,0,255));//新建一个画刷,利用RGB设置颜色,这里是蓝色。du.SelectObject(&brush0);//选入画刷,表示使用这个画刷。

运行并点击拖动鼠标,效果就实现啦。

(五)实现画棋盘功能

1.画棋盘呢分为两步:画格子,填充格子。首先我们来画格子。

在这里我的棋盘是八行八列,通过画线函数来实现。在此之前注释掉画矩形的那两句代码(选入画刷代码,画矩形代码)。将以下代码写入OnLButtonUp()函数中去。

int Ox=200;//棋盘左上角的x轴起点int Oy=100;//棋盘左上角的y轴起点int numx=9;//直线列数int numy=9;//直线行数int bulk=50;//棋盘每个格子大小,设置变量是为了后续的交互式改变大小for(int i=0;i<numx;i++)//画列线{du.MoveTo(Ox+bulk*i,Oy);du.LineTo(Ox+bulk*i,bulk*8+Oy);}for(int j=0;j<numy;j++)//画行线{du.MoveTo(Ox,Oy+bulk*j);du.LineTo(Ox+bulk*8,Oy+bulk*j);}CString str;for(int i=8;i>0;i--){str.Format(_T("%d"),i);du.TextOut(Ox-30,bulk*8+100-bulk/2-(bulk*(i-1)),str);}char b[]={'A','B','C','D','E','F','G','H'};for(int j=1;j<9;j++){str.Format(_T("%c"),b[j-1]);du.TextOut(Ox+bulk/2+bulk*(j-1),Oy-30,str);}

2.好的,现在我们已经有了基础的棋盘格子,现在我们就来为棋盘填充颜色,同样用到画刷工具。

这里需要取消 选入画刷的那句代码的注释。然后在上方代码之后添加以下代码即可:

for(int n=0;n<8;n=n+1){for(int m=0;m<8;m=m+2){CRect rc(Ox+bulk*m,Oy+n*bulk,Ox+bulk*m+bulk,Oy+n*bulk+bulk);//分别是起点的x轴坐标,y轴坐标终点的x轴坐标,y轴坐标。if(n%2==0){du.FillRect(rc,&brush0);//表示填充颜色。rc表示填充的区域。brush0表示填充区域所用的画刷。}}}for(int n=1;n<9;n=n+1){for(int m=1;m<9;m=m+2){if(n%2!=0){CRect rc(Ox+bulk*m,Oy+n*bulk,Ox+bulk*m+bulk,Oy+n*bulk+bulk);//同上方。du.FillRect(rc,&brush0);}}}

好的,恭喜你,棋盘成型啦。效果如下:

偷了个懒,这里我只是填充了一半的格子。白色部分都是透明的。可以自己按逻辑尝试呀。

二、基础交互式示例

(一)、交互式指定绘画方式

我们注意到在在画板周围有菜单栏。所以我们接下来就利用菜单栏来进行绘画方式的选择。

这里我已经插入了一个绘画菜单~以下是过程。

1.找到资源视图,同理:视图-资源视图(没有的话,在视图-其他中找找。)

依次进入 menu 菜单,添加我们所用菜单。1.为我们自设的文件名。2.为Menu菜单。3.为我们所要找的菜单。如下。

2.在右边中找到划红线的部分,然后直接在其中输入控制绘画形式的菜单名:我在这里设置为绘画,之后点击绘画,依次输入点、直线、矩形、棋盘、设置,效果如上。

测试运行就会发现我们所设置的菜单已经存在了,但均为灰色,这里我们想要实现功能是点击它,然后响应相应的事件。所以接下来我们为它添加响应事件。

3.依次右键点击我们在绘画中添加的菜单,例如”点“,点击它的属性,更改ID为容易辨识的,例如我的是:ID_Point。

依次为 直线: ID_Line 矩形:ID_Square 棋盘:ID_Chess 设置:ID_Setting(设置这个模块是为了后续的棋盘交互式的实现),当然,这里你也可以自己设置自己喜欢的名称。

4.现在右击绘画中的菜单,选择添加事件处理程序,基类选择视图类例如我的则是 CDrawView,类型选择 COMAND ,添加编辑就可以了。

这里是以“点”为例,,大家依次添加消息处理程序即可。

5.交互式选择有两种方式。你可以选择直接在相应的事件处理程序中填入相应的代码。也可以选择设置一个全局变量和switch相结合的方式来进行交互式选择。

直接在相应消息函数中添加代码的交互方式,我们在这里不再赘述。下面我们来介绍第二种交互方式。

(1)首先,我们先设置一个全局变量,在我们 类视图-视图类的头文件中添加一个int 类型变量(设置为public 和private 均可,这里我设置为public)来告知我们用户的选择。

添加代码如下:

int m_choose;//我设置变量为 m_chosse;

(2)之后在返回视图类的 .cpp 中(寻找方法在上文),依次在“点”、“直线”、“矩形”、“棋盘”消息函数中给m_choose设置一个不同的值。(这里暂时忽略“Onseting()函数”)

示例如下:

void CDrawView::OnPoint(){// TODO: 在此添加命令处理程序代码m_choose=1;}void CDrawView::OnLine(){// TODO: 在此添加命令处理程序代码m_choose=2;}void CDrawView::OnSquare(){// TODO: 在此添加命令处理程序代码m_choose=3;}void CDrawView::OnChess(){// TODO: 在此添加命令处理程序代码m_choose=4;}void CDrawView::OnSetting(){// TODO: 在此添加命令处理程序代码}

(3)给变量一个初始化:我们找到视图类的.cpp的构造函数。写入默认选定的选项。

例如我默认画直线故而初始化变量值为2。(因为点不明显)

**(4)在OnButtonUp() 写入以下代码:

m_point2=point;CClientDC du(this); //获得一个指向当前画板的句柄,du为自定义变量。int Ox=200;//棋盘左上角的x轴起点int Oy=100;//棋盘左上角的y轴起点int numx=9;//直线列数int numy=9;//直线行数int bulk=50;//棋盘每个格子大小CBrush brush0(RGB(0,0,255));du.SelectObject(&brush0);switch (m_choose){case 1:du.SetPixel(point,RGB(255,0,0));break;case 2:du.MoveTo(m_point1);du.LineTo(m_point2);break;case 3:du.Rectangle(CRect(m_point1,m_point2));break;case 4:for(int i=0;i<numx;i++)//画列线{du.MoveTo(Ox+bulk*i,Oy);du.LineTo(Ox+bulk*i,bulk*8+Oy);}for(int j=0;j<numy;j++)//画行线{du.MoveTo(Ox,Oy+bulk*j);du.LineTo(Ox+bulk*8,Oy+bulk*j);}CString str;for(int i=8;i>0;i--){str.Format(_T("%d"),i);//将数字转为CString类型du.TextOut(Ox-30,bulk*8+100-bulk/2-(bulk*(i-1)),str);//绘制数字}char b[]={'A','B','C','D','E','F','G','H'}; //通过数组存储要绘制的字母for(int j=1;j<9;j++){str.Format(_T("%c"),b[j-1]);//将char类型字母改为CStringdu.TextOut(Ox+bulk/2+bulk*(j-1),Oy-30,str); //输出字母} for(int n=0;n<8;n=n+1){for(int m=0;m<8;m=m+2){CRect rc(Ox+bulk*m,Oy+n*bulk,Ox+bulk*m+bulk,Oy+n*bulk+bulk);if(n%2==0){du.FillRect(rc,&brush0);}}}for(int n=1;n<9;n=n+1){for(int m=1;m<9;m=m+2){if(n%2!=0){CRect rc(Ox+bulk*m,Oy+n*bulk,Ox+bulk*m+bulk,Oy+n*bulk+bulk);du.FillRect(rc,&brush0);}}}break;}

点击就可实现不同的功能。

PS:期间有不可更改ID等情况,建议关闭后重新打开。

至此,我们基本功能已完成,但仍旧存在一些问题,我们后续进行完善。

(二)、交互式指定棋盘大小

首先确定思路:我这里思路是弹出对话框,利用对话框输入棋盘每个格子大小,从而间接改变整个棋盘大小。

1.首先我们来新建一个对话框,用于输入棋盘大小。

1).首先进入 资源视图,找到Dialog,右键单击,选中插入Dialog(E),对话框就新建好了。

2).选中菜单栏的 视图-工具箱,打开如下页面,依次选中以下标红的 编辑文本框 和 静态文本框。进行布局。(直接点击对话框中控件输入文字就可以改变控件显示的文本)

我的布局如下:

右键单击控件,属性,更改ID(这里我更改为IDC_Size):

3).左键双击对话框,弹出添加类窗口,添加类如下(类名自定):

4).完成后,回到对话框页面,右键点击 编辑框,添加变量,用于接收我们输入的数据。类型为int。如下(变量名自定):

完成后,进入类视图,这时就已经可以看到我们新加的类已经在类视图的最底端。点击进入可以看到我们新加的变量也在其中。完成对话框的创建!

2.现在我们将我们进行 点击设置,弹出对话框的功能的实现。

1).首先我们先在视图类的.cpp文件的最上方添加如下代码:

#include "Setting.h" //这里是你新添加的类名的头文件(类名.h),表示引用这个文件的内容。

2).找到我们上文添加的设置菜单的响应函数 OnSetting() ,并写入以下代码:

Setting dlg;//对话框类的一个变量dlg.DoModal();//弹出一个非模态对话框

运行,依次点击绘画-设置效果如下:

现在默认数值为0;

3).为了接收用户输入的变量来在视图类中随意调用,我们需要再在视图类的头文件中再添加一个int型变量。我设置为public类型。

public:int m_SSize;//接收用户输入的尺寸。

同样的在构造函数中初始化m_SSize(构造函数位置在上文提到过);

m_SSize=50;//因为我们现在棋盘大小设置的是50,故而现在先设置为50

好的,接下来我们开始进行数据的交互:

注释掉我们刚在OnSetting()输入的第二行代码,写入以下代码:

Setting dlg;//dlg.DoModal();dlg.m_Size=m_SSize;//将棋盘现在的大小传给对话框,这时对话框中默认值就为50了if(IDOK==dlg.DoModal())//只有按 确认键时,数据才被传入m_SSize{ UpdateData(TRUE);//用于刷新数据,有些版本不需这两句也可达到目的m_SSize=dlg.m_Size;//将对话框的数据传入视图类UpdateData(FALSE);}

现在运行效果如下:

3.更改棋盘大小实现。

我们已经可以用m_SSize接收到用户输入的数据。现在只需将OnButtonUp()函数中的绘制棋盘函数中的这句更改即可:

int bulk=m_SSize;//棋盘每个格子大小,50改为了m_SSize

现在即可实现更改棋盘大小,但是存在问题:前面绘制的棋盘并未消失?

4.刷新棋盘的实现。

持续更新,整理真的好费时间QAQ

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。