windows程序设计实验指导书.docx
《windows程序设计实验指导书.docx》由会员分享,可在线阅读,更多相关《windows程序设计实验指导书.docx(20页珍藏版)》请在冰豆网上搜索。
windows程序设计实验指导书
实验四、WindowsGDI编程
实验目的:
1、了解windowsGDI设备环境的获取与设置。
2、了解windowsGDI绘图对象CPen,CBrush,CFont等的相关基本操作。
3、掌握建立简单图形交互的图形数据管理和鼠标工具设计等。
实验要求:
建立一个windowsSDI(单文档)应用程序,并编辑建立图形属性设置的无模式对话框、简单图形工具条等。
实现直线、矩形、椭圆、多边形的交互绘制及文字显示,并能进行图形属性设置。
实验可以选择竞赛作业题目,则本次的基本操作实验可以不做,竞赛作业可在课程后期交上,计算成绩有加分因素。
竞赛作业:
分析微软Office系列软件的绘图工具箱组件的图形编辑功能和操作特点,抽象出其数据组织的结构体系,并分析其需要的鼠标工具类型,设计出相应合理的数据结构和鼠标工具,模拟实现简单几何图形的绘制工具(能交互设置图形属性、有图形成组操作功能,可以实现图形的简单几何变换为佳)。
实验指导:
一、在VC++6.0环境中建立一个单文档工程。
1、通过资源编辑器编辑如下所示对话框资源和工具条资源。
注意生成对话框类后,为几个组合框添加字符串变量,为Spin控件添加控制变量,并为几个组合对话框添加初始数据:
映射模式:
MM_ANISOTROPIC
MM_HIENGLISH
MM_HIMETRIC
MM_ISOTROPIC
MM_LOENGLISH
MM_LOMETRIC
MM_TEXT
MM_TWIPS
画笔风格:
PS_SOLID
PS_DASH
PS_DOT
PS_DASHDOT
PS_DASHDOTDOT
PS_NULL
PS_INSIDEFRAME
画刷风格:
BS_HATCHED
BS_SOLID
线刷风格:
HS_BDIAGONAL
HS_CROSS
HS_DIAGCROSS
HS_FDIAGONAL
HS_HORIZONTAL
HS_VERTICAL
为生成的对话框类添加构造函数和变量:
.h文件
CGraphPropertyDlg(CView*pView);
GDI_ExeView*m_pView;
.cpp文件
CGraphPropertyDlg:
:
CGraphPropertyDlg(CView*pView)
{
m_pView=(GDI_ExeView*)pView;
}
2、在View类中添加数据成员:
public:
//无模式对话框
CGraphPropertyDlg*pDlg;
intm_nMapMode;//映射模式
LOGBRUSHm_lBrush;//用来交互设置CDC画刷属性的逻辑画刷
LOGPENm_lPen;//用来交互设置CDC画笔属性的逻辑画笔
COLORREFm_cFont;//用来交互设置CDC字体颜色
LOGFONTm_lFont;//用来交互设置CDC字体属性的逻辑字体
private:
//将字符串变量与整形变量之间建立映射关系,用于对话框的数据交互
CMapm_mapMode;
CMapm_mapPen;
CMapm_mapBrush;
CMapm_mapHBrush;
View类中数据成员的初始化:
CGDI_ExeView:
:
CGDI_ExeView()
{
//TODO:
addconstructioncodehere
//初始化映射模式的值-字符串映射表
m_mapMode.SetAt(MM_ANISOTROPIC,"MM_ANISOTROPIC");
m_mapMode.SetAt(MM_HIENGLISH,"MM_HIENGLISH");
m_mapMode.SetAt(MM_HIMETRIC,"MM_HIMETRIC");
m_mapMode.SetAt(MM_ISOTROPIC,"MM_ISOTROPIC");
m_mapMode.SetAt(MM_LOENGLISH,"MM_LOENGLISH");
m_mapMode.SetAt(MM_LOMETRIC,"MM_LOMETRIC");
m_mapMode.SetAt(MM_TEXT,"MM_TEXT");
m_mapMode.SetAt(MM_TWIPS,"MM_TWIPS");
//初始化画笔样式的值-字符串映射表
m_mapPen.SetAt(PS_SOLID,"PS_SOLID");
m_mapPen.SetAt(PS_DASH,"PS_DASH");
m_mapPen.SetAt(PS_DOT,"PS_DOT");
m_mapPen.SetAt(PS_DASHDOT,"PS_DASHDOT");
m_mapPen.SetAt(PS_DASHDOTDOT,"PS_DASHDOTDOT");
m_mapPen.SetAt(PS_NULL,"PS_NULL");
m_mapPen.SetAt(PS_INSIDEFRAME,"PS_INSIDEFRAME");
//初始化画刷样式的值-字符串映射表
m_mapBrush.SetAt(BS_HATCHED,"BS_HATCHED");
m_mapBrush.SetAt(BS_SOLID,"BS_SOLID");
m_mapBrush.SetAt(BS_NULL,"BS_NULL");
//初始化线模式画笔样式的值-字符串映射表
m_mapHBrush.SetAt(HS_BDIAGONAL,"HS_BDIAGONAL");
m_mapHBrush.SetAt(HS_CROSS,"HS_CROSS");
m_mapHBrush.SetAt(HS_DIAGCROSS,"HS_DIAGCROSS");
m_mapHBrush.SetAt(HS_FDIAGONAL,"HS_FDIAGONAL");
m_mapHBrush.SetAt(PS_DASHDOTDOT,"PS_DASHDOTDOT");
m_mapHBrush.SetAt(HS_HORIZONTAL,"HS_HORIZONTAL");
m_mapHBrush.SetAt(HS_VERTICAL,"HS_VERTICAL");
//初始化映射模式,画笔、画刷、字体样式
m_nMapMode=MM_TEXT;
m_lBrush.lbColor=RGB(0,0,0);
m_lBrush.lbHatch=HS_BDIAGONAL;
m_lBrush.lbStyle=BS_HATCHED;
m_lPen.lopnColor=RGB(0,0,0);
m_lPen.lopnStyle=PS_SOLID;
m_lPen.lopnWidth.x=1;
m_cFont=RGB(0,0,0);
m_lFont.lfHeight=30;
m_lFont.lfWidth=0;
m_lFont.lfEscapement=0;
m_lFont.lfOrientation=0;
m_lFont.lfWeight=FW_NORMAL;
m_lFont.lfItalic=FALSE;
m_lFont.lfUnderline=FALSE;
m_lFont.lfStrikeOut=FALSE;
m_lFont.lfCharSet=GB2312_CHARSET;
m_lFont.lfOutPrecision=OUT_STROKE_PRECIS;
m_lFont.lfClipPrecision=CLIP_STROKE_PRECIS;
m_lFont.lfQuality=DRAFT_QUALITY;
m_lFont.lfPitchAndFamily=VARIABLE_PITCH|FF_MODERN;
strcpy(m_lFont.lfFaceName,"楷体");
//无模式对话框的指针初始化
pDlg=NULL;
}
//析构函数的内存释放
CGDI_ExeView:
:
~CGDI_ExeView()
{
m_mapMode.RemoveAll();
m_mapPen.RemoveAll();
m_mapBrush.RemoveAll();
m_mapHBrush.RemoveAll();
}
二、DOC类中的图形数据项及数据管理函数的添加。
数据项添加(*Doc.h)
private:
//存储图形数据的数据结构
CArraym_lineObj;
CArraym_rectObj;
CArraym_ellipseObj;
CTypedPtrListm_polygonObj;
数据操作功能:
//向数据集中追加新的数据的函数
voidAddLine(CRectrect);
voidAddRect(CRectrect);
voidAddEllipse(CRectrect);
voidAddPolygon(CDrawPolygon*pPoly);
//在数据集中删除相应目标
BOOLDeleteLine(CRectrect);
BOOLDeleteRect(CRectrect);
BOOLDeleteEllipse(CRectrect);
BOOLDeletePolygon(intnPolyID);
//调整多边形位置于链表最后
voidPolygonToTail(intnPolyID);
//用于图形选择的函数,主要用了CRgn类的RectInRegion()方法
BOOLGetLineAt(CRect&rect,CPointpoint,LOGPENlogpen);
BOOLGetRectAt(CRect&rect,CPointpoint);
BOOLGetEllipseAt(CRect&rect,CPointpoint);
BOOLGetPolygonAt(CDrawPolygon&poly,CPointpoint);
//画图形的函数
voidDrawLines(CGDI_ExeView*pView,CDC*pDC);
voidDrawRects(CGDI_ExeView*pView,CDC*pDC);
voidDrawEllipses(CGDI_ExeView*pView,CDC*pDC);
voidDrawPolygons(CGDI_ExeView*pView,CDC*pDC);
//移动选中对象
voidMoveObj(CRectrect,intnPolyID,DrawShapetype,CPointdxy);
多边形的数据结构及相关操作函数请参考例程相关代码,争取看懂代码。
三、建立右键菜单资源并在View类中添加对右键菜单的消息处理。
voidCGDI_ExeView:
:
OnContextMenu(CWnd*pWnd,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehere
CMenumenu;
if(menu.LoadMenu(IDR_MENU_POP))
{
CMenu*pPopup=menu.GetSubMenu(0);
if(pPopup!
=NULL)
pPopup->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_LEFTALIGN,
point.x,point.y,pWnd);
}
}
voidCGDI_ExeView:
:
OnDelete()
{
//TODO:
Addyourcommandhandlercodehere
CGDI_ExeDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
CRectrdoc=m_rectSelect;
ClientToDoc(rdoc);
rdoc.NormalizeRect();
intidpoly=m_polygonSelect.m_nID;
if(m_bSelected)
{
switch(m_selectType)
{
caserectangle:
if(pDoc->DeleteRect(rdoc))
m_bSelected=FALSE;
Invalidate();
break;
caseellipse:
if(pDoc->DeleteEllipse(rdoc))
m_bSelected=FALSE;
Invalidate();
break;
caseline:
if(pDoc->DeleteLine(rdoc))
m_bSelected=FALSE;
Invalidate();
break;
casepolygon:
if(pDoc->DeletePolygon(idpoly))
m_bSelected=FALSE;
Invalidate();
break;
}
pDoc->UpdateAllViews(this);
}
}
voidCGDI_ExeView:
:
OnCdcattri()
{
//TODO:
Addyourcommandhandlercodehere
//无模式对话框的建立
if(pDlg==NULL)
{
pDlg=newCGraphPropertyDlg(this);
pDlg->Create(IDD_DIALOG1);
}
pDlg->ShowWindow(SW_SHOW);
}
View类OnDraw()函数的内容请参考下面代码:
//根据逻辑画笔、画刷设置设备环境画笔、画刷的属性
CBrushbrush;
if(!
brush.CreateBrushIndirect(&m_lBrush))
return;
CPenpen;
if(!
pen.CreatePenIndirect(&m_lPen))
return;
CBrush*pOldBrush=pDC->SelectObject(&brush);
CPen*pOldPen=pDC->SelectObject(&pen);
//画矩形
pDoc->DrawRects(this,pDC);
//画椭圆
pDoc->DrawEllipses(this,pDC);
//画多边形
pDoc->DrawPolygons(this,pDC);
//画直线
pDoc->DrawLines(this,pDC);
//还原设备环境
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
//画选中物体的选中句柄
if(m_bSelected)DrawSelectionObj();
//根据“字体”通用对话框中的选项绘制文本
CFontmyFont;
myFont.CreateFontIndirect(&m_lFont);
CFont*pOldFont=pDC->SelectObject(&myFont);
pDC->SetTextColor(m_cFont);
//根据逻辑字体显示文字
pDC->TextOut(80,80,"字体实例,显示选择字体");
//由CreateFont函数直接创建一种显示字体
CFontmyFont1;
myFont1.CreateFont(30,//字符的逻辑高度
0,//字符的平均宽度,缺省值
-450,//文本行顺时针旋转45度
0,
FW_BOLD,//加粗体
TRUE,//不倾斜
TRUE,//加下划线
FALSE,//不加删除线
GB2312_CHARSET,//中文字符集
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_MODERN,
"仿宋");//宋体
pOldFont=pDC->SelectObject(&myFont1);
//将字体颜色设置为兰色
pDC->SetTextColor(RGB(0,0,255));
//根据创建字体显示文字
pDC->TextOut(200,130,"自定义仿宋字体");
//还原设备环境
pDC->SelectObject(pOldFont);
无模式对话框与View之间的方法调用:
voidCGraphPropertyDlg:
:
OnApply()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData();
//调用视图类的方法将图形属性设置变量传过去
m_pView->OnApply();
}
View类中相应方法:
//由无模式对话框设置设备环境属性
voidCGDI_ExeView:
:
OnApply()
{
m_lPen.lopnWidth.x=pDlg->m_nWeight;
POSITIONpos;
pos=m_mapMode.GetStartPosition();
while(pos!
=NULL){
CStringszMapMode;
intnMapMode;
m_mapMode.GetNextAssoc(pos,nMapMode,szMapMode);
if(szMapMode==pDlg->m_strMode){
if(m_nMapMode!
=nMapMode)
{
m_nMapMode=nMapMode;
m_bSelected=FALSE;
}
break;
}
}
pos=m_mapPen.GetStartPosition();
while(pos!
=NULL){
CStringszPenStyle;
intnPenStyle;
m_mapPen.GetNextAssoc(pos,nPenStyle,szPenStyle);
if(szPenStyle==pDlg->m_strPStyle){
m_lPen.lopnStyle=nPenStyle;
break;
}
}
pos=m_mapBrush.GetStartPosition();
while(pos!
=NULL){
CStringszBrushStyle;
intnBrushStyle;
m_mapBrush.GetNextAssoc(pos,nBrushStyle,szBrushStyle);
if(szBrushStyle==pDlg->m_strBStyle){
m_lBrush.lbStyle=nBrushStyle;
break;
}
}
pos=m_mapHBrush.GetStartPosition();
while(pos!
=NULL){
CStringszHBrushStyle;
intnHBrushStyle;
m_mapHBrush.GetNextAssoc(pos,nHBrushStyle,szHBrushStyle);
if(szHBrushStyle==pDlg->m_strHBrush){
m_lBrush.lbHatch=nHBrushStyle;
break;
}
}
Invalidate();
XX文库-让每个人平等地提升自我XX文库-让每个人平等地提升自我}
View类中窗口-视口坐标转换方法:
//窗口-视图坐标变换函数
voidClientToDoc(CPoint&point);
voidClientToDoc(CRect&rect);
voidDocToClient(CPoint&point);
voidDocToClient(CRect&rect);
其它对话框初始化、控件消息响应代码请参考示例程序GDI_Exe。
四、运行程序,观察通过无模式对话框设置绘图设备环境的文字显示效果。
五、添加绘图的鼠标工具类和对绘图工具条消息的处理,重载View类的鼠标消息,调用鼠标工具。
View类中对选择工具的数据项添加,注意对变量的初始化也要加到构造函数中:
//用于单选操作的变量
BOOLm_bSelected;
DrawShapem_selectType;
CRectm_rectSelect;
CDrawPolygonm_polygonSelect;
鼠标工具类的具体代码请参考例程,View类中对鼠标消息的重载示例如下:
voidCGDI_ExeView:
:
OnButtonSelect()
{
//TODO:
Addyourcommandhandlercodehere
CDrawTool:
:
c_drawShape=selection;
}
voidCGDI_ExeView:
:
OnButtonLine()
{
//TODO:
Addyourcommandhandlercodehere
CDrawTool:
:
c_drawShape=line;
}
voidCGDI_ExeView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
CDrawTool*pTool=CDrawTool:
:
FindTool(CDrawTool:
:
c_drawShape);
if(pTool!
=NULL)
pTool->OnLBut