实验一 VC++开发平台和简单VC++程
序设计
实验目的:
1.了解和使用VC++开发环境进行C++语言的编程;
2.掌握基本的错误调试。
3.学习完整的C++程序开发过程(编辑、编译、调试和运行);
4.理解并掌握程序的分支结构;
5.理解函数的声明和定义和调用方法;
6.理解标准库函数和自定义函数。
实验内容:
通过一个最简单的程序熟悉用VC++来调试Dos程序:
#include <iostream.h>
void main()
{
cout <<"I am a student.\n";
}
实验步骤:
步骤一:打开VC++开发软件,从[文件File]菜单中点击[新建New]菜单项,新建一个win32 Console Application的工程,在右上角的工程下输入该工程的名称Project Name,如hello,并设置该工程所保存的路径Location。最后点击确定。
步骤二:当确定后会出现要你选择工程类型的对话框,请选择一个空的工程Empty Project,即第一个选项。
步骤三:当单击确定后,工程建立完毕,接下来建立程序源文件,请再单击[文件File]菜单下的[新建New]出现原先出现的对话框,请选择 “文件Files”选项卡中的c++ source file选项,并取名File,如hello
步骤四: 当确定后,就进入了源代码的编辑窗口。
步骤五:编辑好前面实验内容中的源代码后,就进入了编译和调试阶段。先按下Crtl+F7进行编译,如果编译成功的话按下Ctrl+F5或者单击编译条上的第四个按钮惊叹号,自动建立EXE可执行文件并开始运行程序,同时将可执行文件和编译、连接过程中的中间代码一起放置在debug文件夹中。
思考题:
自行设计程序,并用VC++进行调试。
(1)设计两个数比较大小程序。
[要求]
两数必须从键盘上输入,提示连续输入两个数,必须两数间空一格或输完一数后回车。 显示较大的数,并且连续输两数时要有适当的提示,表示输入的是第几个数。
[参考代码]
#include <iostream.h>
#include <math.h>
double max(double x,double y) //max()函数定义,同时也是函数声明
{
if(x>y)
return x;
else return y;
}
void main()
{
double a,b,c;
cout <<"input two numbers:\n";
cin >>a >>b; c=max(a,b);
cout <<"the squart of maximum =" <<sqrt(c);
}
(2)设计计算圆的面积和周长。
[要求]
用户从键盘上输入圆的半径(任意一个浮点数),由程序负责计算出其相应的面积和周长,并将结果显示出来。
(3)求一元二次方程的根
[要求]
输入三个实数a,b,c(满足b*b-4*a*c>0),求处方程a*x*x+b*x+c=0的两个实根,并显示在屏幕上。
[分析提示]
通过cin输入方程系数a,b,c的值,而后根据求根公式计算并输出它的两个根。
(4)对上一题目中的解答进行扩展,如果随便输入三个实数的话,也要能计算出它的值来,这里就涉及到复数值,请同学们思考,复数如何来显示如何利用公式来计算这样的一元二次方程的根。
[提示]
这里要作一个判断,来明确根是否是实数还是复数。如果是复数的话,怎么样来表达复数,因为在计算机里是没有复数这样的数的, 所以我们可根据复数的两个实部和虚部来表示一个复数。
(5)将上一程序继续作扩展,如果我们将求一元二次方程的根的运算作成一个函数的话,而程序主函数里只要加入输入三个浮点数,然后调用该函数来显示结果。就可以了。
(6)输出方程的根是否可以作为函数的返回值?
(7)如果可以的话,那么由于函数只能返回一个值,不能返回两个值,那么怎么样设计此函数。输出结果的部分应该放在哪个部分?是在主函数里还是放在函数中?
第二篇:VC程序设计实验指导
VC++程序设计
实验指导书
李贵荣
计算机技术实验中心
前 言
一、上机实验目的
上机实验的目的是提高学生的分析问题、解决问题的能力和动手能力,通过实践环节理解 Visual C++ 面向对象与可视化开发工具的基本功能和用法,掌握MFC的类框架结构,学会使用Visual C++ 编写Windows应用程序。
二、实验基本内容
为了使学生在上机实验时目标明确,本实验指导书针对课程内容编写了4个必做实验。学生可以在课内机时先完成指导书中给出的程序,理解所学的知识,在此基础上再编写其他应用程序。指导书中的4个实验如下。
1.基本Windows程序设计(2H,必做)。
2.简单图形界面程序设计(2H,必做)。
3.多文档程序设计(2H,必做)。
4.综合性程序设计(4H,必做)。
三、实验任务与时间安排
《Visual C++ 程序设计》是一门实践性很强的课程,除了在课内安排的实验外,鼓励同学在课外用相关技术进行编程练习。《Visual C++ 程序设计》上机实验时间为10学时,与教学内容同时进行上机实验。10 个上机学时分为4个必做实验。
目 录
实验一 简单Windows程序设计. 3
实验二 简单界面设计. 7
实验三 多文档程序设计. 14
实验四 综合设计实验. 18
实验一 简单Windows程序设计
【实验目的】
1.学会创建Visual C++ 6.0 Win32应用程序工程文件。
2.掌握Windows应用程序的基本结构。
3.理解Windows编程中的窗口、句柄、消息传递等概念及其作用。
4.理解Windows图形设备接口的概念及了解常用Windows绘图函数。
5.学会在Visual C++ 6.0中编译、调试、发布应用程序。
【实验性质】
验证性实验(学时数:2H)
【实验要求】
1.在Windows下启动Visual C++ 6.0,创建工程文件。
2.编写一个简单的 Windows应用程序,并在程序中创建句柄,学会使用句柄。
3.分析上面的程序,在程序中使用注释语句标识出Windows程序的基本构成部分,并在注释语句中注明各部分的作用。
4.在上面程序中添加消息处理函数,使用程序完成如下功能:
(1)定义一只红色的画笔,绘制一个等边五边形;
(2)用不同颜色的线条连接互不想念的两个点;
(3)用不同颜色的画笔填充用上述方法所形成的图形中的每一个区域。
【参考程序】
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define Pi 3.1415926
long WINAPI WndProc(HWND hWnd,
UINT iMessage,
UINT wParam,
LONG lParam); //消息处理函数声明.
BOOL InitWindowsClass(HINSTANCE hInstance); //初始化窗口类声明
BOOL InitWindows(HINSTANCE hInstance, int nCmdShow);//初始化窗口声明.
HWND hWndMain;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) //主函数
{
MSG Message;
if(!InitWindowsClass(hInstance)) //初始化窗口类.
return FALSE;
if(!InitWindows(hInstance,nCmdShow)) //初始化窗口.
return FALSE;
while(GetMessage(&Message,0,0,0))
{
TranslateMessage(&Message); //消息循环.
DispatchMessage(&Message);
}
return Message.wParam;
}
long WINAPI WndProc(HWND hWnd,
UINT iMessage,
UINT wParam,
LONG lParam) //消息处理函数.
{
HDC hDC; //定义设备环境句柄.
HBRUSH hBrush; //定义画刷句柄
HPEN hPen; //定义画笔句柄
PAINTSTRUCT PtStr; //定义包含绘图信息的结构体变量
double dfRadious0=200.0,dfRadious1; //定义外部和内部正五边形外接圆半径.
POINT lpOuterPoints[5],lpInnerPoints[5];//定义外,内正五边形点结构数组.
POINT lpTriangle[3]; //定义三角形点结构数组.
dfRadious1=dfRadious0*sin(0.1*Pi)/sin(126.0/180*Pi);//根据外圆半径计算内园半径.
//计算内外正五边形的点坐标.
for(int i=0;i<5;i++)
{
lpOuterPoints[i].x=(long)(dfRadious0*cos(i*72.0/180*Pi))+200;
lpOuterPoints[i].y=(long)(dfRadious0*sin(i*72.0/180*Pi))+200;
lpInnerPoints[i].x=(long)(dfRadious1*cos(i*72.0/180*Pi+36.0/180*Pi))+200;
lpInnerPoints[i].y=(long)(dfRadious1*sin(i*72.0/180*Pi+36.0/180*Pi))+200;
}
switch(iMessage)
{
case WM_PAINT: //处理绘图消息.
hDC=BeginPaint(hWnd,&PtStr); //得到设备环境句柄
SetMapMode(hDC,MM_ANISOTROPIC); //设置映射模式.
SetWindowOrgEx(hDC,-100,-100,NULL); //设置坐标原点.
hPen=CreatePen(PS_SOLID,1,RGB(255,0,0)); //创新红色画笔.
SelectObject(hDC,hPen); //将画笔选入.
Polygon(hDC,lpOuterPoints,5); //画正五边形.
//填充正五边形的不同区域.
for(i=0;i<5;i++)
{
lpTriangle[0]=lpOuterPoints[i%5]; //生成图形中的三角形区域的坐标.
lpTriangle[1]=lpInnerPoints[i%5];
lpTriangle[2]=lpOuterPoints[(i+1)%5];
//创新新画刷.
hBrush=CreateSolidBrush(RGB(i*10,i*20,i*30));
SelectObject(hDC,hBrush); //选入新画刷.
Polygon(hDC,lpTriangle,3); //画三角形区域.
lpTriangle[2]=lpInnerPoints[(i+4)%5]; //生成图形中的三角形区域的坐标.
hBrush=CreateSolidBrush(RGB(i*40,i*30,i*20));//创新画刷.
SelectObject(hDC,hBrush); //选入画刷.
Polygon(hDC,lpTriangle,3); //画三角形区域.
}
hBrush=CreateSolidBrush(RGB(255,255,255));//创新白画刷.
SelectObject(hDC,hBrush); //选入画刷.
Polygon(hDC,lpInnerPoints,5); //画中心的五边形.
//用不同种颜色的画笔来绘制五角星.
MoveToEx(hDC,lpOuterPoints[0].x,lpOuterPoints[0].y,NULL);
for(i=1;i<=5;i++)
{
hPen=CreatePen(PS_SOLID,1,RGB(0,i*51,0));
SelectObject(hDC,hPen);
LineTo(hDC,lpOuterPoints[(i+2)%5].x,lpOuterPoints[(i+2)%5].y);
}
hPen=(HPEN)(GetStockObject(PS_NULL));
DeleteObject(hPen); //删除画笔.
DeleteObject(hBrush); //删除画刷.
EndPaint(hWnd,&PtStr); //结束绘图.
return 0;
case WM_DESTROY: //处理关闭窗口信息.
PostQuitMessage(0); //向应用程序发送WM_QUIT消息.
return 0;
default:
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
}
BOOL InitWindows(HINSTANCE hInstance, int nCmdShow) //初始化
{
HWND hWnd; //定义窗口句柄.
hWnd=CreateWindow("Polygon", //窗口类名.
"五边形", //窗口实例标题.
WS_OVERLAPPEDWINDOW, //窗口风格.带边框,标题栏,系统菜单和最大和最小按钮.
CW_USEDEFAULT, //窗口左上角坐标.
0, //窗口左上角坐标.
CW_USEDEFAULT, //窗口宽度
0, //窗口高度
NULL, //无父窗口.
NULL, //无主菜单.
hInstance, //创建此窗口的应用程序的当前句柄.
NULL); //指向一个传递给窗口的参数值从指针.
//不使用该值.
if(!hWnd) //如果窗口创建失败,返回false.
return FALSE;
hWndMain=hWnd; //将窗口句柄传递给全局变量.
ShowWindow(hWnd,nCmdShow); //显示窗口.
UpdateWindow(hWnd); //更新并绘制用户区.
return TRUE;
}
BOOL InitWindowsClass(HINSTANCE hInstance) //初始化窗口类.
{
WNDCLASS WndClass; //定义窗口类.
WndClass.cbClsExtra=0; //窗口类无扩展.
WndClass.cbWndExtra=0; //窗口实例无扩展.
WndClass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH));//窗口背景为白色.
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW); //窗口采用箭头光标.
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); //窗口的最小化图标为缺省图标.
WndClass.hInstance=hInstance; //当前实例句柄.
WndClass.lpfnWndProc=WndProc; //窗口处理函数.
WndClass.lpszClassName="Polygon"; //窗口类名.
WndClass.lpszMenuName=NULL; //无菜单
WndClass.style=0; //窗口类型为缺省类型.
return RegisterClass(&WndClass); //返回注册窗口的值.
}
实验二 简单界面设计
【实验目的】
使用MFC应用程序向导,生成Windows基本对话框。通过对Windows基本对话框的学习和使用,了解MFC的类库结构,掌握CDialog的基本组成,了解对话框程序的工作过程,学习使用常用的Windows控件,学会编写消息处理函数。
【实验性质】
验证性实验(学时数:2H)
【实验要求】
使用MFC应用程序向导编写一个基本对话框程序。 在程序综合运用静态文本框、编辑框、按钮控件,在程序练习使用文件对话框、颜色选择对话框、字体对话框、打印对话框等常用类。
【实验内容】
编写一个简单的计算器程序,要求有两个操作数,实现加、减、乘、除。参考界面如下图:
//对话框定义(部分)
// CMy11_4Dlg dialog
class CMy11_4Dlg : public CDialog
{
// Construction
public:
CMy11_4Dlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CMy11_4Dlg)
enum { IDD = IDD_MY11_4_DIALOG };
CEdit m_Item1_Edit;
CEdit m_Item2_Edit;
CString m_sResult_Edit;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMy11_4Dlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CMy11_4Dlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnDevideButton();
afx_msg void OnDifferenceButton();
afx_msg void OnExitButton();
afx_msg void OnMultipleButton();
afx_msg void OnAddButton();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//对话框实现(部分)
#include "stdafx.h"
#include "11_4.h"
#include "11_4Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMy11_4Dlg dialog
CMy11_4Dlg::CMy11_4Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CMy11_4Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMy11_4Dlg)
m_sResult_Edit = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMy11_4Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMy11_4Dlg)
DDX_Control(pDX, IDC_ITEM1_EDIT, m_Item1_Edit);
DDX_Control(pDX, IDC_ITEM2_EDIT, m_Item2_Edit);
DDX_Text(pDX, IDC_RESULT_EDIT, m_sResult_Edit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMy11_4Dlg, CDialog)
//{{AFX_MSG_MAP(CMy11_4Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_DEVIDE_BUTTON, OnDevideButton)
ON_BN_CLICKED(IDC_DIFFERENCE_BUTTON, OnDifferenceButton)
ON_BN_CLICKED(IDC_EXIT_BUTTON, OnExitButton)
ON_BN_CLICKED(IDC_MULTIPLE_BUTTON, OnMultipleButton)
ON_BN_CLICKED(IDC_ADD_BUTTON, OnAddButton)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMy11_4Dlg message handlers
BOOL CMy11_4Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CMy11_4Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CMy11_4Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMy11_4Dlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMy11_4Dlg::OnDifferenceButton()
{
// TODO: Add your control notification handler code here
//开始加入代码
char cstrItem1[10],cstrItem2[10]; //定义编辑框中的字符串对象.
double dfItem1,dfItem2,dfResult; //定义编辑框中的数字.
char cBuffer[10]; //定义存储转换结构的字符串.
m_Item1_Edit.GetWindowText(cstrItem1,10); //得到Item1编辑框中的字符串.
m_Item2_Edit.GetWindowText(cstrItem2,10); //得到Item2编辑框中的字符串.
dfItem1=atof((LPCTSTR)cstrItem1); //将Item1编辑框中的字符串转换为数字.
dfItem2=atof((LPCTSTR)cstrItem2); //将Item2编辑框中的字符串转换为数字.
dfResult=dfItem1-dfItem2; //求差
_gcvt(dfResult,10,cBuffer); //将差转化为字符串.存储在cbuffer中.
m_sResult_Edit=(LPCTSTR)cBuffer; //将结果字符串输出到Result编辑框中
UpdateData(FALSE); //刷新屏幕.
//结束代码.
}
void CMy11_4Dlg::OnAddButton() //单击Add按钮.
{
//开始加入代码.
char cstrItem1[10],cstrItem2[10]; //定义编辑框中的字符串对象.
double dfItem1,dfItem2,dfResult; //定义编辑框中的数字.
char cBuffer[50]; //定义存储转换结构的字符串.
m_Item1_Edit.GetWindowText(cstrItem1,10); //得到Item1编辑框中的字符串.
m_Item2_Edit.GetWindowText(cstrItem2,10); //得到Item2编辑框中的字符串.
dfItem1=atof((LPCTSTR)cstrItem1); //将Item1编辑框中的字符串转换为数字.
dfItem2=atof((LPCTSTR)cstrItem2); //将Item2编辑框中的字符串转换为数字.
dfResult=dfItem1+dfItem2; //求和
_gcvt(dfResult,10,cBuffer); //将和转化为字符串.存储在cbuffer中.
m_sResult_Edit=(LPCTSTR)cBuffer; //将结果字符串输出到Result编辑框中
UpdateData(FALSE); //刷新屏幕.
//结束代码.
}
void CMy11_4Dlg::OnMultipleButton() //单击Multiple按钮.
{
//开始加入代码.
char cstrItem1[10],cstrItem2[10]; //定义编辑框中的字符串对象.
double dfItem1,dfItem2,dfResult; //定义编辑框中的数字.
char cBuffer[10]; //定义存储转换结构的字符串.
m_Item1_Edit.GetWindowText(cstrItem1,10); //得到Item1编辑框中的字符串.
m_Item2_Edit.GetWindowText(cstrItem2,10); //得到Item2编辑框中的字符串.
dfItem1=atof((LPCTSTR)cstrItem1); //将Item1编辑框中的字符串转换为数字.
dfItem2=atof((LPCTSTR)cstrItem2); //将Item2编辑框中的字符串转换为数字.
dfResult=dfItem1*dfItem2; //求积
_gcvt(dfResult,10,cBuffer); //将积转化为字符串.存储在cbuffer中.
m_sResult_Edit=(LPCTSTR)cBuffer; //将结果字符串输出到Result编辑框中
UpdateData(FALSE); //刷新屏幕.
//结束代码.
}
void CMy11_4Dlg::OnDevideButton() //单击Devide按钮.
{
// 加入代码.
char cstrItem1[10],cstrItem2[10]; //定义编辑框中的字符串对象.
double dfItem1,dfItem2,dfResult; //定义编辑框中的数字.
char cBuffer[10]; //定义存储转换结构的字符串.
m_Item1_Edit.GetWindowText(cstrItem1,10); //得到Item1编辑框中的字符串.
m_Item2_Edit.GetWindowText(cstrItem2,10); //得到Item2编辑框中的字符串.
dfItem1=atof((LPCTSTR)cstrItem1); //将Item1编辑框中的字符串转换为数字.
dfItem2=atof((LPCTSTR)cstrItem2); //将Item2编辑框中的字符串转换为数字.
dfResult=dfItem1/dfItem2; //求商
_gcvt(dfResult,10,cBuffer); //将商转化为字符串.存储在cbuffer中.
m_sResult_Edit=(LPCTSTR)cBuffer; //将结果字符串输出到Result编辑框中
UpdateData(FALSE); //刷新屏幕.
//结束代码.
}
void CMy11_4Dlg::OnExitButton() //单击Exit按钮.
{
//加入代码.
OnOK(); //退出.
}
实验三 多文档程序设计
【实验目的】
了解Windows程序的文档、视图结构的基本概念,学会使用AppWizard创建基于文档/视图结构的框架应用程序以及文档类、视图类和文档模板类的应用。
【实验性质】
验证性实验(学时数:2H)
【实验要求】
1.掌握Microsoft MFC中支持的文档/视图结构的基本概念,学会通过应用程序向导生成单文档(SDI)和多文档应用程序(MDI)。
2.编写简单单文档界面应用程序。
3.编写简单多文档界面应用程序。
【实验内容】
(一)单文档界面程序设计
创建一个应用程序,其界面的标题为MySdi。在应用程序的主窗口中显示一行文本“您好,单文档界面的例程!”,并始终出现在窗口的中央。在“编辑”菜单上有一个菜单项“改变显示文本”,单该项可以弹出一个对话框,通过这个对话框可以改变主窗口中的显示文本。
(1) 创建工程文件
首先创建一个MFC AppWizard(exe)工程文件,并取名为MySdi。建立MySdi应用程序工程文件时选择Single Document(单文档)选项,其他的都是默认选项。
(2) 添加资源
为程序添加一个简单对话框CDlgInput,其中有一个文本输入控件IDC_EDIT1,关联的成员变量为m_input,类型为CString。操作过程如前面对话框实验。
(3) 为CMysdiDoc类添加成员变量
为CMysdiDoc类添加成员变量可以有两种方法。
第一种方法是利用VC的可视化编程工具。在Workspace窗口的ClassView选项卡中展开Mysdi Classes,可以看到AppWizard为Mysdi程序生成的所有类。右击CMysdiDoc类,在弹出菜单中单击Add Member Variable选项,在Variable Type框中输入成员变量的类型CString,在Variable Declaration框中输入成员变量名m_str。由于希望其他类的对象可以访问该成员变量,因此访问类型设置为public。单击OK将该成员变量的定义添加到类的定义中。
第二种方法是手动的在CMysdiDoc的定义(MysdiDoc.h)中添加,直接为其添加一个成员变量。
public : CString m_str;
(4) 文档变量初始化
为了测试该程序,我们在CMsdiDoc的OnNewDocument成员变量中为公有成员m_str赋以“您好,单文档界面的例程!”,方法是使用下面的代码替换OnNewDocument的实现代码中的“//TODO”注释。
BOOL CMysdiDoc::OnNewDocument( )
{
if(!CDocument::OnNewDocument( ))
return FALSE;
m_str = “您好,单文档界面的例程!”;
return TRUE;
}
(5) 视图的输出
在MFC应用程序中,文档类是和视图类一起协作完成应用程序功能的。下面我们将为Mysdi程序的视图类CMysdiView类的OnDraw成员函数添加一些代码,以将文档类的m_str成员变量的内容显示到视图的框架窗口中。
void CMysdiView::OnDraw(CDC * pDC)
{
CMysdiDoc * pDoc = GetDocument( );
ASSERT VALID(pDoc);
//TODO: add draw code for native data here
CRect rectClient;
GetClientRect( rectClient); //获取当前客户区的指针
CSize sizeClient = rectClient.Size(); //获取当前客户区的大小
CString str = pDoc -> m_str; //从文件中读取数据
CSize sizeTextExtent = pDC -> GetTextExtent(str); //用新选定的字体绘制字符串
pDC -> TextOut ((sizeClient.cx-sizeTextExtent.cx)/2 , (sizeClient.cy-sizeTextExtent.cy)/2 , str);
}
(6) 串行化(参见教材)
(二)多文档界面程序设计
设计一个多文档应用程序,理解文档/视图结构模型中文档与视图的作用。
(1)创建MDI项目文件
创建步骤同(一),应用程序类型选项卡为:多文档。
(2)通过ClassView向导创建第二个文档类CMyMdiDoc2,其基类为CDocument。
(3)创建资源。
打开资源文件 resource.h,在文件中加入下列代码:
#define IDR_MYMDITYPE2 135
这样就定义了第二个文档类的资源ID,以后定义的菜单、文档模板等资源均可以使用这个ID。
文档模板的资源:
资源模式参见教材相关内容,现在手工加入第二个资源模板字符串。用记事本或其它编辑器打开MyMdi.rc资源文件,找到下面的代码:
IDR_MYMDITYPE "\nMymdi\nMymdi\nMymdi 文件 (*.mmd)\n.mmd\nMymdi.Document\nMymdi Document"
这是第一个文档类的的资源字符串,在后面加入:
IDR_MYMDITYPE2 "\nMymdi2\nMymdi2\nMymdi2 文件 (*.mm2)\n.mm2\nMymdi.Document\nMymdi2 Document"
这是第二个文档类的资源字符串。
(4)菜单、对话框资源
单击Workplace窗口中的Resource View选项卡,展开MyMdi resources | Menu,在“编辑”子菜单中添加一个新的菜单项“改变显示文本”,并将此菜单项的ID设置为ID_EDIT_CHANGETEXT。
使用对话框实验中的方法,生成对话框类CDlgInput,并添加Edit Box控件及其相关联的成员变量m_input,类型为CString。
(5)代码编辑
创建文档模板类,因为本应用程序支持多种文档,所以在应用程序的InitInstance()函数中,需要定义新的文档模板的对象,打开MyMdi.cpp文件,查找如下代码:
BOOL CMymdiApp::InitInstance()
{
AfxEnableControlContainer();
……..
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_MYMDITYPE,
RUNTIME_CLASS(CMymdiDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CMymdiView));
AddDocTemplate(pDocTemplate);
………..
上面是第一个文档的模板,下面在它的后面添加第二个文档的模板,代码如下:
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_MYMDITYPE,
RUNTIME_CLASS(CMymdiDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CMymdiView));
AddDocTemplate(pDocTemplate);
CMultiDocTemplate* pDocTemplate2;
pDocTemplate2 = new CMultiDocTemplate(
IDR_MYMDITYPE2,
RUNTIME_CLASS(CMymdiDoc2), //MDI派生文档类的CRuntimeClass对象的指针
RUNTIME_CLASS(CChildFrame), // MDI派生子框架类的CRuntimeClass对象的指针
RUNTIME_CLASS(CMymdiView2)); //创建文档模板的对象
AddDocTemplate(pDocTemplate2); //将新模板添加到应用程序的文档模板列表中
为了使CMyMdiApp类能够访问第二个文档/视图,需要在MyMdiApp.h中加入它们的头文件。
#include "mymdiDoc2.h"
#include "mymdiView2.h"
完善CMyMdiDoc2类,部分代码如下:
BOOL CMymdiDoc2::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
m_str="您好, 多文档界面的例程!";
return TRUE;
}
void CMymdiDoc2::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
ar<<m_str; //保存文档内容
}
else
{
ar>>m_str; //读取文档内容
}
}
/////////////////////////////////////////////////////////////////////////////
// CMymdiDoc2 commands
void CMymdiDoc2::OnEditChangetext()
{
// TODO: Add your command handler code here
CDlgInput inputDlg;//建立一个CinputDlg的对象inputDlg
if( inputDlg.DoModal()==IDOK )//使inputDlg成为一个模式对话框
{
m_str = inputDlg.m_input;//获取输入的字符串
UpdateAllViews(NULL); //更新视图
}
}
视图输出,需要在CMyMdiView2::OnDraw(CDC * pDC)中添加下列代码:
void CMymdiView2::OnDraw(CDC* pDC)
{
CMymdiDoc2* pDoc = (CMymdiDoc2*)GetDocument();
ASSERT_VALID(pDoc);
// TODO: Add your specialized code here and/or call the base class
CRect rectClient; // 获取当前客户区的大小
GetClientRect(rectClient);
CSize sizeClient=rectClient.Size();
CString str=pDoc->m_str; // 从文件中读取数据
CSize sizeTextExtent=pDC->GetTextExtent(str); // 用新选定的字体绘制字符串
pDC->TextOut((sizeClient.cx-sizeTextExtent.cx)/2,
(sizeClient.cy-sizeTextExtent.cy)/2,
str);
}
实验四 综合设计实验
【实验目的】
了解Visual C++ 6.0开发环境的常用功能,使用Visual C++ 6.0编写对话框/文档视图结构程序,综合运用C++的面向对象程序设计方法,了解MFC类库结构和掌握常用MFC类,学会运用Visual C++较熟练开发MFC应用程序。
【实验性质】
综合性实验(学时数:4H)
【实验要求】
1.了解MFC类库结构,熟悉常用的MFC类。
2.根据个人特点和兴趣,使用Visual C++设计一个功能较完善的Windows应用程序。
3.内容可以选择下面的内容之一:
(1)多媒体应用程序
(2)数据库应用程序
(3)网络应用程序
4.人机界面要求:
主界面的菜单项/按钮不少于5个,其功能均要求实现;对话框不少于3个。
5.程序的文档要求:
要求程序的说明和注释尽可能详尽,通过注释能够反映出程序的思路和执行流程。
【实验内容】
本次实验为设计型实验,实验内容由学生根据自身情况选择。可以参考教材中的第4篇----Visual C++高级编程中的部分内容。