某学院仓库管理系统设计_第1页
某学院仓库管理系统设计_第2页
某学院仓库管理系统设计_第3页
某学院仓库管理系统设计_第4页
某学院仓库管理系统设计_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数据库课程设计报告题目:仓库管理系统组长:王 宁(P)组员:胡乐乐(P)徐 建(P) 葛 东(P) 张 超(P)指导教师:曹永春计算机科学与信息工程学院仓库管理系统一、设计目标企业的仓库物资管理往往复杂、繁琐。本系统主要针对企业生产所需要的各种设备而设计,实施验收入库并填写入库单和入库登记;企业各个部门根据所需要提出物质申请,计划员根据整个企业的需求开出物资设备出库单,仓库管理员根据出库单核对发放设备;设备使用完毕需要及时归还入库,填写还入库单。系统还根据需要按照月、季、年进行统计分析,产生相应报表。根据系统功能的要求,仓库管理系统可以分为日志管理、入库、出库、还库、查询、报表等主要模块。企业的物资供应管理往往是很复杂、繁琐的。由于掌握的物资种类众多,订货、管理、发放的渠道各有差异,各个企业之间的管理机制不尽相同,各类统计计划报表繁多,因此物资管理必须实现计算机化,而且必须根据企业的具体情况制定相应的方案以便提高工作效率。根据当前的企业管理体制,一般物资供应管理系统,总是根据所掌握的物资类别,相应分成几个科室来进行物资的计划、订货、核销托收、验收入库。根据企业各个部门的来发送物资设备,并随时按期进行库存盘点、做台帐、根据企业自身领导和自身管理的需要按月、季、年进行统计分析,产生相应的报表。为了加强相应物资、设备的管理,要定期掌握其储备、消耗情况,根据计划定额和实际消耗定额的比较,进行定额管理。仓库管理的物资在本章中主要是企业生产所需的各种设备。进货时检查合同确认为有效托收之后,进行验收入库、填写入库单和入库登记。企业各个部门根据所需要的物资设备总额和部门生产活动所需要提出物资需求申请,计划员根据企业的需求开出物资设备出库单,仓库管理员根据出库单核对发放设备。设备使用完毕需要及时归还入库,填写还入库单。系统还根据需要按照月、季、年进行统计分析,产生相应报表。为了跟好的理解该系统和读懂该系统的源代码,读者应对以下的知识点有所了解:Access数据库操作的基础知识。ODBC数据源基础知识。基本的SQL语句,如添加、查询、修改和删除记录语句。Visual C+界面设计和关于数据库的基础知识。二、系统设计仓库管理的特点是信息处理量比较大,所管理的物资设备种类繁多,而且入库单、出库单、需求单等单据的发生量特别大,关联信息多,查询和统计的方式各不相同,在管理上实现起来有一定的困难。在管理的过程中经常出现信息的重复传递;单据、报表的种类繁多,各个部门管理规格不统一等问题。在本系统的设计过程中,为了克服这些困难,满足计算机管理的需要,采取了下面的一些原则:统一各种原始单据的格式,统一账目和报表的格式。删除不必要的管理冗余,实现管理规范化、科学化。程序代码标准化,软件统一化,确保软件的可维护性和实用性。界面尽量简单化,做到实用、方便,尽量满足企业中不同层次员工的需要。建立操作日志,系统自动记录所进行的各种操作。1、系统功能分析 本例中的仓库管理系统需要完成的功能主要有以下几点: 仓库管理各种信息的输入,包括入库、出库、还库、需求信息的输入等。 仓库管理各种信息的查询、修改和维护。 设备采购报表的生成。 在库存管理中加入最高储备和最低储备字段,对仓库中的物资设备实现监控和报警。 企业各部门的物资需求的管理。 操作日志的管理。 仓库管理系统的使用帮助。2、系统功能模块设计 在系统功能分析的基础上,结合Visual C+程序编制的特点,得到如图1所示的系统功能模块图。仓库管理系统系统模块输入模块维护模块查看模块报表模块帮助模块日志管理需求模块还库模块出库模块入库模块图1 系统功能模块图 系统主要界面及流程如下所示。 程序开始运行之后先出现如图2的登陆界面。成功输入用户名和密码后将进入主对话框。图2 登陆界面单击“设备代码”按钮进入设备代码表(device_code)的管理。单击“库存信息”按钮进入现有库存表(device)的管理。单击“设备入库”按钮开始设备入库操作,若成功,则在设备入库表(device_in)中增加一条记录,同时修改现有的库存表(device)中的相关数据。单击“设备出库”按钮开始设备出库操作,如图3所示。若成功,则在设备出库表(device)中的相关数据。 图3 设备出库登记窗口单击下方的“出库信息”按钮进入设备出库表(device_out)的管理。如图4所示。图4 出库信息管理界面单击“设备还库”按钮开始设备还库操作。若成功,则在设备还库表(device_return)中增加一条记录,同时修改现有库存表(device)中的相关数据。单击下方的“还库信息”按钮进入设备还库表(device_return)的管理。单击“设备需求”进入设备需求登记的界面,如图5所示。用户在这里填写设备需求。若成功,则在设备需求表(device_need)中增加一条设备需求记录。图5 设备需求登记窗口单击下方“需求信息”按钮进入设备需求表(device_need)的管理。如图6所示。单击“操作日志”按钮查看目前的所有操作日志记录,在里面还可以删除所有日志记录。单击“帮助”按钮进入联机帮助。单击“关于”按钮查看程序信息图6 需求信息管理窗口三、数据库设计1、数据库需求分析在仔细调查企仓库物资设备管理过程的基础上,得到本系统所处理的数据流程,如图7所示。 设备入库设备采购设备还库设备出库仓库现有库存各部门需求企业生产计划汇总图 7 数据流程图针对本实例,通过对企业仓库管理的内容和数据流程的分析,设计的数据项和数据结构如下:设备代码信息:其数据项有设备号、设备名称现有库存信息:其数据项有现有设备、现有数目、总数目、最大库存和最小库存等设备使用信息:其数据项有使用的设备、使用部门、数目、使用时间和出库时状态等设备采购信息:其数据项有采购的设备、采购员、供应商、采购数目和采购时间等设备归还信息:其数据项归还设备、归还部门、归还数目、归还时间和经手人等设备需求信息:其数据项有需求的部门、需求设备、需求数目和需求时间等2、数据概念结构设计这一设计阶段是在需求分析的基础上,设计出能满足用户需求的各种实体,以及它们之间的关系,为后面的逻辑结构设计打下基础。本实例根据上面得设计规划出实体有库存实体,入库实体、出库实体、采购实体、还库实体和需求实体。各实体的E-R图及其关系描述如下:现有库存现有库存现有库存现有库存设备号图8 库存实体E-R图入库供应商信息采购价格数量采购员设备号图9 入库实体E-R图出库使用部门数量、时间经手人设备号图10 出库实体E-R图部门需求需求部门需求数量需求时间设备号 图11 部门需求实体E-R图设备还库还库时间人还库数量经手人设备号图12 还库实体E-R图计划采购库存信息供应信息时间设备号 图13 计划采购实体E-R图入库 现有库存 出库 还库 部门需求设备采购图 14 实体和实体之间的关系E-R图3、数据库逻辑结构设计在上面的实体以及实体之间的关系的基础上,形成数据库中的表格和各个表格之间的关系。仓库管理系统数据库中的各个表格的设计结果如下面的几个表格所示。每个表格表示在数据库中的一个表。 列名 数据类型 可否为空 说明 CodeVARCHAR2(6) NOTNULL 设备号(主键) NameVARVHAR2(20) NULL 设备名称设备代码表device_code 列名 数据类型 可否为空 说明CodeVARCHAR2(6)NOTNULL设备号In_dateDATENOTNULL入库时间(主键)ProviderVARCHAR2(20)NULL供应商TelenoVARCHAR2(20)NULL供应商电话In_numberNUMBER(6)NULL入库数量PriceNUMBER(6)NULL价格BuyerVARCHAR2(10)NULL采购设备库表device_in列名 数据类型 可否为空 说明CodeVARCHAR2(6)NOTNULL设备号DepartmentVARCHAR2(20)NULL使用部门Out_dateDATENULL出库时间(主键)Out_stateNUMBER(1)NULL出库状况Out_personVARCHAR2(10)NULL经手人Out_numberNUMBER2(10)NOTNULL出库数量TakerVARCHAR2(10)NULL领取UsageVARCHAR2(20)NULL用途设备出库表device_out列名数据类型可否为空说明codeVARCHAR2(6)NOT NULL设备号(主键)now_numberNUMBER(6)NULL现有库存high_numberNUMBER(6)NULL最大库存low_numberNUMBER(6)NULL最小库存total_numberNUMBER(6)NULL总数现有数据库表device列名数据类型可否为空说明codeVARCHAR2(6)NOT NULL设备号departmentVARCHAR2(20)NOT NULL部门名称need_numberNUMBER(6)NULL需要数量begin_dateDATENULL需求开始时间end_dateDATEMULL需求结束时间 设备需求表 device_need列名数据类型可否为空说明codeVARCHAR2(6)NOT NULL设备号return_dateDATENULL还库时间(主键)keeperVARCHAR2(10)NULL仓库管理员return_numberNUMBER(6)NULL归还数量return_personVARCHAR2(10)NULL归还人 设备还库表device_return列名数据类型可否为空说明do_userVARCHAR2(10)NOT NULL操作员do_whatVARCHAR2(40)NOT NULL操作内容do_dateDATENOT NULL操作时间操作日志表howdo列名数据类型可否为空说明codeVARCHAR2(6)NOT NULL设备号now_numberNUMBER(6)NULL现有库存total_numberNUMBER(6)NULL总库存max_numberNUMBER(6)NULL购买数量providerVARCHAR(2)NULL供应商priceNUMBER(6)NULL价格buy_dateDATENULL计划采购时间(主键)设备采购计划表 device_wantbuy4、数据库结构的实现创建设备代码device_codeCREATE TABLE “DMS”.device_code(code VARCHAR2(6) NULL,name VARCHAR2(20) NULL,CONSTRANT code_code_pk PRIMARY KEY(code)TABLESPACE”USER_DATA”;创建设备入库表 device_inCREATE TABLE “DMS”.device_in(code VARCHAR2(6) NOT NULL,in_date DATE NOT NULL,provider VARCHAR2(20) NULL,teleno VARCHAR2(10) NULL,in_number NUMBER(6) NULL,price NUMBER(6) NULL,buyer VARCHAR2(10) NULL,CONSTRAINT in_date_pk PRIMARY KEY(in_date)TABLESPACE “USER_DATA”;创建设备出库表 device_outCREATE TABLE “DMS”.device_out(code VARCHAR2(6) NOT NULL,department VARCHAR2(20) NULL,out_date DATE NULL,out_state NUMBER(1) NULL,out_penson VARCHAR2(20) NULL,out_number NUMBER(6) NOT NULL,taker VARCHAR2(10) NULL,usage VARCHAR2(20) NULL,CONSTRAINT out_date_pk PRIMARY KEY(out_date)TABLESPACE”USER_DATA”;创建现有库存表 deviceCREATETABLE ”DMS”.device(code VARCHAR2(6) NULL,now_number NUMBER(6) NULL,high_number NUMBER(6) NULL,low_ number NUMBER(6) NULL,total_ number NUMBER(6) NULL,CONSTRAINT device_code_pk PRIMARY KEY(code)TABLESPACE”USER_DATA”;创建部门需求表 device_needCREATE TABLE “DMS”,device_need(code VARCHAR2(10) NOT NULL,department VARCHAR2(10) NOT NULL,need_number NUMBER(6) NULL,begin_date DATE NULL,end_date DATE NULL,)TABLESPACE ”USER_DATA”;创建设备还库表device_returnCREATE TABLE “DMS”,device_return(code VARHAR2(6) NOT NULL,department VARCHAR2(20) NULL,return_date DATE NULL,keeper VARCHAR2(10) NULL,return_number NUMBER(6) NULL,return_person VARCHAR2(10) NULL,CONSTRAINT return_date_pk PRIMARY KEY (return_date)TABLESPACE ”USER_DATA”;创建设备采购计划表 device_wantbuyCREATE TABLE “DMS”,device_wantbuy(code VARCHAR2(10) NOT NULL,now_number NUMBER(6) NULL,total_ number NUMBER(6) NULL,max_ number NUMBER(6) NULL,buy_ number NUMBER(6) NULL,provider VARCHAR2(20) NULL,price NUMBER(6) NULL,buy_date DATE NULL,CONSTRAINT wantbuy_date_pk PRIMARY KEY (buy_date)TABLESPACE ”USER_DATA”;创建操作日志表 howdoCREATE TABLE “DMS”,howdo(do_user VARCHAR2(10) NOT NULL,do_what VARCHAR2(40) NOT NULL,do_date DATE NOT NULL,)TABLESPACE “USER_DATA”;四、系统实现1、创建应用程序此仓库系统应用程序的创建步骤如下:、选择菜单“File|New”中的“新建项目”选项卡中“MFC AppWizard(exe)”,设置合适的目录和项目名,比如“E:Projects”目录下的“DMS”项目。、创建一个对话框应用程序(“Dialog Based”),单击“Next”按钮。、由于在这个项目中将要使用ADO,所以在MFC AppWizard 的第2步,需要选中“Automation”选项,使应用程序能够支持自动化对象,如图15所示。图15 使应用程序支持自动化(Automation)、单击“Finish”按钮,结束项目的创建。至此一个基于对话框的应用程序框架就搭建好了。主对话框名为CDMSDlg。、项目创建完毕之后,在头文件stdafx.h中加入下面4行:#importc:programfilescommonfilessystemadomsado15.dllno_namespace rename(EOF, adoEOF) #include icrsint.hinline void TESTHR(HRESULT x) if FAILED(x) _com_issue_error(x);#define DATEFMTCString(%s)第1行中的路径可能根据Visual Studio安装路径的不同而不同。其中的rename指令,把ADO中的EOF重命名为adoEOF,这是为了避免和其他库的常量名冲突。注意第3行,这里定义了一个inline函数TESTHER,它的作用是测试COM函数的返回值,在这个返回值包含一个错误的时候,抛出一个_com_error型的异常。ADO作为一个COM组件接口,它的许多函数都会返回一个HRESULT型的值作为结果。如果在每一步都用SUCCEEDED或FAILED宏测试返回值的话,将会不胜其烦,还有可能制造出一连串嵌套的if语句这样不美观的代码。这个函数简化了这种验证操作,利用C+的异常处理机制,使代码显得紧凑而高效,为后面的工作带来很大方便。第4行定义了一个宏。这是不同的后台数据库对SQL语句中日期的用法要求不同引起的。比如Access数据库要求SQL语句中的日期用两个#字符括起,而其他的数据库可能需要使用单引号或者双引号。所以在这里定义了这个DATEFMT宏,为了方便程序在不同的后台数据库键切换。这是一个在开发的时候需要注意的细节,后面还会具体提到。2、COM知识准备下面介绍一些关于COM知识。这部分内容是针对那些没有学习过的COM技术的读者,目的是为他们理解ADO提供一些背景知识。COM技术在微软公司的应用中可以说是无处不在,Windows系统相当多的服务都以这种方式提供,例如著名的DirectX,还有在这一章中广泛应用的ADO。ADO的底层是OLE DB,他本身则是对OLE DB的一个COM包装。所以具备一些COM的知识,对使用ADO是很有帮助的,但并不是说必须要精通COM才能使用ADO。事实上,在一般的应用中,只需要理解下面这段代码即可。/DlgViewReport.cpp_RecordsetPtr pRst = NULL;IADORecordBinding *picRs = NULL; /Interface Pointer declared.(VC+ Extensions) CDevBuyRs rs;try_bstr_t strSQL(SELECT * FROM DEVICE_WANTBUY);TESTHR(pRst.CreateInstance(_uuidof(Recordset);pRst = m_DBCnt-Execute(strSQL, NULL, adCmdText); TESTHR(pRst-QueryInterface(_uuidof(IADORecordBinding),(LPVOID*)&picRs);TESTHR(picRs-BindToRecordset(&rs);int i = 0;while (!pRst-adoEOF)m_list.InsertItem(0, rs.m_sz_code);m_list.SetItemText(i, 1, rs.m_sz_now);m_list.SetItemText(i, 2, rs.m_sz_total);m_list.SetItemText(i, 3, rs.m_sz_max);m_list.SetItemText(i, 4, rs.m_sz_buy);m_list.SetItemText(i, 5, rs.m_sz_provider);m_list.SetItemText(i, 6, rs.m_sz_price);m_list.SetItemText(i, 7, rs.m_sz_date);pRst-MoveNext(); picRs-Release();pRst-Close();catch(_com_error& e) AfxMessageBox(e.ErrorMessage();m_list.SetRedraw(TRUE);return; 、BSTR和_bstr_t下面的语句声明了一个_bstr_t型的变量,_bstr_t是对BSTR类型的一个封装。_bstr_t strSQL(“SELETE *FROM DEVICE_WANTBUY”);对于BSTR,通俗地说,它是COM中使用的字符串,与普通C程序中的字符串的区别在于:它一个带有字符计数值的字符串。它的字符计数值在字符数组的前面。它保存的在字符是所谓的“宽字符”(Wide character)。所以,对于一个BSTR而言,下面的语句就是错的。BSTR str=L”Some words”;正确的做法是:Wchar_t st_=L”Some words”BSTR str;Bstr=SysAllocString(str_)释放一个SBSTR指针时,则调用SysFreeString函数。每次都这样操控字符串未免太过麻烦,所以Visual C+ 里提供了_bstr_t这个类对BSTR做了封装,使程序员可以简单的对这种COM 字符串进行操作了。、IADORecordBinding和Iunkown一个COM组件包含了许多COM对象,程序员通过“接口”来操控这些对象,或者说,这些对象通过提供给程序员的接口来实现自己的功能。下面这行代码中的IADORecordBind就是一个指向这种接口的指针。IADORecordBingding *picRs=NULL; /Interface Pointer declared(VC+ Extension)每个接口都是从IUnkown这个接口派生出来的。IUkown接口声明了3个纯虚函数:HRESULT QueryInterface(REFID rilid,void*ppvObject);ULONG AddRef();ULONG AddRef();一般来说,不能直接拥有一个IADORecordBind或者IFoo、IBirdISomeInterface诸如此类的接口对象,程序员只能得到一个接口的指针,就像下面的这行代码:pRst-QueryInterface(_uuidof(IADORecordBingding),(LPVOID*)&picRs);这行代码解释了IUknown接口中QueryInterfae方法的最基本的用法:程序员用它来得到COM对象支持的某个接口的指针。如上例中,pRst时某一个COM对象提供的一个接口指针,程序员从某本书上(比如MSDN)知道了这个对象一定拥有一个IADORecordBinding型的接口,于是调用上面那行代码,得到了这个IADORecordBinding接口的指针。然后就可以使用IADORecordBinding接口里声明的那些方法了。如上所说,一个COM对象,程序员往往不能直接拥有它的实例,而只是它的接口的指针。那什么时候来释放这个对象呢?这就是AddRef和Release方法的用途。得到了一个接口指针,开始使用一个COM对象,就要调用它的AddRef方法增加它内部的一个引用计数;使用完之后则调用Release方法减少这个计数。如果计数为零,则已经说明没有人使用,这个COM对象就会自己销毁自己。原则上说,同一个对象提供的不同接口,AddRef和Release的效果都是一样的。所以在使用完一个COM接口指针之后,一定要这样:picRs-Release();如果忽略了这一句,就会造成一个COM对象及他所掌握的资源不能被正确释放。RecordsetPtr和智能指针如上一段所讲,使用完一个接口之后忘记调用Release是一件和糟糕的事,为了弥补这一点,就要写出一大串嵌套的if语句,降低了程序的易读性。程序就会抛出异常,而程序员又没有写出捕获这种异常的代码(往往也不能写,谁也无法预料自己调用的某个库函数会跑出什么样的异常),这样也会跳过某个原本不想跳过的Release。怎么解决这个问题呢?一种方法是用try_finally语句,但是由于现有编译器的缺陷,包含这个语句的代码编译出来的效率较低。这就用到了“智能指针这个工具。_RecordsetPtr pRs=NULL上面这行代码声明的变量就是一个智能指针。从他的名字上看,他是对Recordset这种对象的指针进行了包装。TESTHr(pRst.CreateInstance(_uuidof(Recordset);这一句创建了一个Recordset型的COM对象,并对智能指针赋值。在制作所在的函数体结束时,智能指针对象从栈中析构,在它的析构函数里调用了它所包含接口的Release方法。由它的工作原理看出,它解决了上面的问题栈中对象的析构函数无论如何都是会被调用的,即使函数发生了异常而退出的情况也是如此。除此之外,智能指针可以在接口指针赋值是自动调用AddRef方法这也是一个容易犯得错误。它通过重载运算符,使得它在使用时,和普通的接口指针毫无二致。3、操作日志模块的设计、写日志模块 通过操作日志模块,该系统每一次改变数据库数据的操作都会在操作日志表格中有相应的记录。这样可以增强操作人员的责任感,提高系统的安全性,也利于维护数据库数据的完整性。此外,一个翔实的操作日志,也给开发过程中的调试、除错带来很大便利,所以这个模块的设计被改在了最前面。先定义一个名为Clogmngr的类:/ LogMngr.h/定义一个Log管理器class CLogMngr public:CLogMngr();virtual CLogMngr();public:bool AddLog(LPCSTR op);void Setup(_ConnectionPtr cnnt, CString& user)m_DBCnt = cnnt;m_user = user;protected:_ConnectionPtr m_DBCnt;CString m_user;在这个类中,保存了一个数据库连接的指针m_DBCnt和当前用户的ID(m_user)。在主对话框CDMSDlg中加入了一个CLogMngr型的成员变量,并在CDMSDlg:OnInitDialog()中调用其Setup方法进行初始化,设置好数据库连接指针和用户名。这样当程序中某处需要写信息进行操作日志的时候,只需要调用这个类的AddLog方法即可。下面是CLogMngr:AddLog内部实现的详细过程。/LogMngr.cpp/向数据库中添加Log记录的代码bool CLogMngr:AddLog(LPCSTR op)CTime tm = CTime:GetCurrentTime();CString sql_;sql_.Format(INSERT INTO HOWDO (do_user,do_what,do_date) VALUES(%s,%s,%d-%d-%d %d:%d:%d),m_user, op, tm.GetYear(), tm.GetMonth(), tm.GetDay(),tm.GetHour(), tm.GetMinute(), tm.GetSecond();_bstr_t sql = sql_;trym_DBCnt-Execute(sql,NULL,adCmdText);catch(_com_error& e) CString Error = e.ErrorMessage(); AfxMessageBox(e.ErrorMessage();return false; return true;可以看到,它利用了Connection对象的Execute方法,直接执行SQL语句,向表中加入了一条包含了操作者、操作时间和操作内容3个字段的记录。直接使用了SQL语句的方法在表比较简单的时候很快捷,但在表包含比较多的字段的时候,就不太实用了。对日志表,我们暂且先用这种方法。、读日志模块在项目资源中加入一个对话框,它包含了一个列表框控件,几个编辑框和两个按钮。这个窗体用以显示系统所用的日志记录。它还将实现清空所有记录的功能(注意为了保证日志记录的完整性、安全性,不能单独删除某条记录。)在删除所有记录时,用SQL语句显得很方便。但是主意最好不要用那个“Delete * FROM HOWDO”这样的语句,而是使用下面的“TRUNCATETABLE”语句,它的速度比Delete快。/DlgViewLog.cpp/删除所有日志记录的函数void CDlgViewLog:OnBtnVlrmall() _bstr_t strSQL(TRUNCATE TABLE HOWDO);trym_DBCnt-Execute(strSQL,NULL,adCmdText);catch(_com_error& e) AfxMessageBox(e.ErrorMessage();EndDialog(0); RefreshData();此模块的时间和数据处理与后面的类似,这里暂不叙述。最后整个船体的外表如图16所示。 图16 查看日志窗口4、登录窗口的设计在CDMSDlg:OnInitDialog()中加入如下一段代码:/DMSDlg.cpp/弹出登录界面CDlgLogIn dlg;doif (!dlg.DoModal()EndDialog(0); while (dlg.m_UsrName.GetLength()=0);它的目的是弹出图17所示的登录界面,并从中获取一个有效的用户名。图17 登录界面在得到有效的用户名(字符串长度非0)后,程序用如下的代码尝试连接数据库,初始化成员变量(Connection指针和ClogMngr的实例)。在连接成功后,写登录记录进入操作日志。/ DMSDlg.cpp/建立数据库连接,初始化成员变量/登录库,如失败,则关闭程序trym_DBCnt.CreateInstance(_uuidof(Connection);CString sql_;sql_.Format(DSN=DMS;UID=%s;PWD=%s,dlg.m_UsrName,dlg.m_UsrPwd);_bstr_t sql=sql_;m_DBCnt-Open(sql,-1);m_logMngr.Setup(m_DBCnt,dlg.m_UsrName);m_logMngr.AddLog(登录数据库);catch(_com_error& e) AfxMessageBox(e.ErrorMessage();this-EndDialog(0); 最后别忘了在程序结束的时候关闭数据库连接。/ DMSDlg.cpp/void CDMSDlg:OnDestroy() CDialog:OnDestroy(); m_DBCnt-Close();5、主对话框的设计登录完成后,显示出主对话框。它的界面如图18所示,单击某个按钮就能弹出某个功能的界面。注意到按钮的排布时按照所处的模块分类的。 图18 主对话框界面 以其中“设备代码”按钮为例,说明他的事件处理函数。代码如下: /DMSDlg.cpp /显示设备代码管理界面 void CDMSDlg:OnBtnDevcode() CDlgDevcode dlg;dlg.Setup(m_DBCnt,&m_logMngr);this-ShowWindow(SW_HIDE);dlg.DoModal();this-ShowWindow(SW_SHOW);从上面的代码看出,当单击“设备代码”按钮时,程序构造一个CDlgDevcode型对话框实例,通过它的Setup函数赋给它一个数据库连接指针和一个日志管理对象实例的指针,然后主对话框隐藏,直到子对话框事物处理结束。6、设备代码管理窗口的建立设备代码表格(device_code)经常被其他表格引用,如获取合法编码、由设备编码号查找设备名称等。所以自日志模块和主对话框完成之后,先建立这个表格的管理模块。对话框类名为CDlgDevcode,设计如图19所示。图19 设备代码管理窗口这里用一个列表框控件显示读取的数据记录。在CDlgDevcode:OnInitDialog()中对这个控件(m_list)进行初始化(分割列、设置列宽、设置风格等)。/DlgDevcode.cpp/对话框的初始化BOOL CDlgDevcode:OnInitDialog() CDialog:OnInitDialog();m_list.InsertColumn(0,设备号);m_list.InsertColumn(1,设备名);RECT rect;m_list.GetWindowRect(&rect);int wid = rect.right - rect.left;m_list.SetColumnWidth(0,wid/2);m_list.SetColumnWidth(1,wid/2);m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);RefreshData();return TRUE;注意:其中一行代码:m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT),定义了当表格某整行被选中时,将此行的完整数据在表格控件的右侧显示出来。以后的各个模块都用到了这个方法,这部分的代码如下:/DlgDevcode.cpp/消息映射部分BEGIN_MESSAGE_MAP(CDlgDevcode, CDialog)/AFX_MSG_MAP(CDlgDevcode) ON_NOTIFY(NM_CLICK,IDC_LIST_DEVCODE,OnClickListDevcode)/AFX_MSG_MAPEND_MESSAGE_MAP()/事件处理部分void CDlgDevcode:OnClickListDevcode(NMHDR* pNMHDR, LRESULT* pResult) int i = m_list.GetSelectionMark();m_code = m_list.GetItemText(i,0);m_name = m_list.GetItemText(i,1);UpdateData(FALSE);*pResult = 0;其余程序清单/ / DlgDevcode.cpp : implementation file#include stdafx.h#include DMS.h#include DlgDevcode.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CDlgDevcode dialogCDlgDevcode:CDlgDevcode(CWnd* pParent /*=NULL*/): CDialog(CDlgDevcode:IDD, pParent)/AFX_DATA_INIT(CDlgDevcode)m_code = _T();m_name = _T();/AFX_DATA_INITm_DBCnt = NULL;m_log = NULL;void CDlgDevcode:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CDlgDevcode)DDX_Control(pDX, IDC_LIST_DEVCODE, m_list);DDX_Text(pDX, IDC_EDIT_DCCODE, m_code);DDX_Text(pDX, IDC_EDIT_DCNAME, m_name);/AFX_DATA_MAPBEGIN_MESSAGE_MAP(CDlgDevcode, CDialog)/AFX_MSG_MAP(CDlgDevcode)ON_NOTIFY(NM_CLICK, IDC_LIST_DEVCODE, OnClickListDevcode)ON_BN_CLICKED(IDC_BTN_DCADD, OnBtnDcadd)ON_BN_CLICKED(IDC_BTN_DCDEL, OnBtnDcdel)ON_BN_CLICKED(IDC_BTN_DCUPD, OnBtnDcupd)/AFX_MSG_MAPEND_MESSAGE_MAP()/ CDlgDevcode message handlersvoid CDlgDevcode:RefreshData()m_list.DeleteAllItems();m_list.SetRedraw(FALSE);_bstr_t strSQL(SELECT * FROM DEVICE_CODE)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论