通信与信息工程学院
2010 /2011 学年 第 2 学期
课程设计 实验报告
模 块 名 称 VC++软件设计
专 业 电子信息工程
学 生 班 级 B090110
学 生 学 号
学 生 姓 名
指 导 教 师 董恒等
日 期 2012 年 5 月
实验内容
本课程设计分成练习题和综合题两部分。基础练习题11道中每个学生选择5个完成,要求如下:必做:1;2,3选择其一;4,5选择其一;6- 11选择其二。综合课题任选一道。
一 、 练习题:
1、基本环境调试
将例程1用VC++打开,修改错误使程序能够运行。理解编译错误,运行错误等。
2、文件操作
写一个档案文件保存以下内容:
学生姓名,性别,年龄,家庭住址,电话,电子邮件,爱好等。
再以上基础上进行该文件的读出并可编辑浏览显示。
3、图形编程
提供一个图形工具界面,让用户能够画出直线,椭圆,多边形等几何元素,结果可以保存并可读出。
4、字符串操作
能够从磁盘上选择打开文本文档,读入所有内容并显示,统计所有的字符数目,单词数目,中文字符串的数目。
5、动态链接库
目的:了解MFC支持的三种动态链接库:Win32DLL,MFC常规DLL, MFC扩展库。掌握封装DLL的基本方法。
二、综合题:
文件编辑
创建一个多文档工程,实现对于磁盘文件的浏览,编辑等功能。
能够以文本文件,二进制文件方式打开文件;
支持剪贴板功能;
支持搜索,查找,替换功能;
支持文件定位;
基本步骤:
(1)数据库后台设计,数据准备;
(2)界面设计;
(3)功能实现;
(4)测试。
实验环境
VC++ 6.0
实验步骤
基础题
题目1 基本环境调测
1.1实验目的:
该程序计算任意数目以内的素数并且输出,要输入范围参数。修改给出的这段程序,使之能够运行,理解编译错误,运行错误等。
1.2程序说明:
本题是一道改错题,根据已经给出的例程1进行改错及完善的操作。打开VC++6.0,将例程1打开,点编译时会提示有
1.3测试结果:
总结分析:在调试的过程中,通过双击错误提示很轻松的将前两个编译错误很容易改出来了,存放素数的数组定义的太小而导致的问题则比较隐蔽,通过这个题目我对compiling,linking,build有了进一步的理解。
1.4程序:
void CFund1Dlg::OnButton1()
{
UpdateData();
int Primes[200];//存放素数的数组.
int index=0;
//简单的求素数算法.
bool flag=true;
for(int m=2;m<=m_limit;m++)
{
for(int i=2;i<m;i++)
{
if(m%i==0)
{
flag=false;
break;}
else
flag=true;
}
if(flag==true)
Primes[index++]=m;
}
CWnd *pWnd=GetDlgItem(IDC_STATICOUTPUT);
CString str;
str.Format("%d以内的素数有%d个:\n\n",m_limit,index);
for(int i=0;i<index;i++){
char buf[10];
sprintf(buf,"%d ",Primes[i]);
str+=buf;
}
pWnd->SetWindowText(str);
}
题目2 文件操作
2.1实验目的
1) 熟练掌握文件操作,学会用Write() 函数和Read()函数写文件和读文件
2) 学会建立MFC工程提供比较直观的对话框界面供浏览
2.2程序说明:
系统提供了一个控件面板,用鼠标选中我们需要的控件,将其放置对话框,设计出我们需要的程序界面。然后在建立类向导中为控件关联一个变量,分别为m_name,m_age,m_phone,m_email,m_address,m_hoppy,均为Cstring类型。然后就是编写控件消息处理函数,我们需要编写的是void CMyDlg::OnSave() ,void CMyDlg::OnOpen() ,分别对应控件“打开”“保存”,还需要编写voidCMyDlg::Display(StuInfo *si)显示函数。这样,这个程序的基本功能就满足要求了。
2.3流程图:
2.4测试结果:
总结分析:本题主要考察要求的是我们能否学会建立MFC工程提供比较直观的对话框界面供浏览,并编写相应的事件函数,以及熟练掌握文件操作,学会用Write() 函数和Read()函数写文件和读文件。
2.5关键程序:
//显示函数
void CMyDlg::Display(StuInfo *si)
{
//StuInfo si=*m_StuIndex;
m_name=si->name;
m_age=si->age;
m_phone=si->phone;
m_email=si->email;
m_hoppy=si->hoppy;
m_address=si->address;
UpdateData(FALSE); //UpdateData(FALSE)是将控件的关联变量的值传给控件并改变控件状态
}
//保存函数
void CMyDlg::OnSave()
{
// TODO: Add your control notification handler code here
UpdateData(); //UpdateData() 是MFC的窗口函数,用来刷新数据的
StuInfo si;
memset(&si,0,sizeof(StuInfo)); //memset() 函数常用于内存空间初始化
strcpy(si.name,m_name);
strcpy(si.phone,m_phone);
strcpy(si.email,m_email);
strcpy(si.address,m_address);
strcpy(si.hoppy,m_hoppy);
strcpy(si.age,m_age);
// write into the file
CFileDialog fileDlg(FALSE);
fileDlg.m_ofn.lpstrFilter="Stud Info(*.si)\0*.si\0All Files(*.*)\0*.*\0\0";
fileDlg.m_ofn.lpstrDefExt="si";
if(IDOK==fileDlg.DoModal())
{
CFile file(fileDlg.GetFileName(), CFile::modeCreate | CFile::modeWrite);
file.Write(&si, sizeof(StuInfo));
file.Close();
}
}
//打开文件函数
void CMyDlg::OnOpen()
{
// TODO: Add your control notification handler code here
CFileDialog fileDlg(TRUE); //构造对话框对象(FALSE)表示保存(TRUE)表示打开
fileDlg.m_ofn.lpstrFilter = "Stud Info(*.si)\0*.si\0All Files(*.*)\0*.*\0\0";
if(IDOK==fileDlg.DoModal())//DoModal负责对模态话框的创建和撤销
{
CFile file(fileDlg.GetFileName(), CFile::modeRead);
StuInfo si;
file.Read(&si,sizeof(StuInfo));
file.Close();
Display(&si);
}
}
void CMyDlg::OnAdd()
{
// TODO: Add your control notification handler code here
UpdateData();
StuInfo stuinfo;
memset(&stuinfo,0,sizeof(StuInfo));
strcpy(stuinfo.name,m_name);
strcpy(stuinfo.age,m_age);
strcpy(stuinfo.phone,m_phone);
strcpy(stuinfo.hoppy,m_hoppy);
strcpy(stuinfo.email,m_email);
// m_Records.push_back(stuinfo);
// m_StuIndex=m_Records.end()-1;
题目三:图形编辑
1)掌握建立基于MFC的文档工程的步骤
2)熟悉鼠标绘图的机理,了解鼠标消息响应函数框架
3.2程序说明:
本题是使用MFC实现在界面上绘图的功能,基本包括点、直线、椭圆和矩形。关键问题是确定用户选择的图形类型,从而可以调用相应的类库,并将类实例化之后使用其中各种绘图函数。同时需要记录用户鼠标点击的操作,获取鼠标指针当前的屏幕坐标,确定图形的起始位置和结束位置。
3.3程序流程图
3.4测试结果:
结果分析:程序提供了一个图形绘制界面,我们可以画出直线,椭圆,矩形,绘制的结果可以通过文件中的保存并可通过“打开”读出原来原来已经保存的图形。要求我们能够熟悉鼠标绘图的机理,了解鼠标消息响应函数框架。
3.5关键程序:
void CGraphicView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if (!pDoc)
return;
int index;
index = pDoc->m_ObArray.GetSize();//取得直线的数目
for(int i=0;i<index;i++)
{
CShape * pShape = (CShape*) pDoc->m_ObArray.GetAt(i);
pShape->Drawing(pDC);
}
}
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
this->last=point;
CView::OnLButtonDown(nFlags, point);
}
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDrawDoc *pDoc = GetDocument();
pDoc->AddShape(last,point, m_sType);
Invalidate();
CView::OnLButtonUp(nFlags, point);
}
题目四:字符串的操作
4.1实验目的
1)熟练掌握字符串处理
2)熟练掌握判断中文字符,英文单词的方法
3)掌握文件操作,如文件读取,文件存储
4)掌握MFC工程建立方法
4.2程序说明:
本题是对文本文件内的字符信息做统计工作。主要思想是通过嵌套判断来实现对字母,字符,汉字的区分。编写一个统计的函数Counting(char *p, int length)来统计,字符数numChar的大小由GetLength()得到,用if((p[i]>='a'&&p[i]<='z')||(p[i]>='A'&&p[i]<='Z'))判断是否是英文字母,因为我们知道英文单词的开头和结尾都是英文字符,我们不妨设置bool wordBeg = true,如果是,则numWord++,并且将wordBeg = false,这样判断完全部就能得到英文单词的数目了。再利用if(p[i]>=0x00&&p[i]<=0x7F)得到ASC码的数目,用总的字符数减去ASC码的数目就能得到中文字符数目的两倍(因为一个中文占两个字符)。这样所要求的都可以求出来了。
定义Display()和OnOpen()。把当前统计的数目分别赋给m_char,m_chinese,m_word,再通过UpdateData(FALSE) 将控件的关联变量的值传给控件并改变控件状态显示在窗口。OnOpen(),打开一个文本,CFileDialog fileDlg(TRUE);dwFileLen = file.GetLength(),用file.Read(pBuf, dwFileLen)读取dwFileLen长度的文件,用Close()关闭文件。
4.3程序流程图:
4.4测试结果:
总结分析:本题只要考察我们是否能够熟练掌握字符串处理,掌握判断中文字符,英文单词的方法掌握文件操作,如文件读取,文件存储掌握MFC工程建立方法。
4.5关键程序:
void CMyDlg::OnOpen()
{
// TODO: Add your control notification handler code here
CFileDialog fileDlg(TRUE); //构造对话框对象(FALSE)表示保存(TRUE)表示打开
fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0\0";
if(IDOK==fileDlg.DoModal())
{
CFile file(fileDlg.GetFileName(), CFile::modeRead);
char *pBuf;
DWORD dwFileLen;
dwFileLen = file.GetLength(); //长度
// This the # of total char
this->m_char= dwFileLen;
pBuf = new char[dwFileLen];
file.Read(pBuf, dwFileLen);
file.Close();
m_content =pBuf;
Counting(pBuf, dwFileLen);
}
}
void CMyDlg::Counting(char *p, int length) //计算模块
{
bool wordBeg = true;
bool flag = true;
int numAsc=0;
this->m_word=0;
for(int i=0; i<length; i++)
{
if((p[i]>='a'&&p[i]<='z')||(p[i]>='A'&&p[i]<='Z'))
{
if(wordBeg)
{
this->m_word++;
wordBeg = false;
}
}
else
{
wordBeg = true;
}
if(p[i]>=0x00&&p[i]<=0x7F)
numAsc++;
}
this->m_chinese = (length-numAsc)/2;
//this->numChar=length-numChinese;
UpdateData(FALSE);
}
题目五:动态链接库
5.1实验目的
了解MFC 支持的三种动态链接库:Win32DLL,MFC 常规DLL, MFC扩展库。掌握封装DLL的基本方法。
5.2程序说明:
本题是使用动态链接库来完成一些简单的程序算法。动态链接库分为Win32、MFC及MFC扩展三种,分别通过不同的方法来建立。动态链接库编写完毕后,生成Dll和Lib文件,将其复制到测试工程的Debug文件夹下,并在工程中与Lib文件关联之后就可以调用动态链接库中的函数或方法
5.3测试结果:
总结分析:本题主要要求我们了解MFC 支持的三种动态链接库:Win32DLL,MFC 常规DLL, MFC扩展库,掌握封装DLL的基本方法。
5.4关键程序:
void CTestDLLDlg::OnButtonAdd()
{
// TODO: Add your control notification handler code here
HINSTANCE hInst;
hInst=LoadLibrary("Win32DLL.dll");
typedef int (*ADDPROC)(int a);
ADDPROC Add=(ADDPROC)GetProcAddress(hInst,"add");
if(!Add)
{
MessageBox("获取函数地址失败");
return;
}
UpdateData(TRUE);
m_r1=Add(m_n);
UpdateData(FALSE);
}
void CTestDLLDlg::OnButtonfactorial()
{
// TODO: Add your control notification handler code here
HINSTANCE hInst;
hInst=LoadLibrary("MFCDLL.dll");
typedef int (*ADDPROC)(int a);
ADDPROC Jiechen=(ADDPROC)GetProcAddress(hInst,"Jiechen");
if(!Jiechen)
{
MessageBox("获取函数地址失败");
return;
}
UpdateData(true);
m_r2=Jiechen(m_n2);
UpdateData(FALSE);
}
二 、综合题。
实验目的:
首先创建一个多文档工程,实现对于磁盘文件的浏览,编辑等功能。能够以文本文件,二进制文件方式打开文件;支持剪贴板功能;支持搜索,查找,替换功能;功能参考了磁盘文件工具程序UltraEdit 。
程序说明:
功能要求分析:
1. 文件读取功能:
即利用目标系统能通过读取功能,一方面能够显示文件的原来数据形式,另一方面也能够把原来的数据形式通过编码转化为用户很方便识别的十六进制数据,进而为用户方便的了解文件的存储数据。
2. 文件编辑功能:
即利用目标系统能通过编辑功能,把对读取的文件数据进行修改,添加,删除,进而实现对原文件的更新的功能,以方便用户能够对文件的方便的操作。
3文件保存功能:
即利用目标系统能通过保存功能,把对读取的文件数据进行修改和编辑过后的数据在保存回原文件,以实现对原文件的保存
测试结果:
关键程序:
void CHexEditView::OnDraw(CDC* pDC)
{
CRect rc;
GetClientRect(rc);
if(m_text == NULL)
{
pDC->FillRect(rc, &CBrush(RGB(255,255,255)));
return;
}
CDC dc;
dc.CreateCompatibleDC(pDC);
CBitmap bm;
bm.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
dc.SelectObject(bm);
dc.SetBoundsRect(&rc, DCB_DISABLE);
CFont font;
font.CreateFont ( m_LineHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, 0 );
CFont* oldFont = dc.SelectObject ( &font );
CBrush bkBrush(RGB(255,255,255));
dc.FillRect(rc, &bkBrush);
UINT lineCY, lineCX;
UINT dwPos;
char currentchar[20];
UCHAR text[17];
int lineBeginPos;
m_HexStart = m_CharWidth * (14 - m_LeftChar); //计算二进制显示开始位置
m_TextStart = m_HexStart + m_CharWidth * 50; //计算ASCII码显示开始位置
for(UINT i = 0; i < m_PageRows; i++) //按行显示数据
{
lineBeginPos = (m_TopLine+i-1)*16; //计算当前行开始字符相对于总缓冲区的位置
lineCY = i * m_LineHeight; //当前行的Y坐标
sprintf(currentchar, "%08Xh:", lineBeginPos);
dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(RGB(255,255,255));
dc.TextOut (m_CharWidth*(2-m_LeftChar), lineCY, currentchar); //显示地址基值
memcpy(text,&m_text[lineBeginPos],16); //取当前行数据
text[16] = '\0';
for(int l = 0; l < 16; l++)
{
if(text[l] < 32)
text[l] = 46; //不可见ASCII字符用.表示
}
if(lineBeginPos+16 > m_CharCount)
{
text[m_CharCount%16] = '\0'; //最后的数据不满一行时
}
dc.TextOut (m_TextStart, lineCY, text);//显示右面的ASCII字符
//被选中时反色显示右面的ASCII字符
int selStart = (m_SelStart - lineBeginPos)<0? 0:(m_SelStart - lineBeginPos);
int selEnd = (m_SelEnd - lineBeginPos)>15? 15:(m_SelEnd - lineBeginPos);
if(selStart <= 15 && selEnd >= 0)
{
dc.SetBkColor(::GetSysColor ( COLOR_HIGHLIGHT ));
dc.SetTextColor(::GetSysColor ( COLOR_HIGHLIGHTTEXT ));
text[selEnd+1]='\0';
dc.TextOut (m_TextStart+selStart*m_CharWidth, lineCY, &text[selStart]);
}
else
{
dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(RGB(255,255,255));
}
for(UINT j = 0; j < 16; j++)
{
dwPos = j + lineBeginPos;
if(dwPos > (m_CharCount-1))
goto bitblt; //显示完最后一行退出
if(dwPos >= m_SelStart && dwPos <= m_SelEnd)
{
dc.SetBkColor(::GetSysColor ( COLOR_HIGHLIGHT ));
dc.SetTextColor(::GetSysColor ( COLOR_HIGHLIGHTTEXT ));
}
else
{
dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(RGB(255,255,255));
}
lineCX = m_HexStart + j * m_CharWidth *3 ; //计算当前要显示的二进制字符的位置
sprintf(currentchar, "%02X", ((UCHAR *)m_text)[dwPos]);
dc.TextOut (lineCX, lineCY, currentchar); //显示二进制字符
if(dwPos == m_SelEnd) //选中单个字符的显示
{
dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(RGB(255,0,0));
UCHAR cHex = m_text[dwPos];
if(m_bFirst)//二进制字符的高四位选中
{
cHex = cHex & 0xf0;
cHex = cHex >> 4;
sprintf(currentchar, "%X", cHex);
dc.TextOut (lineCX, lineCY, currentchar);
}
else
{
lineCX = m_HexStart + j * m_CharWidth *3 + m_CharWidth;
cHex = cHex & 0x0f;
sprintf(currentchar, "%X", cHex);
dc.TextOut (lineCX, lineCY, currentchar);
}
}
}
}
bitblt:
pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &dc, 0, 0, SRCCOPY);
dc.DeleteDC ();}
小结
经过四周的c++软件设计,我能明显感受到我在编程语言的应用上有了显著提高。由于以前接触c++的时候基本是编写一个控制台应用程序,而这一次基本上是必须使用MFC编写。而对此我基本上就是第一次遇到,并且由于大一c++课程结束后就几乎没怎么碰过C++等原因,所以在实验周开始后我除了找出原来教材开始温故知新,我还去图书馆借了《可视化程序设计Visual C++》、《Visual C++程序设计实用案例教程》两本书。
一开始编程有许多不懂的或记得不带清楚的地方, 我就一一 翻书寻找答案解决问题。 随着一个一个困难的解决, 我的第一个程序终于可以完成题目所要求的功能。此外,咨询老师和其他同学也是十分必须的。来自于别人的帮助也十分重要,有时候别人的点拨和指导会让你茅塞顿开,帮助我们更准确的理解题意,比如动态链接库,那个开始根本让我摸不着头脑,经过别人的指导,就知道怎么入手了。
对于编程,我个人觉得,修改和程序的调试需要有细心和耐心。细心可以让我们发现微小的错误,耐心帮我们很好的解决这些错误。面对几百行代码,不断的设置断点,不断的调试,实在是一件很繁琐的事情。也许程序员的辛苦也在此处。但是,每当一个程序调试成功,都是那么地让人振奋人心。辛苦编写代码,修改,程序调试成功,一系列流程中都伴随着烦躁和耐心的较量。
在这四周的软件设计中我体会到失败的无耐,同时也体会到了成功的喜悦。 总的来说,这次程序设计使我受益匪浅,对程序设计有了进一步的认识,同时也认识到了自己的不足,今后我会更加努力学习程序设计为以后工作增添筹码。
编号字号软件课程设计报告班级姓名学号指导老师中国矿业大学计算机科学与技术学院年月1软件课程设计任务书专业年级计算机科学与技术计科1…
华中科技大学电子科学与技术系课程设计报告(20--xx年度第学期)名称:软件课程设计题目:院系:班级:学号:学生姓名:指导教师:设…
软件工程课程设计报告海天一色网上书店软件工程课程设计个人报告题目网上书店学院名称信息科学与工程学院专业班级计算机092班报告人姓名…
软件课程设计实验报告个人报告课班成员学一需求分析1引言32预期功能33设计目标4二界面方案设计说明1拟选用的开发平台和工具介绍42…
软件开发课程设计报告题目职工信息管理系统设计院系专业班级学生姓名学号指导教师2013年9月2日至2013年9月15华中科技大学武昌…
河海大学计算机及信息工程学院常州MFC课程设计报告题目聊天室程序设计学号20xx2325专业计算机科学与技术授课班号243002学…
计算机程序设计VC课程设计指导书江苏科技大学南徐学院20xx年2月一课程设计教学目的和任务计算机程序设计VC课程设计是实践性教学环…
VC程序设计课程设计报告书题目绘图软件设计班级学号姓名指导教师周期成绩一课程设计的目的与要求一课程设计目的与任务目的根据自身对vi…
VC课程设计报告一设计时间20xx年12月27日12月31日二设计地点三设计目的VC程序设计是计算机科学与技术专业的必修专业基础课…
班级学号姓名课程设计报告文档题目俄罗斯方块游戏一引言1编写目的通过本课程设计使学生巩固面向对象程序设计的基本概念原理和技术学会使用…
计算机科学与工程学院项目报告设计名称Windows程序设计综合项目设计题目学生学号专业班级学生姓名xxxxxxxx学生成绩指导教师…