石家庄经济学院
实 验 报 告
课程名称: MFC Windows 应用程序设计 学 院: 信息工程学院 专 业: 计算机科学与技术 学 号 姓 名: 王 龙
实验一 用C语言实现简单的Windows应用程序
1.实验目的与要求
1)熟悉在VC++6.0开发环境,掌握Win32 Application工程创建、程序编写、编译、连接、运行、调试方法;
2)掌握VC++帮助文档-MSDN的使用方法;
3)掌握Windows应用程序结构; 使用C语言及Windows API 函数实现简单Windows应用程序的编写。
2.实验内容
1)熟悉VC++6.0开发环境的使用和MSDN的使用;
2)参照教材例子1-1,使用C语言及Windows API 函数编写简单的Windows应用程序。窗口名称为“我的窗口”,窗口背景颜色设为灰色,按下鼠标左键盘时,使用API函数 MessageBox 显示“鼠标左键按下!”(MessageBox的使用参看MSDN)。
3.程序源代码
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance HINSTANCE PrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
HWND hwnd;
MSG msg;
char lpszClassName[]="窗口";
WNDCLASS wc;
wc.style=0;
wc.lpfnWndProc=WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName=lpszClassName;
RegisterClass(&wc);
hwnd=CreateWindow(lpszClassName,
"我的窗口",
WS_OVERLAPPEDWINDOW,
120,50,800,600,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch(message)
{
case WM_LBUTTONDOWN:
{
MessageBox(NULL,"您已经按下了鼠标左键!","警告",MB_YESNOCANCEL|MB_ICONQUESTION);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
4.实验总结(实验中遇到的问题及解决方法;本次实验学到的知识及体会)
经过本次实验,我对windows程序设计有了更深的了解,对早期的windows程序结构有了初步认识,懂得了API函数的调用方法,最终掌握了程序创建的方法。
第二篇:VC++实验报告
面向对象课程设计
题目:通讯录
学 院: 数学科学与计算技术学院
班 级:
姓 名:
指导教师:
20##年12月
一:设计题目
题目要求:用Visual C++ 2005以上版本,创建一个MFC应用程序,来管理通讯录数据库,实现数据的浏览,更新,添加和删除。下图为案例运行的主界面,可以通过单击工具条上箭头形状的按钮来移动当前记录,通过单击相应的按钮来实现记录的修改、删除和添加操作。
1、 课程设计的目的
VC++是计算机相关专业的重要程序语言课程。开设本实验课程可以进一步巩固理论课上所学到的知识,深刻把握面向对象编程技术的特性,锻炼学生熟练的应用面向对象的思想和设计方法解决实际问题的能力,深化对VC++语言编程和开发工具运用的认识,提高软件项目开发实践能力和软件工程管理能力。
2、 课程设计的要求和主要设计思想
用Visual studio2010,创建一个MFC应用程序,来管理通讯录数据库,实现数据的浏览,更新,添加和删除。
要求能够通过单击工具条是哪个箭头状的按钮来移动当前记录,通过单击相应按钮实现记录的删除修改和添加
主要是使用MFC设计程序,用access数据库存储相应的数据,利用ODBC连接数据源的方法连接数据库。
二、总体方案设计
2.1需求分析
通讯录使我们每个人必不可少的一个工具,利用通讯录我们可以对同学、朋友、同事等信息进行有效的管理,包括查询、添加、删除和修改等。
此通讯录系统利用本着人性化的设计,此系统包括了联系人的姓名、电话、地址、E-mail、和备注等信息,利用此系统可以对联系人进行查询、增加、修改、删除等操作,基本上可以满足我们对通讯录的需要。
基于MFC简易通讯录管理系统具有以下特点:1,操作简单,所有人不需学习就可以使用的系统;2,输入简单,输入框都有相关提示,我们可以按照提示输入相关信息;3,界面显示信息完整,界面上每一个编辑框显示一条联系人信息,很清楚地显示了联系人的全部信息。数据库的操作与运行相比文件较复杂,一般对安全性较高的大型信息管理系统采用数据库方式,这里我们采用文件存取方式即可。
2.2 整体框图
2.3 模块功能
(1) 增加记录:可以增加通讯录相关信息;
(2) 修改记录:可以修改通讯录相关信息;
(3) 浏览记录:可以查找通讯录中每个人的信息;
(4) 删除记录:可以删除通讯录单条个人信息;
三、详细设计
3.1程序设计思想
在MFC中进行数据库编程需要设计4个基本的数据库类:Cdatabase,Crecored,CrecordView和CDBException.
一个Cdatabase对象代表与数据库的一个连接。创建一个Cdatabase对象后,即调用Open或OpenEx成员函数打开指定的数据源,从而建立与底层数据源的连接,应用程序可以通过ExecuteSQL函数项数据源发出一条不需要返回数据的语句。Cdatabase对象在 使用完毕后通过Close函数关闭与数据源的连接。
一个Crecored对象代表从一个数据源检索出一组记录。Crecored支持多种类型的记录集,常用的是动态集类型dynaset和快照类型snapshot.动态集类型是数据库的动态集合,它支持双向滚动,能够与数据源的其他用户做出更新保持同步;快照类型是记录集被填充的数据的静态映像,它也支持双向滚动,但不能保证与其他用户保持同步。
构造Crecoredset对象时需要一个Cdatabase对象。通过Crecord
set的Open函数能够打开数据集并且执行默认的查询语句从数据源中获取数据,函数Close则用了关闭数据集,切断数据集和数据源的连接。在数据集中移动当前记录可以通过函数MoveFirst、MoveLast、和Edit状态,然后对数据集的变量进行赋值,最后通过Update函数完成写入操作。删除操作则通过Delete 函数完成的。
在执行数据库操作的时候可能会引发CDBException类型的异常。CDBException由异常类Cexception派生而来,成员m_strError指明了造成异常的原因,RecordError函数则能够直接弹出一个对话框说明造成异常的原因。
CrecordView用对话框控件来显示数据库记录,可以把它看作是具有数据操作功能的视图类,它能够想对话框一样在设计阶段就编好资源。
3.2设计步骤
第一步:建立access数据库
第二步:将此数据库添加到数据源上
控制面板->管理工具->数据源
点击确定完成添加。
第三步:前台设计
运用VS2010制作MFC前台应用程序,打开VS2010,新建项目,选择MFC应用程序,输入项目名tsu,点击确定,在向导中选择单个文档,在数据库支持中选择提供文件支持的数据库视图,ODBC,在弹出的对话框里选择机器数据源选择上面建立的access数据源单击确定,再在高级功能中取消 ActiveX 控件选项和打印和打印预览选项框架即建立完成。
第四步:打开对话框编辑器编制对话框ID_tsu_FORM如下表所示:
对话框ID_tsu__FORM的设计
设置如下图所示:
为对话框中的各个控件添加消息处理函数。
第五步:
打开类向导窗口,在类名下拉列表中选择CtsuView选项,在对象ID列表框中选择ID_RECORD_FIRST选项然后再消息列表中选择COMMAND选项,单击添加处理程序,添加响应函数OnRecordFirst
用同样的方法分别为ID_RECORD_FLAST,ID_RECORD_NEXT,ID_RECORD_PREV添加事件处理函数OnRecordLast,OnRecordNext,OnRecordPrev;
第六步:程序代码编写
CtsuSet类的接口定义,定义有积累Crecordset派生的CtsuSet类:
class CtsuSet : public CRecordset
{
public:
CtsuSet(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CtsuSet)
long m_ID;
CStringW column1;
CStringW column2;
CStringW column3;
CStringW column4;
// 重写
// 向导生成的虚函数重写
public:
virtual CString GetDefaultConnect(); // 默认连接字符串
virtual CString GetDefaultSQL(); // 记录集的默认 SQL
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX 支持
// 实现
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
};
源文件CtsuSet.cpp。实现CtsuSet类的功能,初始化成员变量和数据库默认连接
CtsuSet::CtsuSet(CDatabase* pdb)
: CRecordset(pdb)
{
m_ID = 0;
column1 = L"";
column2 = L"";
column3 = L"";
column4 = L"";
m_nFields = 5;
m_nDefaultType = dynaset;
}
//数据库的默认连接
CString CtsuSet::GetDefaultConnect()
{
return _T("DSN=AddressBook");
}
//数据库的默认查询
CString CtsuSet::GetDefaultSQL()
{
return _T("[通讯录]");
}
//数据库表格内容与成员变量的数据教皇
void CtsuSet::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
// RFX_Text() 和 RFX_Int() 这类宏依赖的是
// 成员变量的类型,而不是数据库字段的类型。
// ODBC 尝试自动将列值转换为所请求的类型
RFX_Long(pFX, _T("[通讯录ID]"), m_ID);
RFX_Text(pFX, _T("[姓名]"), column1);
RFX_Text(pFX, _T("[分类]"), column2);
RFX_Text(pFX, _T("[电子邮件地址]"), column3);
RFX_Text(pFX, _T("[联系方式]"), column4);
}
/////////////////////////////////////////////////////////////////////////////
定义CtsuView类,在CTXLView.h头文件中定义CtsuView类的接口,定义由基类CrecordView派生的类CtsuView
class CtsuView : public CRecordView
{
protected: // 仅从序列化创建
CtsuView();
DECLARE_DYNCREATE(CtsuView)
public:
enum{ IDD = IDD_TSU_FORM };
CtsuSet* m_pSet;
// 特性
public:
CtsuDoc* GetDocument() const;
// 操作
public:
// 重写
public:
virtual CRecordset* OnGetRecordset();
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
virtual void OnInitialUpdate(); // 构造后第一次调用
// 实现
public:
virtual ~CtsuView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// 生成的消息映射函数
protected:
afx_msg void OnFilePrintPreview();
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnButtonModify();
afx_msg void OnButtonDelete();
afx_msg void OnButtonAdd();
CString m_name;
CString m_type;
CString m_mail;
CString m_address;
afx_msg void OnRecordFirst();
afx_msg void OnRecordLast();
afx_msg void OnRecordNext();
afx_msg void OnRecordPrev();
protected:
void RefreshData(void);
};
#ifndef _DEBUG // tsuView.cpp 中的调试版本
inline CtsuDoc* CtsuView::GetDocument() const
{ return reinterpret_cast<CtsuDoc*>(m_pDocument); }
#endif
源文件CtsuView.cpp,实现类CtsuView视图显示功能:
消息映射:
IMPLEMENT_DYNCREATE(CtsuView, CRecordView)
BEGIN_MESSAGE_MAP(CtsuView, CRecordView)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_BN_CLICKED(IDC_BUTTON_MODIFY, &CtsuView::OnButtonModify)
ON_BN_CLICKED(IDC_BUTTON_DELETE, &CtsuView::OnButtonDelete)
ON_BN_CLICKED(IDC_BUTTON_ADD, &CtsuView::OnButtonAdd)
ON_COMMAND(ID_RECORD_FIRST, &CtsuView::OnRecordFirst)
ON_COMMAND(ID_RECORD_LAST, &CtsuView::OnRecordLast)
ON_COMMAND(ID_RECORD_NEXT, &CtsuView::OnRecordNext)
ON_COMMAND(ID_RECORD_PREV, &CtsuView::OnRecordPrev)
END_MESSAGE_MAP()
// CtsuView 构造/析构
CtsuView::CtsuView()
: CRecordView(CtsuView::IDD)
, m_name(_T(""))
, m_type(_T(""))
, m_mail(_T(""))
, m_address(_T(""))
{
m_pSet = NULL;
// TODO: 在此处添加构造代码
}
实现控件和成员变量的数据交换
void CtsuView::DoDataExchange(CDataExchange* pDX)
{
CRecordView::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_NAME, m_name);
DDX_Text(pDX, IDC_EDIT_TYPE, m_type);
DDX_Text(pDX, IDC_EDIT_MAIL, m_mail);
DDX_Text(pDX, IDC_EDIT_ADDRESS, m_address);
}
设定显示风格:
BOOL CtsuView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CRecordView::PreCreateWindow(cs);
}
初始化视图的显示
vvoid CtsuView::OnInitialUpdate()
{
m_pSet = &GetDocument()->m_tsuSet;
CRecordView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
try
{
m_pSet=new CtsuSet();
m_pSet->Open();
RefreshData();
}
catch(CDBException *pe)
{
AfxMessageBox(pe->m_strError);
pe->Delete();
}
}
CtsuView的数据库支持和消息处理:
1) 获得数据
CRecordset* CtsuView::OnGetRecordset()
{
return m_pSet;
}
2) 显示第一条记录
void CtsuView::OnRecordFirst()
{
// TODO: 在此添加命令处理程序代码
m_pSet->MoveFirst();
RefreshData();
}
3) 显示最后一条记录
void CtsuView::OnRecordLast()
{
// TODO: 在此添加命令处理程序代码
m_pSet->MoveLast();
RefreshData();
}
4) 显示下一条记录
void CtsuView::OnRecordNext()
{
// TODO: 在此添加命令处理程序代码
m_pSet->MoveNext();
RefreshData();
}
5) 显示上一条记录
void CtsuView::OnRecordPrev()
{
// TODO: 在此添加命令处理程序代码
m_pSet->MovePrev();
RefreshData();
}
6) 单击“修改记录”按钮的响应函数
void CtsuView::OnButtonModify()
{
// TODO: 在此添加控件通知处理程序代码
try
{
m_pSet->Edit();;
UpdateData(TRUE);
m_pSet->column1=m_name;
m_pSet->column2=m_type;
m_pSet->column3=m_address;
m_pSet->column4=m_mail;
m_pSet->Update();
}
catch(CDBException* pe)
{
AfxMessageBox(pe->m_strError);
pe->Delete();
}
}
void CtsuView::OnButtonDelete()
{
// TODO: 在此添加控件通知处理程序代码
try
{
m_pSet->Delete();
m_pSet->Requery();
RefreshData();
}
catch(CDBException* pe)
{
AfxMessageBox(pe->m_strError);
pe->Delete();
}
}
7) 单击“删除记录”按钮的响应函数
void CtsuView::OnButtonDelete()
{
// TODO: 在此添加控件通知处理程序代码
try
{
m_pSet->Delete();
m_pSet->Requery();
RefreshData();
}
catch(CDBException* pe)
{
AfxMessageBox(pe->m_strError);
pe->Delete();
}
}
8) 单击“添加记录”按钮的响应函数
void CtsuView::OnButtonAdd()
{
// TODO: 在此添加控件通知处理程序代码
try
{
m_pSet->AddNew();
UpdateData(TRUE);
m_pSet->column1=m_name;
m_pSet->column2=m_type;
m_pSet->column3=m_address;
m_pSet->column4=m_mail;
m_pSet->Update();
m_pSet->Requery();
}
catch(CDBException* pe)
{
AfxMessageBox(pe->m_strError);
pe->Delete();
}
}
9) 用数据集的当前内应更新视图
void CtsuView::RefreshData(void)
{
m_name=m_pSet->column1;
m_type=m_pSet->column2;
m_address=m_pSet->column3;
m_mail=m_pSet->column4;
UpdateData(false);
}
四 程序的调试与运行结果说明
运行结果如下图:
而用Visual C++6.0编译的结果如下图
由图可以清楚知道,两者界面存在很大差别。
五 课程设计总结
本程序基本完成了报告上要求的浏览、添加、修改、删除这些要求。通过自己的不断练习,自己逐渐学会一些基本控件的使用,掌握了ODBC连接数据库的方法。由于教程上所用的开发工具是vc6.0,而自己用的是vs2010,有一些函数在vs2010不能使用,通过自己网上搜索和请教同学,找到了相应的函数,并实现了所需的功能。
六 实验过程中遇到的问题
1、按照教程上的方法在运行时出现数据库连接失败,经过自己的调试和修改,发现是连接代码出现错误,针对不同的access版本,连接代码不同。得到了自己想要的结果。、
2、在编辑对话框时由于一些函数不会添加,我请教了和我做同一个设计的同学,最终完成