windows程序设计实验指导书3GDI编程正确解析.docx
《windows程序设计实验指导书3GDI编程正确解析.docx》由会员分享,可在线阅读,更多相关《windows程序设计实验指导书3GDI编程正确解析.docx(21页珍藏版)》请在冰豆网上搜索。
![windows程序设计实验指导书3GDI编程正确解析.docx](https://file1.bdocx.com/fileroot1/2023-2/6/be6cab5a-3375-4275-b25e-15c2039f3cd8/be6cab5a-3375-4275-b25e-15c2039f3cd81.gif)
windows程序设计实验指导书3GDI编程正确解析
实验三、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
为对话框类添加构造函数和变量:
C*Dlg(C*View*pView);
G*View*m_pView;
C*Dlg:
:
C*Dlg(C*View*pView)
{
m_pView=(C*View*)pView;
}
//重载消息
voidC*Dlg:
:
PostNcDestroy()
{
//TODO:
Addyourspecializedcodehereand/orcallthebaseclass
//用于在无模式对话框关闭时自动释放堆空间
deletethis;
CDialog:
:
PostNcDestroy();
}
//通过“颜色”通用对话框设置画笔颜色
voidC*Dlg:
:
OnButtonPencolor()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CColorDialogdlgColor;
if(dlgColor.DoModal()==IDOK){
m_pView->m_lPen.lopnColor=dlgColor.GetColor();
m_pView->Invalidate();
}
}
//通过“颜色”通用对话框设置画刷颜色
voidC*Dlg:
:
OnButtonBrucol()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CColorDialogdlgColor;
if(dlgColor.DoModal()==IDOK){
m_pView->m_lBrush.lbColor=dlgColor.GetColor();
m_pView->Invalidate();
}
}
//通过“字体”通用对话框设置字体属性
voidC*Dlg:
:
OnButtonFont()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
//声明一个“字体”通用对话框对象
CFontDialogdlg;
//定义“字体”通用对话框的初值
dlg.m_cf.lpLogFont=&(m_pView->m_lFont);
dlg.m_cf.rgbColors=m_pView->m_cFont;
dlg.m_cf.Flags|=CF_INITTOLOGFONTSTRUCT;
//打开“字体”通用对话框,若单击了“确定”按钮
if(dlg.DoModal()==IDOK){
//获取所选择的字体属性
dlg.GetCurrentFont(&(m_pView->m_lFont));
//获取所选择的字体颜色
m_pView->m_cFont=dlg.GetColor();
//重画窗口
m_pView->Invalidate();
}
}
//重载消息
BOOLC*Dlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
//TODO:
Addextrainitializationhere
//控件必要的初始化
m_ctrlSpin.SetRange(1,1000);
m_ctrlSpin.SetBase(10);
m_ctrlSpin.SetPos
(1);
m_ctrlPS.SetCurSel(0);
m_ctrlMM.SetCurSel(6);
m_ctrlHBS.SetCurSel(0);
m_ctrlBS.SetCurSel(0);
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
//EXCEPTION:
OCXPropertyPagesshouldreturnFALSE
}
voidC*Dlg:
:
OnApply()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData();
//调用视图类的方法将图形属性设置变量传过去
m_pView->OnApply();
}
voidC*Dlg:
:
OnOK()
{
//TODO:
Addextravalidationhere
UpdateData();
//也调用视图类的方法将图形属性设置变量传过去
m_pView->OnApply();
CDialog:
:
OnOK();
}
2、在View类中添加数据成员:
intm_nMapMode;//映射模式
LOGBRUSHm_lBrush;//用来交互设置CDC画刷属性的逻辑画刷
LOGPENm_lPen;//用来交互设置CDC画笔属性的逻辑画笔
COLORREFm_cFont;//用来交互设置CDC字体颜色
LOGFONTm_lFont;//用来交互设置CDC字体属性的逻辑字体
//将字符串变量与整形变量之间建立映射关系,用于对话框的数据交互
CMapm_mapMode;
CMapm_mapPen;
CMapm_mapBrush;
CMapm_mapHBrush;
3、在View类中添加成员函数和实现:
头文件(.h)中所加内容:
//无模式对话框
C*Dlg*pDlg;
//图形属性对话框Apply、OK按钮的消息处理
voidOnApply();
源文件(.cpp)中所加内容:
构造函数中添加内容:
*View:
:
*View()
{
//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;
}
C*View:
:
~*View()
{
m_mapMode.RemoveAll();
m_mapPen.RemoveAll();
m_mapBrush.RemoveAll();
m_mapHBrush.RemoveAll();
}
OnDraW()函数中添加显示文字代码:
void*View:
:
OnDraw(CDC*pDC)
{
CExm_Menu_ToolBarDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
//根据逻辑画笔、画刷设置设备环境画笔、画刷的属性
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);
//根据“字体”通用对话框中的选项绘制文本
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_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_ROMAN,
"仿宋");//宋体
pOldFont=pDC->SelectObject(&myFont1);
//将字体颜色设置为兰色
pDC->SetTextColor(RGB(0,0,255));
//根据创建字体显示文字
pDC->TextOut(200,130,"自定义仿宋字体");
//还原设备环境
pDC->SelectObject(pOldFont);
}
voidC*View:
:
On*()
{
//TODO:
Addyourcommandhandlercodehere
//无模式对话框的建立
if(pDlg==NULL)
{
pDlg=newC*Dlg(this);
pDlg->Create(IDD_DIALOG1);
}
pDlg->ShowWindow(SW_SHOW);
}
//由无模式对话框设置设备环境属性
voidC*View:
:
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();
}
4、在文挡类中添加相关绘图对象数据成员和方法:
头文件中:
//存储图形数据的数据结构
CArraym_lineObj;
CArraym_rectObj;
CArraym_ellipseObj;
CTypedPtrListm_polygonObj;
//向数据集中追加新的数据的函数
voidAddLine(CRectrect);
voidAddRect(CRectrect);
voidAddEllipse(CRectrect);
voidAddPolygon(CDrawPolygon*pPoly);
//画图形的函数
voidDrawLines(C*View*pView,CDC*pDC);
voidDrawRects(C*View*pView,CDC*pDC);
voidDrawEllipses(C*View*pView,CDC*pDC);
voidDrawPolygons(C*View*pView,CDC*pDC);
源文件中:
C*Doc:
:
~C*Doc()
{
//释放内存
m_lineObj.RemoveAll();
m_rectObj.RemoveAll();
m_ellipseObj.RemoveAll();
while(!
m_polygonObj.IsEmpty())
{
deletem_polygonObj.GetHead();
m_polygonObj.RemoveHead();
}
}
voidC*Doc:
:
AddLine(CRectrect)
{
m_lineObj.Add(rect);
UpdateAllViews(NULL);
}
voidC*Doc:
:
AddRect(CRectrect)
{
m_rectObj.Add(rect);
UpdateAllViews(NULL);
}
voidC*Doc:
:
AddEllipse(CRectrect)
{
m_ellipseObj.Add(rect);
UpdateAllViews(NULL);
}
voidC*Doc:
:
AddPolygon(CDrawPolygon*pPoly)
{
pPoly->m_nID=m_polygonObj.GetCount()+1;
m_polygonObj.AddTail(pPoly);
UpdateAllViews(NULL);
}
voidC*Doc:
:
DrawLines(C*View*pView,CDC*pDC)
{
CStringstr;
for(inti=0;i{
CRectrect=m_lineObj[i];
pView->DocToClient(rect);
pDC->MoveTo(rect.TopLeft());
pDC->LineTo(rect.BottomRight());
str.Format("%d",i+1);
pDC->TextOut(rect.left+rect.Width()/2+