产品故障信息管理系统
内容摘要
本文介绍了如何使用Visual C++ 6.0编程制作彩色电视机故障信息共享系统, 实现信息管理共享的自动化。由此实现了信息的增加、删除、修改、查看等功能,并且进而实现信息的安全管理,使信息的管理更加人性化,规范化。从而提高故障排除效率,提高信息利用率,有助于进一步提高生产效率。
关键词: 信息管理 信息共享 故障 数据库
Abstract
The main work of this paper is introduce how to use Visual C++6.0 programming a Color TV Malfunction-Information In-Common System, achieve the auto-manage of the Malfunction-Information. According these, this system achieves the information’s function of add,delete ,edit and view, it also get the information managed safety, so the management of the information will be more humanity & normalize. Thereby, it can improve the efficiency of the m alfunction’s elimination, enhance the exploitation of the information, and also help improving the efficiency of the produce by a large step.
Key words: Information management Information shares ADO
目 录
前 言 .................................................................................................................................. 1
1. 系统设计 .......................................................................................................................... 2
1.1目标设计 ................................................................................................................ 2
1.2开发设计思想 ........................................................................................................ 2
1.3功能分析 ................................................................................................................ 2
1.4功能模块设计 ........................................................................................................ 2
2. 数字库设计 ...................................................................................................................... 3
2.1数据库需求分析 .................................................................................................... 3
2.2数据库概念结构设计 ............................................................................................ 4
3. 创建应用程序 .................................................................................................................. 4
4. 数据库操作准备 .............................................................................................................. 5
5. 功能模块的创建 .............................................................................................................. 7
5.1系统主体窗体的创建 ............................................................................................ 7
5.1.1主菜单的创建 ............................................................................................. 7
5.1.2右键菜单的创建 ......................................................................................... 8
5.1.3工具栏的创建 ............................................................................................. 9
5.1.4数据显示与表格控件的创建 ..................................................................... 9
5.2系统用户权限管理模块的创建 .......................................................................... 11
5.2.1添加用户对话框的创建 ........................................................................... 12
5.2.2更改密码对话框的创建 ........................................................................... 14
5.2.3删除用户对话框的创建 ........................................................................... 16
5.2.4用户登录对话框的创建 ........................................................................... 17
5.3信息管理模块的创建 .......................................................................................... 18
5.3.1添加记录对话框的创建 ........................................................................... 18
5.3.2查询记录对话框的创建 ........................................................................... 20
5.3.3修改记录对话框的创建 ........................................................................... 22
5.3.4查看记录对话框的创建 ........................................................................... 22
5.4打印预览模块的创建 .......................................................................................... 22
7. 接口网络编程原理 ........................................................................................................ 26
8. Windows Sockets编程原理 ........................................................................................ 29
8.1异步选择机制 ...................................................................................................... 29
8.2异步请求函数 ...................................................................................................... 29
8.3阻塞处理方法 ...................................................................................................... 29
8.4错误处理 .............................................................................................................. 29
8.5启动和终止 .......................................................................................................... 29
9. 实现远程数据的管理 .................................................................................................... 30
9.1 设计基本思路: ................................................................................................... 30
9.2 具体实现(为了数据传送的可靠性,采用基于TCP 的流式套接字): ......... 30
10. 程序的编译和系统的实现 .......................................................................................... 31
11. 结论 .............................................................................................................................. 31
12. 致谢 .............................................................................................. 错误!未定义书签。 参 考 文 献 ...................................................................................... 错误!未定义书签。
前 言
Visual C++是Microsoft 公司开发的基于Windows 操作系统的编程工具,它采用一种巧妙的方法将Windows 的编程复杂性封装起来,编程者可以比较轻松地进行Windows 应用程序的设计。Visual C++ 6.0继承了以前版本的优点,为用户提供了更为友好的可视化开发环境,是当今程序员首选的开发工具。它在编程的深入性、运行的快速性等方面具有很强的功能。
随着社会的飞速发展,信息管理系统已广泛地运用于各行各业。信息在企业生产经营中扮演着越来越重要的角色。企业内部和外部之间的信息变得越来越频繁,方式越来越复杂,信息量日益增大,速度越来越快,丝毫不亚于企业的物质、能量交流,信息流在企业系统中所占份额逐渐上升。这样一来,企业信息管理才应运而生,成为企业管理的重要组成部分。企业信息管理的产生是企业管理发展到一定阶段的必然产物,是企业管理发展史上的划时代的进步。
故障信息管理,一般是指设备或系统在使用中丧失或降低其规定的功能。故障管理,其目的是保证设备经常处于完好状态,严格控制设备的故障发生,降低故障率,减少维修费用,延长设备的使用寿命。
而信息化建设对企业来说无疑已经成为企业在现代竞争社会中立足的重要因素。而从中国大陆企业现状来看,大部分企业的信息化建设都是依靠专业化软件公司。毋庸置疑,对于大规模的管理系统,例如CRM (Client Relation Manager),ERP
(Enterprise Resource Plan)等,使用专业软件公司开发的产品,功能相对齐全,安全级别也相对较高。但对于企业内部小范围内所需的一些小系统而言,如也依靠此种方式,势必会产生无谓的成本流失。鉴于这种形式,借助这次毕业设计的机会,在指导老师的帮助下,经过一段时间的努力,开发出了这套彩电共享系统。本系统主要用于对已有故障信息进行更高效的管理,提高信息的利用率,改变了以往烦琐的查找,大大提高了故障的排除速度及正确率,对进一步提高生产效率具有十分重要的意义。 下面我们将按照软件工程学思想,对整个系统制作过程做个一般性阐述。
1. 系统设计
1.1目标设计
通过一个彩电故障信息共享系统,使生产工程部的故障处理工作系统化,规范化,自动化,从而达到提高故障排除效率,提高信息利用率的目的。
1.2开发设计思想
● 尽量采用生产工程部现有的软硬件环境及齐全的故障信息,从而达到充分利用现有资源,提高系统开发水平和应用效果的目的。
● 系统应符合生产工程部资料管理规范,符合普通员工操作的规范,达到操作过程中的直观、方便、实用、安全等要求。
● 系统采用Visual C++环境,用ADO (ActiveX Data Objects)数据访问方式,采用Microsoft Access 2000作为数据源,使整个系统易于使用及维护。
● 系统采用模块化程序设计方法,既便于系统功能的各种组合和修改,又便于未参与开发的技术维护人员补充、维护。
● 系统应具备数据维护功能,及时根据数据变化进行添加、删除、修改、查询等操作,并加入拥护权限功能,使系统更加安全
1.3功能分析
本系统功能分析是在系统开发总体任务的基础上完成的,本系统需要完成的功能如下:
●
●
● 故障信息的输入、查询、修改、删除 故障信息的打印 系统用户管理,权限管理
1.4功能模块设计
在系统功能分析的基础上,考虑Visual C++程序编制的特点,得到图1所示的系统功能模块图。
图1
系统功能模块图 图2 数据流程图 2. 数字库设计 数据结构的好坏将直接影响到系统的效率以及实现的效果。好的数据库结构会减少数据库的存储量、冗余度,数据的完整性和一致性比较高,系统具有较快的响应速度,简化基于数据库的应用程序的实现方法等。 2.1数据库需求分析 在仔细研究资料管理过程的基础上,归纳出系统的数据流程图如上图2所示,所有数据均由管理员输入管理。 根据图2的数据流程图,可得到所须设计的数据项和数据结构如下: ● 故障信息,包括的数据项有显象管、机芯、机壳、器件、技术员、时间、其他、信息名、具体内容等。 ● 权限验证,包括的数据项有用户名、密码等。 据表均用Access 2000实现。Access 中的设计视图如图3、图4所示,其中数据类型根据具体的数据字段来设置。 由上分析,为此需要有2个数据表分别用来存放故障信息的用户信息。这两个数 图3 info1视图
图4 login视图
2.2数据库概念结构设计
在分析需求的基础上,我们得到整个系统的E-R 图如图5所示。
3. 创建应用程序
本彩电故障信息共享系统采用Visual C++ 6.0的ADO 方法开发。工程创建具体步骤如下:
打开Visual C++后,选择菜单“File/New”中的“Project ”选项卡中的“MFC AppWizard [exe]”,设置工程名字为“CaidianGuzhang ”,选择存储位置,单击“OK ”。
创建一个单文档应用程序,在Step1中,选择“Single Document”,然后单击“Next ”按扭,进入“Step 2 of 6”。
一直单击“Next ”按扭,直到进入“Step 6 of 6”。因为为了能使数据更直观,我们采用列表形式,所以需要在本步骤中,选择CCaidianGuzhangView 类的Base Class (基类)为ClistView 。然后单击“Finish ”,最后将出现确认窗口,如图6所示,检查无误后,单击“确定”,即可完成工程创建。
图6 确认
为了使程序能支持ADO 数据库对象,应该在头文件stdafx.h(预编译头文件) 中加入 #import "c:\Program Files\Common Files\System\ado\msado15.dll"\
rename_namespace("AdoNS")\
rename("EOF","adoEOF")
using namespace AdoNS; 导入ADO 库
并在主程序入口:BOOL CCaidianGuzhangApp::InitInstance()中加入
AfxOleInit();初始化COM 环境。
ADO (ActiveX Data Objects)是Microsoft 开发数据库应用程序的面向对象的新接口,描述了软件中存取多种数据源的统一接口,并提供了实现ADO 模型的COM 组件,使得不同程序设计语言均可使用ADO 。在NET Framework的System.Data 命名空间中定义这些类-这些类表示到数据库的连接、数据库中的表,和表中所包含的数据类型。更广义地讲,ADO . NET 就是Microsoft 最新的数据访问策略。其主要的优点是灵活,易于使用、速度快、内存支出少和磁盘遗迹小,简化了操作。
ADO 类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C ++使用的COM vtable接口。当使用#import 指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C ++头文件。
ADO 库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。 _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL 语句,如一个存储过程。
_CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL 语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。
_RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。
4. 数据库操作准备
由于本系统使用的是ADO 方式访问数据库,因此可以使用从视表到记录集的映射。为了编程便捷,可以为数据库中的每个表映射一个记录集类(从CDaoRecordSet 类继承)。映射关系如下表1所示。
CDaoRecordSet 封装了ADO 记录集对象,用于管理一个来自表定义(基础表)或查询定义的记录集合。CDaoRecordSet 对象有三种使用的原型,分别为table-type (基于单个数据表)、dynaset-type (基于组合查询)、snapshot-type (基于组合查询的静态拷贝)。对记录集的映射有两种方法:第一种是直接从CDaoRecordSet 类创建记录集,并且动态绑定记录字段;第二种是使用ClassWizard
创建CDaoRecordSet 类的派生类,并利用DFX 机制记录数据与记录集字段数据成员之间的映射。在本系统中,我首先使用第二种方法,方法是在ClassWizard 中单击“New Class ”,进入下一窗口,设置类名为“CDataSet ”,选择Base Class (基类)为CDaoRecordSet ,然后单击“OK ”,进入“Database Option”窗口,选中“ADO ”,按浏览按钮后,选择需要映射的文件(此处为info1.mdb ),具体过程如图7所示。最后在弹
图7 选择ADO 数据库文件
出的Select Database Table(数据表选择对话框)中选中要映射的表名(在此为info1)。单击“OK ”即可。同样的方法,建立类“CloginSet ”,映射的表名为login 。
但是此种方法把数据库访问路径给固定了,我们可以从以下Visual C++自行建立的函数看出。
CString CDataSet::GetDefaultDBName() { }
return _T("D:\\visual\\MSDev98\\MyProjects\\xiahua\\info1.mdb");
为了能使系统在各个环境下都可正常运行,需要修改此函数,使数据库实现动态链接,修改后的函数程序如下:
CString CDataSet::GetDefaultDBName() { }
char path[50];
CString m_strDatabaseName;
::GetCurrentDirectory(50,path); //得到当前应用程序所在的路径 strcat(path,"\\");
m_strDatabaseName=_T(path);
m_strDatabaseName+="info1.mdb"; //将所对应文件改成所要的数据库名 return m_strDatabaseName; //返回数据库所在的完整路径
同样的,我们也必须修改CLoginSet::GetDefaultDBName()函数。因为其内部程序与CDataSet::GetDefaultDBName()相同,所以我们就不再此列出。
5. 功能模块的创建
在链接了数据库后,接下来我们就可以开始进行各功能模块的创建。
5.1系统主体窗体的创建
在我们按照VC++的AppWizard 创建完工程后,为了使主窗口框架更适合整个系统的操作,我们有必要进行修改,重新创建。
5.1.1主菜单的创建
在WorkSpase 中选择ResourseView ,然后双击Menu 文件夹,再双击IDR_MAINFRAME选项,单击右边窗口中“帮助”旁边的虚线框,在双击或按回车键,就会出现“Menu Item Properties”对话框,在这个对话框中输入菜单项的内容,如图8所示。
图8设置一级菜单
二级菜单的设置基本上都和图8相同,只是必须设置ID 。按照这种方法,最终创建出如表2所示的菜单结构。
表2 菜单结构
为了实现操作的方便、快捷,我们在程序中加入了右键菜单。在VC 的主菜单中,按“Project ”—>“New Project ”—>“Components and Controls Gallery ”即可进入“Components and Controls Gallery”对话框,然后再打开Visual C++ Components文件,再选择“Pop-up Menu”,单击“insert ”,随后在跳出的对话框中选择“CxiahuaView ”,最后单击“OK ”。完成后,需要对其进行编辑。单击WorkSpase 中的ResourseView ,在Menu 文件夹中选择CG_IDR_POPUP_MAIN_FRAME,之后边可在右边窗口对其进行编辑。编辑方法与主菜单相同,其中各项的ID 分别对应相应的菜单项,对应关系如表3所示。
表3 右键菜单对应的菜单项ID
5.1.3工具栏的创建
在WorkSpase 中选择ResourseView ,然后双击Toolbar 文件夹,再双击IDR_MAINFRAM选项,就可以利用工具条编辑器(Toolbar Editor)编辑右边的工具条。本系统创建的工具条如图9所示。其中各按钮的ID 分别对应相应的菜单项,按从做到右的顺序对应的菜单项ID 如表4所示。
表4工具条对应的菜单项ID
(注:其中第5个是显示全部数据,实现刷新功能,在菜单中没有)
5.1.4数据显示与表格控件的创建
因为CxiahuaView 是从ClistView 继承的,所以创建完工程后,就已经有表格控件存在。而我们目的就是使控件上的显示更符合系统的使用,所以我们有必要对初试界面也就是对CXiahuaView::OnInitialUpdate()函数进行修改,修改后的函数如下:
void CXiahuaView::OnInitialUpdate() {
CListView::OnInitialUpdate();
// TODO: You may populate your ListView with items by directly accessing CListCtrl &ctl=GetListCtrl();
ctl.ModifyStyle(0,LVS_REPORT|LVS_SINGLESEL);
ctl.SetExtendedStyle(LVS_EX_FLATSB|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLIN
ES);//设置窗体类型
//初始化m_pSet指针,m_pSet原型为CDataSet* m_pSet
m_pSet=&GetDocument()->m_dataSet;
//初始化m_pLset指针,m_pLset原型为CLoginSet* m_pLset
m_pLset=&GetDocument()->m_dataLset;
if(m_pSet->IsOpen())
m_pSet->Close();
m_pSet->Open(); //打开数据库
GetDocument()->SetTitle("彩电故障信息共享系统"); //设置标题
CString str;
//以下是设置控件按钮显示字符 str.LoadString(IDS_SERIAL); ctl.InsertColumn(0,str); ctl.InsertColumn(1,"显象管");
ctl.InsertColumn(2,"机芯"); }
ctl.InsertColumn(3,"机壳"); ctl.InsertColumn(4,"器件"); ctl.InsertColumn(5,"技术员"); ctl.InsertColumn(6,"时间"); ctl.InsertColumn(7,"其他"); ctl.InsertColumn(8,"信息名"); ctl.InsertColumn(9,"具体内容"); m_bIsAsc=TRUE; m_bIsShowAll=TRUE;
ShowTableData(); //调用显示数据函数,显示数据
接下来就是要编写ShowTableData()函数。程序如下:
void CXiahuaView::ShowTableData() {
CListCtrl &ctl=GetListCtrl();
ctl.DeleteAllItems(); //删除所有已显示内容
m_pSet->MoveFirst(); //将m_pSet指针指向首条记录
int i=0;
int ColWidth[10]={0};
while(!m_pSet->IsEOF()) //如果没有到达数据末尾,则显示数据 {
┇ ┇
}
//设置各数据项的显示宽度 for(int j=0;j
ctl.SetColumnWidth(j,ColWidth[j]+30); }
ctl.SetColumnWidth(8,100); ctl.SetColumnWidth(9,100);
m_pSet->MoveFirst(); //将m_pSet指针再指向首条记录,便于下次操作 }
到此,我们完成了主体框架的制作,主窗口如图9所示。
图9 主窗口
5.2系统用户权限管理模块的创建
为了数据库使用的安全,必须对数据库的各种操作实行权限管理。只有管理员允许的人员才有权力使用。允许的用户和密码都预先存在数据库中,本系统中为
login 表。权限管理模块主要实现如下功能:
● 添加用户 ● 更改密码 ● 删除用户
● 用户登录(权限验证)
5.2.1添加用户对话框的创建
在ResourseView 中,右击Dialog ,选择Insert Dialog,便可在右边窗口中编辑对话框。完成的对话框如图10所示。对话框中各种非静态文本控件的属性见表5。
图10 添加用户对话框 图11密码修改对话框
表5添加用户对话框中各控件的属性设置
对话框编辑完成后,双击该对话框,进入New Class对话框,取此登记对话框的类名为CAddUser 。然后在MFC ClassWizard中选择Class name为CXiahuaView ,Object IDs 为“ID_USER_ADD”,Messages 为“COMMAND ”,单击Add Function按钮,取系统默认的函数名,再单击Edit Code 按钮,即可进入代码编辑器对函数CXiahuaView::OnUserAdd()进行编辑。此函数代码如下:
void CXiahuaView::OnUserAdd() {
// TODO: Add your command handler code here
CLoginSet *m_daorecordset=new CLoginSet(&pDatabase);//初始化连接数据库指针 CString strSQL;
if(adiministrator()==0) //管理员权限验证,失败返回
return;
else //成功进入增加用户窗口 {
CAddUser adduser;//进入增加用户窗口 if(adduser.DoModal()==IDCANCEL)
return;
else
{
m_daorecordset->Close();
strSQL.Format("select * from login where user='%s'",adduser.m_strUser);
m_daorecordset->Open(AFX_DAO_USE_DEFAULT_TYPE,strSQL); if(m_daorecordset->GetRecordCount()!=0)
{
AfxMessageBox(_T(" 对不起!\n"+adduser.m_strUser+"已经存在, 请尝试用其他名
字!"),MB_ICONEXCLAMATION);
┇
} else {
if(adduser.m_strPswd.Compare(adduser.m_strCompswd)!=0) {
AfxMessageBox(_T("两遍新密码输入不一致!\n请重输!"),MB_ICONEXCLAMATION);
}
else
{
┇
}
}
}
} }
5.2.2更改密码对话框的创建
更改密码对话框的创建与添加用户对话框的创建基本相同,完成后的对话框如图11所示。对话框中各种非静态文本控件的属性见表6。
表6 修改密码对话框中各控件的属性设置
同样方法,取此密码对话框的类名为CModPswd 。执行此对话框的函数为CXiahuaView::OnPasswardEdit(),实现密码修改功能的程序代码如下:
void CXiahuaView::OnPasswardEdit() {
// TODO: Add your command handler code here UpdateData(TRUE); COleVariant var; CModPswd modpswd;
if(modpswd.DoModal()==IDCANCEL) else {
return;
CLoginSet *m_daorecordset=new CLoginSet(&pDatabase);
CString strSQL; CString str1;
strSQL.Format("select * from login where user='%s'",modpswd.m_strUser); m_daorecordset->Open(AFX_DAO_USE_DEFAULT_TYPE,strSQL); if(m_daorecordset->GetRecordCount()==0) {
AfxMessageBox(_T("无此用户!\n请向管理员咨询"),MB_ICONEXCLAMATION);
}
m_daorecordset->Close(); OnPasswardEdit();
else
{
m_daorecordset->Close();//先关闭,以便以后再次打开记录集体对象
strSQL.Format("select * from login where user='%s' and passward='%s'", modpswd.
m_strUser,modpswd.m_strFormerps);
m_daorecordset->Open(AFX_DAO_USE_DEFAULT_TYPE,strSQL); if(m_daorecordset->GetRecordCount()==0) {
AfxMessageBox(_T("密码错误!\n请注意大小写"),MB_ICONEXCLAMATION);
} else {
if(modpswd.m_strNewps.Compare(modpswd.m_strConfirps)!=0) {
AfxMessageBox(_T("两遍新密码输入不一致!\n 请重输!"), MB_ICONEX
CLAMA TION);
modpswd.m_strNewps.Empty();
} else {
modpswd.m_strConfirps.Empty(); UpdateData(FALSE);
m_daorecordset->Edit();//使记录集可编辑
m_daorecordset->m_passward=modpswd.m_strNewps;
}
}
} }
}
m_daorecordset->Update();//修改后刷新
AfxMessageBox(_T("密码修改成功!\n请记住新密码!"),MB_ICONEXCLAMATION);
5.2.3删除用户对话框的创建
创建方法同上,完成后的对话框如图12所示。对话框中各种非静态文本控件的属性见表7。取此删除用户对话框的类名为CDelUser 。执行此对话框功能的函数为CXiahuaView::OnUserDel(),代码如下:
表7 删除用户对话框中各控件的属性设置
图12删除用户对话框 图13用户登录对话框 void CXiahuaView::OnUserDel() {
// TODO: Add your command handler code here
CLoginSet *m_daorecordset=new CLoginSet(&pDatabase); CString strSQL; CString user;
user.Format("administrator");
if(adiministrator()==0)//管理员权限验证,失败返回 else
return;
{
CDelUser deluser;//成功。调入删除用户窗口 if(deluser.DoModal()==IDCANCEL)
return; else
{
if(deluser.m_strUser.Compare(user)==0)
{
AfxMessageBox(_T(" 对不起!\n不允许删除管理员"),MB_ICONEXCLAMATION); } else {
CString str1;
str1.Format("%s",deluser.m_strUser);
if(AfxMessageBox("确定要删除"+str1+"吗?",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
} }
strSQL.Format("delete from login where user='%s'",deluser.m_strUser);
pDatabase.Execute(strSQL); }
}
}
5.2.4用户登录对话框的创建
创建方法同上,完成后的对话框如图13所示。对话框中各种非静态文本控件的属性见表8。取此删除用户对话框的类名为CloginDlg 。
表8 修改密码对话框中各控件的属性设置
5.3信息管理模块的创建
故障信息在管理中需要进行各种不同的操作,信息管理模块主要实现如下功能: ● 查看记录 ● 查询记录 ● 添加记录 ● 删除记录 ● 修改记录
5.3.1添加记录对话框的创建
在ResourseView 中,右击Dialog ,选择Insert Dialog,便可在右边窗口中编辑对
话框。完成的对话框如图14所示。对话框中各种非静态文本控件的属性见表9。
表9信息登记对话框中各控件的属性设置
图14 信息登记对话框
对话框编辑完成后,双击该对话框,进入New Class 对话框,取此登记对话框的类名为CInfoDlg 。然后在MFC ClassWizard中选择Class name为CXiahuaView ,Object
IDs 为“ID_RECORD_ADD”,Messages 为“COMMAND ”,单击Add Function按钮,再单击Edit Code按钮,即可编辑执行添加信息功能的函数,程序如下:
void CXiahuaView::OnRecordAdd() {
// TODO: Add your command handler code here if(memberright()==0) //系统用户验证,失败返回 else {
return;
CInfoDlg addDlg; //成功进入增加窗口 if(addDlg.DoModal()==IDOK) {
CString crt; crt=addDlg.m_strCrt;
if(addDlg.m_strInfo.IsEmpty())
{
AfxMessageBox(_T("为保证数据的有效性,\n请确定您已输入有效信息
"),MB_ICONEXCLAMATION);
OnRecordAdd();
addDlg.m_strCrt=crt;
}
else {
addDlg.m_strCrt.TrimLeft(" "); //去除各选项左右无效空格字符 addDlg.m_strCrt.TrimRight(" "); addDlg.m_strCase.TrimLeft(" ");
┇
┇
m_pSet->AddNew(); //增加数据
m_pSet->m_crt=addDlg.m_strCrt; m_pSet->m_info=addDlg.m_strInfo; m_pSet->m_case=addDlg.m_strCase;
m_pSet->m_date=addDlg.m_strDate;
m_pSet->m_device=addDlg.m_strDevice; m_pSet->m_clips=addDlg.m_strClips;
m_pSet->m_content=addDlg.m_strContent;
m_pSet->m_other=addDlg.m_strOther; m_pSet->m_workor=addDlg.m_strWorkor; m_pSet->Update();
Sort(m_bIsAsc);
ShowTableData(); }
}
}
}
5.3.2查询记录对话框的创建
查询记录对话框与添加记录对话框的创建方法相似,只是起省略了具体内容这一项。各控件的属性也与添加记录对话框相同。该对话框的类名为CrecordSearch ,其所对应的实现查询记录功能函数为CXiahuaView::OnRecordSearch(),该函数实现代码如下:
void CXiahuaView::OnRecordSearch() {
// TODO: Add your command handler code here CRecordSearch search; CString str;
if(search.DoModal()==IDCANCEL)return; else {
ASSERT(m_pSet->CanRestart()); search.m_strCrt.MakeLower(); m_bIsShowAll=FALSE; CDaoFieldInfo fieldInfo; if(!search.m_strCrt.IsEmpty()) {
fieldInfo.m_strName="显象管";
m_pSet->m_strFilter=fieldInfo.m_strName+" = "+"'"+search.m_strCrt+"'"; m_pSet->Requery();
}
else if(!search.m_strClips.IsEmpty()) {
fieldInfo.m_strName="机芯";
m_pSet->m_strFilter=fieldInfo.m_strName+" = "+"'"+search.m_strClips+"'";
m_pSet->Requery();
}
else if(!search.m_strCase.IsEmpty()) {
┇ ┇
} else { }
ShowTableData();
AfxMessageBox(_T("请输入显象管型号"),MB_ICONEXCLAMATION); OnRecordSearch();
}
}
5.3.3修改记录对话框的创建
修改记录对话框的创建与增加记录对话框的创建相似,其界面和各控件的属性与添加记录对话框相同,只是其对应的类名为CrecordEdit 。实现修改记录功能函数为CXiahuaView::OnRecordEdit(),以下是其完整代码。
void CXiahuaView::OnRecordEdit() {
// TODO: Add your command handler code here if(memberright()==0) else {
return;
CListCtrl &ctl=GetListCtrl();
POSITION pos=ctl.GetFirstSelectedItemPosition(); if(pos==NULL)
{
A fxMessageBox(_T("没有选中记录"),MB_ICONEXCLAMATION);
}
else
┇
┇
}
}
5.3.4查看记录对话框的创建
此对话框的创建与上大同小异,这里略去。
5.4打印预览模块的创建
在以上实现了各模块后,基本上一完成了对数据的完整操作,为了能更好的实现数据信息在现实中的多方位使用,有必要对系统实现按照生产工程部的资料管理规范的打印功能。实现该打印功能,主要是编辑OnPrint 函数。具体代码如下:
void CXiahuaView::OnPrint(CDC* pDC, CPrintInfo* pInfo) {
// TODO: Add your specialized code here and/or call the base class pDC->SetMapMode(MM_LOENGLISH); CXiahuaDoc* pDoc=GetDocument(); ASSERT_VALID(pDoc);
┇
┇
clrRef=0X00000000;
oPen.CreatePen(PS_SOLID,2,clrRef); pDC->SelectObject(&oPen);
clrRef=0X00C000C0;
oBrush.CreateSolidBrush(clrRef); pDC->SelectObject(&oBrush);
oHeadFont.CreatePointFont(160,"Areal",pDC); pDC->SelectObject(&oHeadFont); pDC->SetBkMode(TRANSPARENT); CListCtrl &ctl=GetListCtrl();
POSITION pos=ctl.GetFirstSelectedItemPosition(); if(pos==NULL) { AfxMessageBox(_T("没有选中记录"),MB_ICONEXCLAMATION); return;
} else {
┇ ┇
} }
6. Windows Sockets规范简介
Windows Sockets规范以U.C. Berkeley大学BSD UNIX中流行的Socket 接口为范例定义了一套Micosoft Windows下网络编程接口。它不仅包含了人们所熟悉的Berkeley Socket风格的库函数;也包含了一组针对Windows 的扩展库函数,以使程序员能充分地利用Windows 消息驱动机制进行编程。
Windows Sockets规范本意在于提供给应用程序开发者一套简单的API ,并让各
家网络软件供应商共同遵守。此外,在一个特定版本Windows 的基础上,Windows Sockets 也定义了一个二进制接口(ABI ),以此来保证应用Windows Sockets API的应用程序能够在任何网络软件供应商的符合Windows Sockets 协议的实现上工作。因此这份规范定义了应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数调用和相关语义。
遵守这套Windows Sockets 规范的网络软件,我们称之为Windows Sockets 兼容
的,而Windows Sockets兼容实现的提供者,我们称之为Windows Sockets提供者。一个网络软件供应商必须百分之百地实现Windows Sockets规范才能做到现Windows Sockets 兼容。
任何能够与Windows Sockets兼容实现协同工作的应用程序就被认为是具有
Windows Sockets接口。我们称这种应用程序为Windows Sockets应用程序。
Windows Sockets 规范定义并记录了如何使用API 与Internet 协议族(IPS ,通
常我们指的是TCP/IP)连接,尤其要指出的是所有的Windows Sockets 实现都支持流套接口和数据报套接口。
应用程序调用Windows Sockets的API 实现相互之间的通讯。Windows Sockets又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。它们之间的关系如图15。
图15 应用程序与Windows Sockets关系图
虽然我们并不反对使用这一套API 来实现另一通讯协议栈(而且我们期望在将来规范的修改中能够讨论这个问题),但这种用法已经超出了我们这一份规范所规定的范围,我们在此将不作讨论。
6.1 Bekeley套接口
Windows Sockets 规范是建立在Bekeley 套接口模型上的。这个模型现在已是TCP/IP网络的标准。它提供了习惯于UNIX 套接口编程的程序员极为熟悉的环境,并且简化了移植现有的基于套接口的应用程序源代码的工作。Windows Sockets API也是和4.3BSD 的要求一致的。
6.2 Microsoft Windows和针对Windows 的扩展
这一套Windows Sockets API能够在所有3.0以上版本的Windows 和所有Windows Scokets 实现上使用,所以它不仅为Windwos Sockets实现和Windows Sockets应用程序提供了16位操作环境,而且也提供了32位操作环境。
Windows Sockets也支持多线程的Windows 进程。一个进程包含了一个或多个同
时执行的线程。在Windows 3.1非多线程版本中,一个任务对应了一个仅具有单个线程的进程。而我们在本书中所提到的线程均是指在多线程Windows 环境中的真正意义的线程。在非多线程环境中(例如Windows 3.0)这个术语是指Windows Sockets 进程。
Windows Sockets规范中的针对Windows 的扩展部分为应用程序开发者提供了开
发具有Windows 应用软件的功能。它有利于使程序员写出更加稳定并且更加高效的程序,也有助于在非占先Windows 版本中使多个应用程序在多任务情况下更好地运作。除了WSAStartup()和WSACleanup()两个函数除外,其他的Windows 扩展函数的使用不是强制性的。
7. 接口网络编程原理
套接口有三种类型:流式套接口、数据报套接口和原始套接口。
流式套接口定义了一种可靠的面向连接的服务,实现了无差错无重复的顺序数据传输。数据报套接口定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错。原始套接口允许对低层协议如IP 或ICMP 直接访问,主要用于新的网络协议实现的测试等。
无连接服务器一般都是面向事务处理的,一个请求一个应答就完成了客户程序与服务程序之间的相互作用。若使用无连接的套接口编程,程序的流程可以用图16表示。
服务器
图16 无连接套接口应用程序时序图
面向连接服务器处理的请求往往比较复杂,不是一来一去的请求应答所能解决
的,而且往往是并发服务器。使用面向连接的套接口编程,可以通过图16来表示:其时序。
服务器
图17面向连接套接口应用程序时序图
套接口工作过程如下:服务器首先启动, 通过调用socket()建立一个套接口,然后
调用bind()将该套接口和本地网络地址联系在一起,再调用listen()使套接口做好侦听的准备,并规定它的请求队列的长度,之后就调用accept()来接收连接。客户在建立套接口后就可调用connect()和服务器建立连接。连接一旦建立, 客户机和服务器之间就可以通过调用read()和write()来发送和接收数据。最后,待数据传送结束后,双方调用close()关闭套接口。
8. Windows Sockets编程原理
由于Windows 的基于消息的特点,WINSOCK 和BSD 套接口相比,有如下一些新的扩充:
8.1异步选择机制
异步选择函数WSAAsyncSelect()允许应用程序提名一个或多个感兴趣的网络事
件, 如FD_READ,FD_WRITE,FD_CONNECT,FD_ACCEPT等等代表的网络事件。当被提名的网络事件发生时,Windows 应用程序的窗口函数将收到一个消息。这样就可以实现事件驱动了。
8.2异步请求函数
异步请求函数允许应用程序用异步方式获得请求的信息,如
WSAAsyncGetXByY()类函数。 这些函数是对BSD 标准函数的扩充。函数WSACancelAsyncRequest()允许用户中止一个正在执行的异步请求。
8.3阻塞处理方法
WINSOCK 提供了" 钩子函数" 负责处理Windows 消息,使Windows 的消息循环能
够继续。WINSOCK 提供了两个函数(WSASetBlockingHook()和
WSAUnhookBlockingHook())让应用程序设置或取消自己的" 钩子函数" 。函数WSAIsBlocking()可以检测是否阻塞,函数WSACancelBlockingCall()可以取消一个阻塞的调用。
8.4错误处理
WINSOCK 提供了两个WSAGetLastError()和WSASetLastError()来获取和设置
最近错误号。
8.5启动和终止
由于Windows Sockets的服务是以动态连接库WINSOCK.DLL 形式实现的,所以
必须要先调用WSAStartup()函数对Windows Sockets DLL进行初始化,协商WINSOCK 的版本支持,并分配必要的资源. 在应用程序关闭套接口后,还应调用WSACleanup()终止对Windows Sockets DLL的使用,并释放资源,以备下一次使用。
9. 实现远程数据的管理
9.1 设计基本思路:
企业内部局域网内部实现信息的远程管理,
局域网内部每台运行有故障信息系统的PC 机都能为其他用户提供服务,具体实现采用Windows Sockest(网络套接字)结合多线程网络通信的方法。
Windows Sockets 是Microsoft Windows 的网络程序设计接口,它是由Berkeley Sockets 扩展而来的,以动态链接库的形式提供给用户使用。Windows Sockets在继承了Berkeley Sockets的主要特征基础上,又对它进行了重要扩充。目前使用较多的Windows Sockets 2.0版本和Berkeley Sockets 一样都是基于TCP/IP协议的,用于为上层应用程序完成网络数据通信,而不必关心底层网络链路的通信情况,真正实现了底层网络通信对应用程序的透明。
9.2 具体实现(为了数据传送的可靠性,采用基于TCP 的流式套接字):
作为服务器端(每个故障管理系统既是服务器端又能充当客户端) ● 创建套接字(socket )
● 将套接字绑定到一个本地地址和端口上(bind ) ● 将套接字设为诊听模式,准备接收客户请求(listen )
● 等待客户请求到来:当请求到来后,接收连接请求,返回一个新的对应此连接的套接字(accept )
● 用返回的套接字和客户端进行通信(send/recv) ● 返回,等待另一客户端请求 ● 关闭套接字结束通信
作为客户端(每个故障管理系统既是服务器端又能充当客户端)
● 创建套接字(socket )
● 向服务器发出连接请求(connect ) ● 和服务器端进行通信(send/recv) ● 关闭套接字
结合多线程实现网络通信的实现:
10. 程序的编译和系统的实现
上面我们完成了信息管理系统的编程和调试工作,接下来就是系统的编译和发布。选择Build 菜单下的Set Active Configuration选项,选择Project Configuration为Win32 Release,然后编译项目,得到可执行文件。打开此文件即可实现系统。另外需要指出的是,因为本系统是使用ADO 方式,所以要求运行本系统的机器都必须要求有安装ADO3. 0以上。
11. 结论
综上所述,利用Visual C++6.0开发彩电故障信息共享系统,能更好的实现信息的管理。对于企业中的小部门内的资料的管理能达到成本低、管理效率高的要求。另外该系统的模块化设计是系统的可维护性能强,可以根据其他部门的不同需要,稍做修改就可使用,具有很强的可移植性。