应用程序设计基础课程设计.docx
- 文档编号:5250951
- 上传时间:2022-12-14
- 格式:DOCX
- 页数:20
- 大小:70.84KB
应用程序设计基础课程设计.docx
《应用程序设计基础课程设计.docx》由会员分享,可在线阅读,更多相关《应用程序设计基础课程设计.docx(20页珍藏版)》请在冰豆网上搜索。
应用程序设计基础课程设计
课程设计方案
一、课程设计的题目
画图软件的开发
2、课程设计的目的
《应用程序设计基础(课程设计)》作为一门重要的实践性课程,重点培养学生的动手操作和创新素养。
通过学习和实践,使学生掌握基本的软件设计技能,了解并熟悉常用的软件设计方法,掌握常用计算机软件的开发知识,为学习后续课程打下良好的基础。
三、课程设计的功能要求
1、绘制直线图元,或称为线段图元,允许用户使用鼠标选择顶点绘制。
2、绘制椭圆图元,允许用户拖动鼠标控制椭圆的外接矩形,来进行绘制。
也可以绘制圆形。
3、绘制三角形图元,允许用户拖动鼠标控制三角形的顶点位置,来绘制合适的三角形。
4、绘制矩形图元,使用鼠标控制矩形的位置和外形。
5、填充形状,使用当前画刷填充形状内部。
6、显示或隐藏绘图工具栏。
7、在状态栏显示鼠标位置
4、课程设计的主要内容
(一)、程序框架设计
1、创建应用程序框架
创建一个名为Painter的多文档应用程序
2、制作标准工具栏
使用工具栏资源编辑器创建工具栏资源,为每个工具栏按钮增加消息处理函数,使用ClassWizard可以将工具栏按钮接到应用程序中的代码中。
使用EnableDocking和DockContorlBar两个函数使工具栏停靠。
主要代码及说明:
intCMainFrame:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CMDIFrameWnd:
:
OnCreate(lpCreateStruct)==-1)
return-1;
//载入常用工具栏
if(!
m_wndToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP
|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||
!
m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failedtocreatetoolbar\n");
return-1;//failtocreate,创建标准工具栏失败
}
//TODO:
Deletethesethreelinesifyoudon'twantthetoolbarto
//bedockable,使常用工具栏浮动
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
//载入绘图工具栏
if(!
m_DrawToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_ALIGN_LEFT
|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||
!
m_DrawToolBar.LoadToolBar(IDR_DRAW_TOOLBAR))
{
TRACE0("Failedtocreatetoolbar\n");
return-1;//failtocreate,创建绘图工具栏失败
}
//使绘图工具栏浮动
m_DrawToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
3、制作绘图工具栏
方法同制作标准工具栏,效果如下:
需要添加的工具栏按钮消息处理函数
对象标示符
消息
函数名
所属类
ID_DRAW_ELLIPSE
COMMAND
OnDrawEllipse
CPainterView
ID_DRAW_TRIANGLE
COMMAND
OnDrawTriangle
CPainterView
ID_DRAW_LINE
COMMAND
OnDrawLine
CPainterView
ID_DRAW_RECTANGLE
COMMAND
OnDrawRectangle
CPainterView
ID_DRAW_FILL
COMMAND
UPDATE_COMMAND_UI
OnDrawFill
OnUpdateDrawFill
CPainterView
4、使用状态栏
在应用程序中一般通过重载CMainFrame类中的OnCreate函数载入状态栏,下面是Painter应用程序中使用状态栏的实现代码。
定义状态栏各窗格字符串ID数组
staticUINTindicators[]=
{
ID_SEPARATOR,//第一窗口,提示信息输出栏
ID_SEPARATOR,//第二窗口,鼠标位置
ID_INDICATOR_CAPS,//第三窗口,显示CapsLock键状态
ID_INDICATOR_NUM,//第四窗口,显示NumLock键状态
ID_INDICATOR_SCRL,//第五窗口,显示ScrollLock键状态
};
声明状态栏对象
classCMainFrame:
publicCMDIFrameWnd
{
…………
protected:
//controlbarembeddedmembers
CStatusBarm_wndStatusBar;
…………
}
创建状态栏
intCMainFrame:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
//载入状态栏
if(!
m_wndStatusBar.Create(this)||
!
m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failedtocreatestatusbar\n");
return-1;//failtocreate
}
//设置状态栏第二窗格,鼠标位置状态栏初始显示文本m_wndStatusBar.SetPaneText(1,"x=10,y=10",TRUE);
m_wndStatusBar.SetPaneInfo(1,ID_SEPARATOR,SBPS_STRETCH,10);
}
(二)、实现绘图功能
1、图元数据的定义
Painter应用程序中将处理的图元包括直线、矩形、三角形、圆形(椭圆形),将其定义在GraphRecord.h头文件中,如下述代码所示:
//Graphrecord.h
#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000
//Graphrecord.h:
headerfile
#defineNONE0
#defineLINE1
#defineRECTANGLE2
#defineTRIANGLE3
#defineELLIPSE4
#defineFILL5
#defineSELECT6
#defineTEXT7
#defineMOVE8
#defineSOLIDBRUSH0x100
//画笔
structPENTYPE
{
intiWidth;
intiStyle;
COLORREFColor
//直线
structLINENODE
{
BYTEbType;//绘图单元的类型
//该记录的状态:
bDo>0显示;bDoc<=0不显示
//-3-粘贴,-6-剪切,0-不显示,1-显示,2-被选择,3-粘贴,5-移动,6-剪切,7-移动被恢复
intbDo;
intIndex;//图元索引
PENTYPEpen;//绘制直线所用的画笔类型
POINTstart;//直线的起点
POINTEnd;//直线的终点
LINENODE()//直线图元的初始化函数
{
bType=LINE;
bDo=1;
};
};
……………………
2、文档类说明
应用程序中文档类的作用就是统筹数据。
一方面,支持视图类,以便数据能够及时修改数据,以使视图能够更新显示。
在CPainterDoc类的头文件中声明了下面的数据成员。
CPtrListRecordList;//图元记录链表
3、视图类说明
添加数据成员和函数用来管理视图中绘制的状态和操作。
重载视图类的OnDraw成员函数,以将文档的数据显示在屏幕上。
实际上,所有应用程序的绘制输出都是在OnDraw函数中实现的,除非用户重载视图类的OnPaint函数,并使该函数不调用OnDraw函数。
在视图类中定义消息处理函数,来处理标准的Windows消息(由鼠标和键盘动作产生)和命令(由菜单、工具栏按钮产生),以及完成所见即所得绘图。
消息处理函数就会调用文档数据,并将相应地图元数据更改为被选择状态(bDo=2)。
当鼠标移动时,消息处理函数首先改变状态栏坐标输出,然后根据当前绘图状态分别作出处理。
根据需要,重载视图类中的其他成员函数,以便进行必要的视图初始化工作。
在CPainterView类的头文件中,为每个基本图元数据结构都声明了一个指针变量。
在用户进行基本图元的创建时,这些成员变量用于保存创建过程中图元的数据。
直到图元绘制完毕才为链接表创建新的节点,并将存储在这些成员变量中的数据添加到新建的链表节点中。
………………
public:
CPainterDoc*GetDocument();
//输出文本
BYTE*DrawType;
CStringm_strText;
POINTPrePoint;//原先鼠标位置
POINTTempPoint;//暂存鼠标位置
intOppIndex;//图元索引
protected:
LINENODE*linenode;//直线图元结构
RECTANGLENODE*rectanglenode;//矩形图元结构
ELLIPSENODE*ellipsenode;//椭圆图元结构
TRIANGLENODE*trianglenode;//三角形图元结构
FILLNODE*fillnde;//填充图元结构
在CPainterView的构造函数中完成了对这些成员变量的初始化操作,其源代码如下:
CPainterView:
:
CPainterView()
{
//TODO:
addconstructioncodehere
hatchIndex=0;//当前填充方式
CurColor=(0,255,0);//当前颜色
PenCurColor=(0,0,0);//画笔颜色
penType=0;//画笔种类为0
penWidth=1;//画笔宽度为1
DrawStep=0;//绘图状态为未完成
DrawType=newBYTE;
*DrawType=LINE;//当前无绘图种类
}
(3)、实现所见即所得绘图
1、鼠标消息响应函数框架
所见即所得绘图主要是通过重载鼠标处理函数来完成的,下面是鼠标左键按下消息响应函数框架,在本消息处理函数中主要完成绘图操作的初始步骤,例如选定矩形左上角等。
对于不同图元绘制处理,主要是通过函数中的Switch-Case根据当前DrawType的取值实现的。
OnLButtonDown()函数
voidCPainterView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
InvalidateRect(NULL,FALSE);
CPainterDoc*pDoc=GetDocument();
CDC*dc=GetDC();
PrePoint=TempPoint=point;
inti;
switch(*DrawType)//根据绘图类型作不同处理
{
caseSELECT:
//图元选择判断
break;
caseLINE:
break;
caseRECTANGLE:
break;
caseTRIANGLE:
break;
caseELLIPSE:
break;
caseFILL:
break;
default:
break;
}
CView:
:
OnLButtonDown(nFlags,point);
}
OnMouseMove()函数
通过调用AfxGetApp可以得到程序应用类对象CPainterApp
的指针,使用该指针可以操作应用程序信息。
voidCPainterView:
:
OnMouseMove(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
CDC*dc=GetDC();
intiR;
//设置状态栏输出
CStatusBar*pStatus=(CStatusBar*)
AfxGetApp()->m_pMainWnd->GetDescendantWindow(ID_VIEW_STATUS_BAR);
if(pStatus)
{
chartbuf[40];
sprintf(tbuf,"(%d,%d)",point.x,point.y);
//在状态条的第二个窗格中输出当前鼠标的位置
pStatus->SetPaneText(1,tbuf,TRUE);
pStatus->SetPaneInfo(1,ID_SEPARATOR,SBPS_STRETCH,10);
}
//如果绘图未完成返回
if(DrawStep==0)
return;
//否则处理
switch(*DrawType)
{
caseLINE:
break;
caseRECTANGLE:
break;
caseTRIANGLE:
break;
caseELLIPSE:
break;
}
CView:
:
OnMouseMove(nFlags,point);
}
OnLButtonUp()函数
下面是鼠标左键释放消息响应函数框架,在本消息函数中主要完成绘图操作的结束步骤,完成图元的创建和向链表添加节点的功能。
对于不同图元绘制的处理,主要是通过函数中的Switch-Case根据当前DrawType的取值实现的。
voidCPainterView:
:
OnLButtonUp(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
CPainterDoc*pDoc=GetDocument();
CDC*dc=GetDC();
switch(*DrawType)
{
caseRECTANGLE:
break;
caseTRIANGLE:
break;
caseELLIPSE:
break;
caseLINE:
break;
}
//Invalidate();//重回窗口
dc->SelectObject(OldPen);//恢复设备环境设备
CView:
:
OnLButtonUp(nFlags,point);
}
2、绘制直线
单击“绘制直线”按钮,使系统进入直线绘制状态。
这需要向“绘制直线”按钮的消息响应OnDrawLine中添加代码,其源代码如下:
voidCPainterView:
:
OnDrawLine()
{
//TODO:
Addyourcommandhandlercodehere
DrawType=newBYTE;
*DrawType=LINE;
}
在客户区中单击鼠标,选择直线的起点。
需要向OnLButtonDown中相应地Case语句中添加代码。
由于直线起点终点的选择和记录都是通过OnLButtonDown函数来完成的,因此需要使用DrawStep来标识不同的步骤,即当前是选择直线起点还是终点。
caseLINE:
if(!
DrawStep)
{
linenode=newLINENODE;
linenode->start=point;
DrawStep=1
}
Break;
移动鼠标,在此过程中需要鼠标移动消息的相应函数进行处理。
具体来说,就是根据鼠标移动位置动态来绘制直线,以直观地向用户展示绘制过程。
caseLINE:
iR=dc->SetROP2(R2_NOTXORPEN);//设置绘图模式,擦除以前的直线
dc->MoveTo(linenode->start);
dc->LineTo(PrePoint);
//绘制当前直线
dc->MoveTo(linenode->start);
dc->LineTo(point);
PrePoint=point;
dc->SetROP2(iR);//恢复原始绘图模式
break;
在客户区中单击鼠标,选择直线的终点。
要向OnLButtonUp中相应地Case语句中添加代码。
此时DrawStep=1标识当前单击是选择直线终点。
这一步实际上结束了当前直线的绘制,将图元类型(DrawType)和图元数据(linenode)存入图形数据链表中,实现代码如下:
if(!
DrawStep)
{DrawStep=1;
linenode=newLINENODE;
linenode->start=point;
}
else
{DrawStep=0;
if(abs(linenode->start.x-point.x)>abs(linenode->start.y-point.y))
{
linenode->End.x=point.x;
linenode->End.y=linenode->start.y;
}
else
{
linenode->End.x=linenode->start.x;
linenode->End.y=point.y;
}
dc->MoveTo(linenode->start);
dc->LineTo(linenode->End);
OppIndex+=1;
linenode->Index=OppIndex;
pDoc->RecordList.AddTail(DrawType);
pDoc->RecordList.AddTail(linenode);
}
break;
3、绘制矩形
绘制矩形图元时,只需要选择矩形的左上角和右下角即可。
绘制矩形图元与绘制直线图元步骤有相同之处就不一一详细叙述。
voidCPainterView:
:
OnLButtonUp(UINTnFlags,CPointpoint)
{
………………
caseRECTANGLE:
if(p==1)
{
p=0;
rectanglenode->rT.right=point.x;
rectanglenode->rT.bottom=point.y;
dc->MoveTo(rectanglenode->rT.left,rectanglenode->rT.top);
dc->LineTo(rectanglenode->rT.right,rectanglenode->rT.top);
dc->LineTo(rectanglenode->rT.right,rectanglenode->rT.bottom);
dc->LineTo(rectanglenode->rT.left,rectanglenode->rT.bottom);
dc->LineTo(rectanglenode->rT.left,rectanglenode->rT.top);
OppIndex+=1;
rectanglenode->Index=OppIndex;
pDoc->RecordList.AddTail(DrawType);
pDoc->RecordList.AddTail(rectanglenode);
}
break;
………………
}
4、绘制椭圆
绘制椭圆图元时,只需要选择椭圆外接矩形的左上角和右下角即可。
由于此时需要进行拖动操作,因此需要区分释放鼠标左键和按下鼠标左键消息。
当鼠标按下时为选择外接矩形左上角,并在OnLButtonDown中进行记录;然后拖动鼠标,此时,在OnMouseMove函数中根据当前外接矩形绘制临时椭圆,当用户对所绘制的椭圆满意时,释放鼠标左键选择外接矩形的终点,并在OnLButtonUp中进行记录。
voidCPainterView:
:
OnLButtonUp(UINTnFlags,CPointpoint)
{
………………
caseELLIPSE:
if(p==1)
{
p=0;
ellipsenode->rT.right=point.x;
ellipsenode->rT.bottom=point.y;
Arc(dc->m_hDC,ellipsenode->rT.left,ellipsenode->rT.top,
ellipsenode->rT.right,ellipsenode->rT.bottom,0,0,0,0);
OppIndex+=1;
ellipsenode->Index=OppIndex;
pDoc->RecordList.AddTail(DrawType);
pDoc->RecordList.AddTail(ellipsenode);
}
break;
………………
}
5、绘制三角形
绘制三角形图元时,首先要按下鼠标选择三角形的一个顶点,然后根据鼠标拖动绘制临时三角形,最后释放鼠标选择三角形的另一个顶点。
实际上,这里是根据三角形的外接矩形来进行绘制的,而绘制的结果则是等腰三角形。
由于此时需要进行拖动操作,因此需要区分释放鼠标左键和按下鼠标左键消息。
当鼠标按下为选择外接三角形的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 应用 程序设计 基础 课程设计
![提示](https://static.bdocx.com/images/bang_tan.gif)